不幸的是,如果不完全重新构造语法,这种“需要更多的前瞻性”问题很难解决,因为语法通常会丢失所需的输入结构,有时会接受原始语法将拒绝的退化输入。通常,您可以拒绝这些输入,并通过对解析树进行后处理来返回该结构,但这需要更多的工作。在您的案例中,语法:
Timestamp = "[TIMESTAMP]";
BlockHeader = Timestamp "BLOCK";
Begin = Timestamp "BEGIN" "EVENT";
End = Timestamp "END" "EVENT";
Event = Begin End;
Item = BlockHeader | Event;
pub Input = Item*
应该这样做,但问题是它会丢失块结构(而不是给您一个块头和事件的非结构化序列),并且它接受空块。通过对项目列表进行后处理,您可以轻松地处理这两个问题。
当所需的展望很小且有界时,另一种选择是在标记器中处理它。我不熟悉larpop,但是应该可以将
[TIMESTAMP]
带有紧跟关键字标记的标记(因此时间戳不会出现在语法中,而只是关键字的一个属性),在这种情况下,使用单个标记先行,一切都可以正常工作。