java - 在嵌套条件中使用 LOOKAHEAD

标签 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 中的右括号设为可选

显然两者都不能让我满意。

我是不是忽略了什么?

最佳答案

也许我错过了你的代码的意图,但是规则

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/

相关文章:

whitespace - 任何类型的空格上的 JavaCC 词法错误

java - Spring应用程序的默认html页面

java - 即使我不使用 Double,ClassCastException Double 也会 float

java - Java中的静态 block 与初始化 block ?

java - 用 JMonkey 画一个矩形

javascript - 如何在 JavaCC 中实现对 token 的负 LOOKAHEAD 检查?

JavaCC语法问题,具有理解能力

java - gradle 生成的文件编译失败

java - 如何从 JTable 中删除重复行?

java - JavaCC语法中的try-catch block