我目前正在为我的语法开发解析器。我的目标是在不引起先行的情况下实现这一目标,而这正是我真正奋斗的目标。
这里有一个小例子,我相信足以证明我遇到的问题。
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.
答案 0 :(得分:1)
真的,我们需要更多地了解Z
。我假设L({Z
)(即Z
生成的语言)不包含空序列,也不包含以ID
,bha
开头的序列或bah
。我还要假设main
之后的第一个令牌不能是ID
,bha
或bah
。
在这种情况下,我几乎肯定会先行使用
void main() : {}
{
AsBs()
}
void AsBs() : {}
{
LOOKAHEAD( A() )
A() AsBs() ;
|
(B()*)
|
{/*nothing*/}
}
与原始帖子中的A
,B
和C
一样。
但是,发布者希望在不提前使用的情况下解决问题。这是一个。我做出了与上述相同的假设。
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>
}
这里不需要A
或C
。