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.

Foi útil?

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top