Problema de WhiteSpace do canal oculto Antlr
-
18-09-2019 - |
Pergunta
Eu tenho a seguinte gramática 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; };
No intérprete Antlrworks 1.2.3, as entradas hi world
,hi/**/world
e hi /*A*/ world
trabalho, como esperado.
No entanto, a entrada hiworld
, que não deveria trabalho, também é aceito. Como faço para fazer hiworld
falhou? Como forço pelo menos um espaço em branco (ou comentário) entre "Hi" e "World"?
Observe que eu usei apenas MLComment e WhiteSpace neste exemplo para simplificar, mas outros tipos de comentários seriam suportados.
Solução
Você precisa criar um token de identificação geral. Como o Lexer constrói o token mais longo que pode, ele veria a entrada "Hiworld" como uma única palavra, pois é mais longa que "Hi" ou "World" sozinha. Essa regra pode parecer:
ID : ('a'..'z' | 'A'..'Z')+;
Como exemplo, é exatamente assim que os analisadores de programação separam a palavra -chave "DO" de "Double" (tipo de palavra -chave, começa com 'do') ou "done" (nome da variável).
Outras dicas
Uma maneira de fazer a corda hiworld
A falha é usar um predicado semântico validador que é garantido que falha, da seguinte maneira:
doc: intro planet;
failure : 'hiworld' { false }?;
intro : 'hi';
planet : 'world';
// rest of grammar omitted