LR(1)移位/减少消歧

问题描述 投票:1回答:1

给定的输入以重复BLOCKs,其中每个块具有重复BEGIN EVENTEND EVENT条目(END EVENT总是跟随一个BEGIN EVENT):

[TIMESTAMP] BLOCK
[TIMESTAMP] BEGIN EVENT
[TIMESTAMP] END EVENT
[TIMESTAMP] BEGIN EVENT
[TIMESTAMP] END EVENT
...
[TIMESTAMP] BLOCK

你如何消除歧义这个语法与LR(1)?我使用LALRPOP,并在此最小的例子是:

Timestamp = "[TIMESTAMP]";
BlockHeader = Timestamp "BLOCK";
Begin = Timestamp "BEGIN" "EVENT";
End = Timestamp "END" "EVENT";

Block = BlockHeader (Begin End)+;
pub Blocks = Block*

因为LR(1)只能向前看,虽然一个道理,这个语法是模糊的,因为LALRPOP有益告诉你(部分错误):

Local ambiguity detected

  The problem arises after having observed the following symbols in the input:
    BlockHeader (Begin End)+
  At that point, if the next token is a `"[TIMESTAMP]"`, then the parser can proceed in two different ways.

  First, the parser could execute the production at
  /home/<snip>.lalrpop:51:9: 51:32, which would consume
  the top 2 token(s) from the stack and produce a `Block`. This might then yield a parse tree like
    BlockHeader (Begin End)+ Block
    ├─Block────────────────┤     │
    ├─Block+───────────────┘     │
    └─Block+─────────────────────┘

  Alternatively, the parser could shift the `"[TIMESTAMP]"` token and later use it to construct a
  `Timestamp`. This might then yield a parse tree like
    (Begin End)+ "[TIMESTAMP]" "BEGIN" "EVENT" End
    │            ├─Timestamp─┘               │   │
    │            └─Begin─────────────────────┘   │
    └─(Begin End)+───────────────────────────────┘

我看到,它告诉我,解析BlockHeader后,开始和结束也想不通如果下一个标记是另一个开始,或另一个块的开始。我还没有找到一种方式,LR(1)消除歧义,但我只能假设这是一个缺乏对我而言,虽然理解,而不是LR(1)语法的继承限制?

rust lr1
1个回答
2
投票

不幸的是这种“需要更多的先行”问题的是硬而不完全重组语法,这往往失去输入的期望的结构来解决,并且有时简并接受输入的原始语法会拒绝。通常,您可以拒绝那些投入和获取结构回来后处理解析树,但更多的工作。在你的情况下,语法:

Timestamp = "[TIMESTAMP]";
BlockHeader = Timestamp "BLOCK";
Begin = Timestamp "BEGIN" "EVENT";
End = Timestamp "END" "EVENT";
Event = Begin End;
Item = BlockHeader | Event;
pub Input = Item*

应该做的伎俩,但它失去的块结构(而不​​是给你块头和事件的非结构化序列)的问题,它接受空块。你可以很容易地处理与后处理的项目列表中这两个问题。

当需要先行是小的,有限的另一种选择是在你的标记生成器来对付它。我不熟悉LALRPOP,但它应该是可能的“结合”的[TIMESTAMP]标记与紧随其后的关键字标记(所以时间戳将不会出现在语法,而不是仅仅是对关键字的属性),其中情况下,一切会正常工作与单令牌前瞻。

© www.soinside.com 2019 - 2024. All rights reserved.