문제

나는 다음과 같은 antlr 문법을 가지고 있습니다.

grammar MyGrammar;

doc :   intro planet;
intro   :   'hi';
planet  :   'world';
MLCOMMENT 
    :   '/*' ( options {greedy=false;} : . )* '*/' { $channel = HIDDEN; };
WHITESPACE : ( 
    (' ' | '\t' | '\f')+
  |
    // handle newlines
    ( '\r\n'  // DOS/Windows
      | '\r'    // Macintosh
      | '\n'    // Unix
    )
    )
 { $channel = HIDDEN; };

antlrworks 1.2.3 통역사에서 입력 hi world,hi/**/world 그리고 hi /*A*/ world 예상대로 작동합니다.

그러나 입력 hiworld, 어느 그렇지 않아야합니다 작업도 받아 들여집니다. 어떻게 만드나요? hiworld 불합격? "hi"와 "world"사이에 적어도 하나의 공백 (또는 주석)을 강요합니까?

이 예제에서는 MLComment와 whitespace 만 사용하여 단순화하지만 다른 종류의 의견이 지원됩니다.

도움이 되었습니까?

해결책

일반 ID 토큰을 만들어야합니다. Lexer는 가능한 가장 긴 토큰을 구축하기 때문에 "Hiworld"는 "Hi"또는 "World"보다 길기 때문에 "Hiworld"를 단일 단어로 볼 수 있습니다. 그러한 규칙은 다음과 같습니다.

ID : ('a'..'z' | 'A'..'Z')+;

예를 들어, 프로그래밍 언어를위한 구문 분석기가 "do"키워드를 "double"(키워드 유형, 'do'로 시작) 또는 "done"(변수 이름)과 분리하는 방법입니다.

다른 팁

문자열을 만드는 한 가지 방법 hiworld 실패는 다음과 같이 실패 할 수있는 검증 된 시맨틱 술어를 사용하는 것입니다.

doc:      intro planet;
failure : 'hiworld' { false }?;
intro   : 'hi';
planet  : 'world';
// rest of grammar omitted
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top