我正在维护使用 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
中的右括号设为可选
显然两者都不能让我满意。
我是不是忽略了什么?
最佳答案
也许我错过了你的代码的意图,但是规则
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 成为现在的样子,请发表评论,我将提交一个可行的解决方案,至少对于上面的示例来说是如此
关于java - 在嵌套条件中使用 LOOKAHEAD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48567882/