ANTLR 语法行 1:6 不匹配的输入"<EOF>"期望"。



我正在使用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 '.'

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

知道我能做什么吗?

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

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

$.name生成2个令牌:

  1. ROOT
  2. ID

但是您的第一个备选方案ROOT expr ('.' expr)需要两个由.分隔的表达式。也许你想让第二个expr是可选的,比如:

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

EOF通常添加在启动规则的末尾,以强制解析器使用所有令牌。正如您现在所做的那样,解析器成功地解析了ROOT expr,但随后未能进一步解析,并产生了您看到的警告(应为".")。

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

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

此外,像[]'[?('等这样的令牌看起来很可疑。我对Object Path不是很熟悉,但通过将这些字符相互粘合,像这样的输入[ ](用空格分隔的[])将不会被[]匹配。因此,如果foo[ ]有效,我会这样写:

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

并跳过lexer中的空格:

SPACES : [ trn]+ -> skip;

相关内容

  • 没有找到相关文章

最新更新