línea antlr Gramática 1: 6 de entrada '<EOF>' esperando mismatched ''.

Andrei Ciobanu:

Estoy jugando con los archivos de gramática antlr4, y quería escribir mi propia jsonpath gramática.

Tengo comeup con esto:

grammar ObjectPath;

objectPath      : dnot;

dnot            : ROOT expr ('.' expr)
                | EOF
                ;

expr            : select #selectExpr
                | ID #idExpr
                ;

select          : ID '[]' #selectAll
                | ID '[' INT ']' #selectIndex
                | ID '[' INT (',' INT)* ']' #selectIndexes
                | ID '[' INT ':' INT ']' #selectRange
                | ID '[' INT ':]' #selectFrom
                | ID '[:' INT ']' #selectUntil
                | ID '[-' INT ':]' #selectLast
                | ID '[?(' query ')]' #selectQuery
                ;

query           : expr (AND|OR) expr # andOr
                | ALL # all
                | QPREF ID # prop
                | QPREF ID GT INT # gt
                | QPREF ID LT INT # lt
                | QPREF ID EQ INT # eq
                | QPREF ID GTE INT # gte
                | QPREF ID LTE INT # lte
                ;

/** Lexer **/
ROOT    : '$.' ;
QPREF   : '@.' ;
ID      : [a-zA-Z][a-zA-Z0-9]* ;
INT     : '0' | [1-9][0-9]* ;
AND     : '&&' ;
OR      : '||' ;
GT      : '>'  ;
LT      : '<'  ;
EQ      : '==' ;
GTE     : '>=' ;
LTE     : '<=' ;
ALL     : '*'  ;

Después de ejecutar esto en una simple expresión:

CharStream input = CharStreams.fromString("$.name");
ObjectPathLexer lexer = new ObjectPathLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);

ObjectPathParser parser = new ObjectPathParser(tokens);
ParseTree parseTree = parser.dnot();
ObjectPathDefaultVisitor visitor = ...
System.out.println(visitor.visit(parseTree));
System.out.println(parseTree.toStringTree(parser));

La salida está bien, lo que significa que el "nombre" en realidad se recupera de la JSON, pero hay una advertencia que no puedo explicar:

line 1:6 mismatched input '<EOF>' expecting '.'

He leído que tengo que tener una regla explícita EOF añadió a mi a partir de un ( dnot), pero esto no parece funcionar.

Cualquier idea de lo que puedo hacer?

Bart Kiers:

Su entrada $.nameno se puede analizar mediante la regla:

dnot            : ROOT expr ('.' expr)
                | EOF
                ;

$.name produce 2 tokens:

  1. ROOT
  2. ID

Sin embargo, su primera alternativa, ROOT expr ('.' expr), espera 2 expresiones separadas por una .. ¿La intención era hacer el segundo expr opcional, como esto:

dnot            : ROOT expr ('.' expr)*
                | EOF
                ;

Y el EOFgeneral se añade al final de la regla de inicio, para forzar al analizador de consumir todas las fichas. Como lo hizo ahora, el analizador ha analizado correctamente ROOT expr, pero luego no pudo analizar aún más, y produce la advertencia que viste (esperando '').

Puesto que objectPathparece ser la regla de inicio, creo que esto es lo que quiere hacer:

objectPath      : dnot EOF;

dnot            : ROOT expr ('.' expr)?
                ;

Además, como estas fichas [], '[?('etc parecen sospechosas. No estoy muy familiarizado con la trayectoria del objeto, pero por encolado estos caracteres entre sí, de entrada como esta [ ]( [y ]separadas por un espacio) no será igualado por []. Así que si foo[ ]es válida, me gustaría escribir como este en su lugar:

select          : ID '[' ']' #selectAll
                | ...

y saltar espacios en el léxico:

SPACES : [ \t\r\n]+ -> skip;

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=232479&siteId=1
Recomendado
Clasificación