我正在用JavaCC编写一个jsonpath解析器,需要区分简单对象(如$.book)和数组(如$.book),以下是jjt文件的运行方式:
void Root() #void: {}
{
<ROOT><SEPARATOR> Expression() (<EOL>)? # starts with $.
}
void Expression() #void: {}
{
Variable()
(
<SEPARATOR>
Variable()
)*
}
void Variable() #void: {} # here is where the error resides
{
LOOKAHEAD(Object()) # a choice conflict between book and book[0]
Object()
|
Array()
}
void Object():
{
Token t;
}
{
t = <IDENTIFIER> # such as $.book
{
jjtThis.setName(t.image);
}
}
void Array():
{
Token t;
}
{
t = <IDENTIFIER> # such as book[0]
{
jjtThis.setName(t.image);
}
<BRACKET_OPEN>t=<INTEGER_LITERAL><BRACKET_CLOSE> # such as [0]
{
jjtThis.setIndex(java.lang.Integer.parseInt(t.image));
}
}
对于生成的JsonPathParser,它不像预期的那样工作:
SimpleNode node = new JsonPathParser(new StringReader("$.book[0]")).parse();
SimpleNode child = simpleNode.jjtGetChild(0);
assertTrue(child instanceof ASTArray); # assert failure, child is of type ASTObject
我知道根本原因在这里:查找( Object() )Object()AC.26 Array(),但我无法使其正确。
尝试在Object()方法中使用t = <IDENTIFIER>(?!\[)
,以确保它没有后面跟着一个[
,但是得到了一个org.javacc.jjtree.ParseException: Encountered " "?" "? "" at line 96, column 27
错误。
任何帮助都是非常感谢的。
发布于 2022-05-17 02:38:02
终于解决了。总之,我们必须使用“语义前瞻性”来实现这一点。一个快速回答如下所示,详情请阅读本文:https://www.cs.purdue.edu/homes/hosking/javacc/doc/lookahead.html
void Variable() #void:
{
Token t;
}
{
( LOOKAHEAD( Object(), { getToken(2).kind != BRACKET_OPEN })
Object()
|
Array()
)
}
发布于 2022-05-24 06:14:05
像这样的事怎么样:
void Root() #void: {}
{
<ROOT> Selector() (<EOL>)? # starts with $.
}
void Selector() #void: {}
{
Field()
(
Field() | Index()
)*
}
void Field():
{
Token t;
}
{
<SEPARATOR> t = <IDENTIFIER> # such as $.book
{
jjtThis.setName(t.image);
}
}
void Index():
{
Token t;
}
{
<BRACKET_OPEN>t=<INTEGER_LITERAL><BRACKET_CLOSE> # such as [0]
{
jjtThis.setIndex(java.lang.Integer.parseInt(t.image));
}
}
https://stackoverflow.com/questions/72215308
复制相似问题