消除PLY语法中的这种Shift-Reduce冲突

时间:2018-07-10 19:51:42

标签: python compiler-construction yacc lex context-free-grammar

所以我的源代码中有这些语法产品。

function_defination : FUNC WHITESPACE ID LPAREN optional_parameters RPAREN WHITESPACE optional_return_type WHITESPACE LBRACE ENTER statements RBRACE

optional_parameters : has_parameter
                        | empty
has_parameter : has_parameter COMMA has_parameter
                        | ID COL WHITESPACE TYPE

在奔跑时,我意识到它给了我1个换班/减少冲突的机会。仔细检查parser.out文件后,

    (27) has_parameter -> has_parameter COMMA has_parameter .
    (27) has_parameter -> has_parameter . COMMA has_parameter

  ! shift/reduce conflict for COMMA resolved as shift

我意识到冲突源于生产

has_parameter : has_parameter COMMA has_parameter
                        | ID COL WHITESPACE TYPE

这种移位/减少冲突的产生是由于以下事实:如果 has_parameter COMMA has_parameter 当前在堆栈中,则解析器(如果遇到逗号作为下一个符号)将不知道它是否要将其减小为has_parameter或将COMMA移到堆栈上。

我尝试了许多不同的方式,例如制作许多不同的作品,等等,但是我不确定消除这种转变/减少冲突的有效方法。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:3)

列表的惯用法是:

optional_parameters : parameter_list
                    | empty

对于可选参数列表,然后添加

parameter

没有必要将{{1}}定义为单独的非终结符,尤其是在只有一个关联生产的情况下。但是通常不止一个,而且语法更容易理解,而且带有额外的非终结符。


顺便说一句,忽略扫描仪中的空格通常比尝试将其包含在语法中的任何地方都麻烦得多。 (对于即使是稍微复杂的语法,尝试显式处理空白通常也会导致需要额外的提前行。)