繁体   English   中英

ANTLR语法行1:6输入不匹配&#39; <EOF> &#39;期待&#39;。

[英]ANTLR Grammar line 1:6 mismatched input '<EOF>' expecting '.'

我正在玩antlr4语法文件,我想编写自己的jsonpath语法。

我想出了这个:

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     : '*'  ;

在一个简单的表达式上运行后:

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));

输出正常,这意味着“名称”实际上是从json检索的,但是有一个警告我无法解释:

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

我已经读到我需要明确地将EOF规则添加到我的开始规则( dnot )中,但这似乎不起作用。

知道我该怎么办吗?

您的输入$.name不能通过您的规则进行解析:

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

$.name产生2个令牌:

  1. ROOT
  2. ID

但是您的第一个选择ROOT expr ('.' expr)期望2个表达式之间用a分隔. 也许您打算将第二个expr设为可选,如下所示:

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

通常在开始规则的末尾添加EOF ,以强制解析器使用所有令牌。 正如您现在所做的那样,解析器成功解析了ROOT expr ,但随后无法进一步解析,并产生了您看到的警告(期望为“。”)。

由于objectPath似乎是您的开始规则,所以我认为这是您想要做的:

objectPath      : dnot EOF;

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

另外,像这些[]'[?('等)的标记看起来也很可疑。我对Object Path并不是很熟悉,但是通过将这些字符彼此粘合在一起,可以像这样输入[ ][]并用空格隔开)不会与[]匹配。因此,如果foo[ ]有效,我会这样写:

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

并跳过词法分析器中的空格:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM