Separar analisador léxico do analisador sintáctico

Muito embora se possa definir a gramática completa, juntando a análise léxica e a sintáctica no mesmo módulo, podemos também separar cada uma dessas gramáticas.

Isso facilita, por exemplo, a reutilização de analisadores léxicos.

Existem também algumas funcionalidades do analisador léxico, que obrigam a essa separação (“ilhas” lexicais).

Para que a separação seja bem sucedida há um conjunto de regras que devem ser seguidas:

  1. Cada gramática indica o seu tipo no cabeçalho.

  2. Os nomes das gramáticas devem (respectivamente) terminar em Lexer e Parser.

  3. Todos os tokens implicitamente definidos no analisador sintáctico têm de passar para o analisador léxico (associando-lhes um identificador para uso no parser).

  4. A gramática do analisador léxico deve ser compilada pelo ANTLR4 antes da gramática sintáctica.

  5. A gramática sintáctica tem de incluir uma opção (tokenVocab) a indicar o analisador léxico.

lexer grammar NAMELexer;
...
parser grammar NAMEParser;
options {
    tokenVocab=NAMELexer;
}

No teste da gramática deve utilizar-se o nome sem o sufixo:

  • antlr4-test NAME rule

Exemplo

lexer grammar CSVLexer ;
COMMA: ’,’ ;
EOL: ’\r’? ’\n’ ;
STRING: ’"’ ( ’""’ | ~’"’ )* ’"’ ;
TEXT: ~[,"\r\n]~[,\r\n]* ;
parser grammar CSVParser ;
options {
tokenVocab=CSVLexer ;
}
file : firstRow row* EOF;
firstRow : row ;
row : field (COMMA field )* EOL;
field : TEXT | STRING | ;
antlr4 CSVLexer.g4
antlr4 CSVParser.g4
antlr4-javac CSV* java
antlr4-test CSV file

Last updated