0

这是我的令牌表:

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 会删除警告。任何帮助理解将不胜感激。

4

1 回答 1

2

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

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

void Start() :{} {
    LOOKAHEAD([ <B> ] ( <A> )* <C>) one()
    |
    LOOKAHEAD(<B> <A>) two()
    |
    three()
    |
    four()
}
于 2015-04-11T16:08:04.300 回答