转换语法以避免常见的前缀

Transform grammar to avoid common prefixes

我有这个带有通用前缀 (<id>) 的语法,我想对其进行转换以避免它们。

void Components() : {}
{
    (Read() | Write())* (<id>Assignment())* <id>Declaration() (Read() | Write() | <id>(Assignment() | Declaration()))*
}

问题是(<id>Assignment())* <id>Declaration()。语法可以有 0 个或多个 Assignments/Read/Write 语句,但至少有 1 个声明,然后是任意顺序的任何 statment/declaration。

重构这很容易,但我可能不会这样做。我可能会向前看一点。这里有两种解决方案


分解出 <id>

void Components() : {}
{
    (Read() | Write())*
    <id>
    (Assignment() <id>)*
    Declaration()
    ( Read()
    | Write()
    | <id> (Assignment() | Declaration())
    )*
}

使用更长的前瞻性

void Components() : {}
{
    (Read() | Write())*
    (LOOKAHEAD( 2 ) <id> Assignment())*
    <id> Declaration()
    ( Read()
    | Write()
    | LOOKAHEAD( 2 ) <id> Assignment()
    | <id> Declaration())
    )*
}