不确定为什么在这些情况下需要这个LOOKAHEAD

时间:2015-04-11 13:17:47

标签: parsing javacc lookahead javaparser

这是我的令牌表:

TOKEN :
{
  < A : "A" >
| < B : "B" >
| < C : "C" >
}

我的代码包含2个选择冲突。

void Start() : {} {
    < A> [ Bs() ] "-" < A>
}
void Bs() : {} {
    ( "-" < B> )+
}

为了删除选择冲突警告,我需要添加2个LOOKAHEAD语句,如此...

void Start() : {} {
    < A> [ LOOKAHEAD(2) Bs() ] "-" < A>
}
void Bs() : {} {
    ( LOOKAHEAD(1) "-" < B> )+
}

我理解为什么需要第一个LOOKAHEAD(2),但我不知道为什么需要第二个LOOKAHEAD(1)。有人可以解释一下吗?

同样的例子......

void Start() :{} {
    one()
    |
    two()
    |
    three()
    |
    four()
}
void one() : {} {
    [ <B> ] ( <A> )* <C>
}
void two() : {} {
    <B> <A> < A> <B>
}
void three() : {} {
    <B> <B> <A> [ <B> ] <A>
}
void four() : {} {
    <A> [ <B><C> ] two()
}

为了消除选择冲突,我需要像这样添加LOOKAHEADS ......

void Start() :{} {
    LOOKAHEAD(1) one()
    |
    LOOKAHEAD(1) two()
    |
    three()
    |
    four()
}
void one() : {} {
    [ <B> ] ( <A> )* <C>
}
void two() : {} {
    <B> <A> < A> <B>
}
void three() : {} {
    <B> <B> <A> [ <B> ] <A>
}
void four() : {} {
    <A> [ LOOKAHEAD(1) <B><C> ] two()
}

我不知道为什么这些LOOKAHEADS会删除警告。任何帮助理解将不胜感激。

1 个答案:

答案 0 :(得分:2)

对于您的第一个示例,由于您定义Start的方式,Bs后面可以跟一个“ - ”标记。现在说输入是A - B - ...( "-" < B> )+循环应该执行一次还是两次?它取决于下一项输入。如果它是A,一旦,如果它是B,至少两次。所以解析器需要看过“ - ”。

对于您的第二个示例:当您输入LOOKAHEAD规范时,JavaCC不会发出警告,即使LOOKAHEAD规范不足以解决问题。在这种情况下,您可以使用

void Start() :{} {
    LOOKAHEAD([ <B> ] ( <A> )* <C>) one()
    |
    LOOKAHEAD(<B> <A>) two()
    |
    three()
    |
    four()
}