为什么野牛可以将"error"项目简化为空规则



我有以下yacc语法:

33 CompSt: "{" DefList StmtList "}"
34       | "{" error ";" DefList StmtList "}"
......
52 DefList: Def DefList
53        | %empty
54 Def: Specifier DecList ";"
55    | Specifier error ";"
56    | Specifier DecList error ";"
57    | Specifier VarDec "[" error ";"
58    | Specifier VarDec "[" INT error ";" 
59 DecList: Dec
60        | Dec "," DecList
61 Dec: VarDec
62    | VarDec "=" Exp

我添加了第34条规则来处理当一个非法项目出现在一对大括号的开头时的情况。我认为这个规则是必要的(如果你有任何其他方法,请告诉我(,但有一个转移/减少警告:

33 CompSt: "{" . DefList StmtList "}"
34       | "{" . error ";" DefList StmtList "}"
error   shift, and go to state 45
STRUCT  shift, and go to state 2
TYPE    shift, and go to state 3
error   [reduce using rule 53 (DefList)]

我不明白为什么"错误";可以根据规则53减少,我不知道如何修复此警告。

非常感谢你的回复。

在shift-reduce冲突中,解析器有两个选项:reduce(一个特定的产品(,让先行标记稍后处理,或者shift先行标记。错误规则也没什么不同;至少在最初,error被视为任何其他令牌。(特殊处理是error移位后的重新同步,但那是在它移位后。(

因此,error不会因产量53而减少。它是在error之前的空Deflist。当然,这种减少从来没有发生过,因为bison解决了有利于转移操作的转移-减少冲突,但它是在警告您,以防您认为减少空的Deflist很重要。

尽管这种减少冲突的转变并不重要,但它有点丑陋,而且根本不清楚为什么你觉得有必要首先添加错误产生。您真的不需要那么多错误生成,因为错误实际上会在解析中冒泡。(我想,除非你试图在每种情况下产生特定的错误消息。(

我会删除错误生成55到58,将34更改为更简单的

| "{" error "}"

并添加

| error ';'

Deflist(生产后52(。

相关内容

  • 没有找到相关文章

最新更新