我目前正在为我的语法开发解析器。我的目标是不做任何提前准备,而这正是我真正奋斗的目标。

这是我认为足以证明我所遇到的问题的一个精简示例。

void main() : {}
{
    (A())* (B())*
}

void A() : {}
{
    C() <ID>
}

void B() : {}
{
    <ID> Z()
}

void C() : {}
{
    <bah>
    | <bha>
    | <ID>
}


这是输出警告(我要删除它)

Warning: Choice conflict in (...)* construct at line 200, column 23.
         Expansion nested within construct and expansion following construct
         have common prefixes, one of which is: <ID>
         Consider using a lookahead of 2 or more for nested expansion.

最佳答案

确实,我们需要更多地了解Z。我假设L(Z)(即Z生成的语言)不包含空序列,也不包含以IDbhabah开头的序列。我还要假设main之后的第一个标记不能是IDbhabah

在这种情况下,我几乎肯定会先行使用

void main() : {}
{
    AsBs()
}

void AsBs() : {}
{
  LOOKAHEAD( A() )
  A() AsBs() ;
|
  (B()*)
|
  {/*nothing*/}
}


ABC相同,如原始帖子中所述。



但是,张贴者需要不提前使用的解决方案。这是一个。我做出了与上述相同的假设。

void main() : {}
{
    AsBs()
}

void AsBs() : {}
{
    C1() <ID> AsBs()
|
    <ID>  // This ID might be the start of either A or B
    ( <ID> AsBs()  // That ID started an A
    | Z() (B())* ) // That ID started a B.
|
    {/*nothing*/}
}

void B() : {}
{
    <ID> Z()
}

void C1() : {}
{
    <bah>
    | <bha>
}


这里不需要AC

10-06 07:17