antlr 숨겨진 채널 공백 문제
-
18-09-2019 - |
문제
나는 다음과 같은 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
제휴하지 않습니다 StackOverflow