【问题标题】:What's wrong with my LR(0) grammar?我的 LR(0) 语法有什么问题?
【发布时间】:2012-10-17 21:40:19
【问题描述】:

我正在尝试制作自己的 LR(0) 解析器,但遇到了一些语法问题。

基本上,对于语法

exp:  mexp
mexp: '1'
mexp: mexp '*' '1'

我的解析器正在输出

State 0: • 1
       | • mexp
       | • exp
       | • mexp * 1
State 1: 1 •
State 2: exp •
State 3: mexp • * 1
       | mexp •
State 4: mexp * • 1
State 5: mexp * 1 •

警告

(state 3, *) already has reduction:  exp: mexp

我的程序为此语法导出的 LR(0) 表是:

         '1' exp mexp '*'    $
State 0:  s1  s2   s3         
State 1:  r3           r3   r3
State 2:                   acc
State 3:  r2           s4   r2
State 4:  s5                 
State 5:  r4           r4   r4

其中 $ 表示文件的结尾。

警告源于这样一个事实,即状态 3(对应于mexp • * 1 | mexp •)具有两个减少r2 状态转换s4对于输入*

但看起来像according to Wikipedia,这不应该发生——我应该只有减少:

如果一个项目集 i 包含一个 A → w • 形式的项目,并且 A → w 是规则 mm > 0那么动作表中状态i的行完全被reduce动作rm填充。

有趣的是,当我删除规则 exp: mexp 时,我没有遇到任何此类冲突。

所以我无法弄清楚的是,这确实是语法中的真正问题吗?
(换句话说,这个语法实际上不是LR(0)吗?)
我不认为是这种情况,但我不确定。

如果是这样,为什么?如果没有,那有什么问题? (是我的桌子错了,还是我做错了什么?)

【问题讨论】:

  • 我认为您实际上想让 exp 规则包含“$”标记,因为它是开始生产。
  • ... 或类似的东西 :) 建议的答案。

标签: parsing language-agnostic grammar lr


【解决方案1】:

(在仔细阅读了那个维基百科页面之后。)

维基百科的引文是(强调):

如果一个项目集 i 包含一个形式为 A → w • 的项目并且 A → w 是规则 m 其中 m > 0 那么动作表中状态 i 的行被完全填充减少动作 rm.

规则 0 是增强的开始规则,在您的情况下应该是:

start : mexp '$'

(就我个人而言,我更喜欢显式添加 EOF 令牌;这样的例外情况较少。)

但是,我认为你得到的是:

start : exp '$'
exp   : mexp

实际上不是 LR(0),因为单位缩减规则 (exp → mexp) 会导致您发现的移位缩减冲突。

如果规则是用明确的结束标记编写的,那么维基百科文章对m = 0 的例外将是不必要的;在这种情况下,动作acc是根据修改后的动作3生成的:

  1. “$”(输入结束)的额外列被添加到包含每个包含 S → E • '$' 的项目集的 acc 的操作表中。

(实际上,您不需要“额外列”部分;使用明确的结束标记,您应该已经有一个列。关键是用 acc 操作覆盖 shift 操作。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多