在嵌套条件下使用 LOOKAHEAD
Using LOOKAHEAD in nested conditions
我正在维护使用 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
分别表示 (
和 )
的文字标记
- 指示解析器忽略空格
我的问题是 "simple" 输入如下:
bazz ( bar blah x y )
...右括号作为 Z
条件(0 or 1
、?
量词)的一部分使用,因此 [=13= 中的强制性右括号] 会产生语法错误,其中解析器会期望 B
或 <EOF>
.
JavaCC 正则表达式不像 Java 正则表达式那样具有细粒度量词,因此我不能在 Z
的右括号中使用不情愿的量词。
我已经阅读了 LOOKAHEAD
结构(一些 tutorial/docs here)并且认为我可以使用一个来推断结束右括号是否不应该被 [=21 使用=],因此将 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 成为现在的样子,请发表评论,我会提交一个可行的解决方案,至少对于上面的例子是这样
我正在维护使用 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
分别表示(
和)
的文字标记- 指示解析器忽略空格
我的问题是 "simple" 输入如下:
bazz ( bar blah x y )
...右括号作为 Z
条件(0 or 1
、?
量词)的一部分使用,因此 [=13= 中的强制性右括号] 会产生语法错误,其中解析器会期望 B
或 <EOF>
.
JavaCC 正则表达式不像 Java 正则表达式那样具有细粒度量词,因此我不能在 Z
的右括号中使用不情愿的量词。
我已经阅读了 LOOKAHEAD
结构(一些 tutorial/docs here)并且认为我可以使用一个来推断结束右括号是否不应该被 [=21 使用=],因此将 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 成为现在的样子,请发表评论,我会提交一个可行的解决方案,至少对于上面的例子是这样