我正在维护使用JavaCC来解析语法的旧代码。
我的.jjt
文件大致如下:
void Top() {}
{
Bazz() OpenParenthesis() Foo() CloseParenthesis()
}
void Foo() {}
{
Bar() Blah() A()
}
void A() {}
{
Z() (B() Z())*
}
void Z() {}
{
(OpenParenthesis())? X() Y() (CloseParenthesis())?
}
传奇:
Top
是<EOF>
之前的主要条件,包含在返回Node
OpenParenthesis
和CloseParenthesis
分别代表(
和)
的文字代币我的问题是通过“简单”输入,例如:
bazz ( bar blah x y )
...右括号作为Z
条件的一部分(0 or 1
,?
量词)消耗,因此Top
中的强制右括号产生语法错误,解析器要求B
或<EOF>
。
JavaCC正则表达式不像Java正则表达式那样具有细粒度量词,因此我不能使用不情愿的量词来表示Z
的右括号。
我已经阅读过关于LOOKAHEAD
构造(一些教程/文档here)并且认为我可以使用一个来推断Z
是否不应该使用结束右括号,因此将Z
重写为:
void Z() {}
{
(OpenParenthesis())? X() Y() (LOOKAHEAD(1) CloseParenthesis())?
}
我也揣着前瞻的大小。
不幸的是,要么我不理解该功能,要么前瞻不能使用上面所示的分层语法。
到目前为止,我发现了一些糟糕的解决方法:
Z
完全删除可选括号Top
显然根本不满足我。
我忽略了什么吗?
答案 0 :(得分:2)
也许我错过了您的代码的意图,但规则
void Z() {}
{
(OpenParenthesis())? X() Y() (CloseParenthesis())?
}
对我来说看起来很奇怪。您是否真的希望以下所有序列都可以解析为Z?
( x y )
x y
( x y
x y )
如果您认为最后两个不应解析为Z,则将规则更改为
void Z() {}
{
OpenParenthesis() X() Y() CloseParenthesis()
|
X() Y()
}
如果你真的真的希望Z成为现实,那么发表评论我会提交一个有效的解决方案,至少对于上面的例子而言