在嵌套条件下使用LOOKAHEAD

时间:2018-02-01 16:51:26

标签: java javacc

我正在维护使用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
  • 实例的方法中
  • OpenParenthesisCloseParenthesis分别代表()的文字代币
  • 指示解析器忽略空格

我的问题是通过“简单”输入,例如:

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
  • 中选择右括号

显然根本不满足我。

我忽略了什么吗?

1 个答案:

答案 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成为现实,那么发表评论我会提交一个有效的解决方案,至少对于上面的例子而言