单引号和双引号文字的Yacc / Bison差异

时间:2014-05-09 17:58:37

标签: bison yacc

我有一个我用Yacc编写的语法。语法的相关部分在这里摘录

postfix
    : primary
    | postfix '[' expr ']'
    | postfix '[' expr ':' expr ']'
    | postfix "." STRING
    | postfix '(' ')'
    | postfix '(' args ')'
    ;

unary
    : postfix
    | '!' unary
    | '-' unary
    | '+' unary
    ;

如果查看后缀定义,您会注意到我在第四个规则的周期内有双引号。我不得不把它放进去,因为没有它我就会有一个转移/减少冲突。当我改变使用的引用类型时,我有点困惑为什么转移/减少冲突会消失,我怀疑这里有一些我错过的东西。如果有人能够解释这些引号的区别以及我应该使用哪一个,我会很感激。

1 个答案:

答案 0 :(得分:4)

在野牛中,单引号和双引号的文字不同之处在于它们命名不同的标记 - 因此'.'"."是两个不同的标记。在你的语法中使用两者都被认为是不好的形式,因为它非常混乱。

请注意,只有基于'单个字符令牌与引号之间的内容有任何实际关系。这样的标记获得的令牌代码等于该单个字符的字符代码。所有其他令牌都会获得由bison选择的唯一令牌值,只有这样才能使所有不同的令牌获得不同的令牌号,除非它们被声明为别名。

因此,当令牌'.'将获得令牌代码46(假设为ascii)时,令牌"."将获得一些其他代码(某些数字大于256)。除非您将"."的别名声明为某个命名令牌,否则词法分析器无法轻松知道"."的令牌代码是什么并将其返回。

以上所有内容仅适用于野牛; Berkeley yacc和AT& T yacc是不同的(彼此和野牛)。


因此,当您更改为"."时,转换/减少冲突会消失,因为您的语法中有'.'的其他用法,而'.'的两种用法与其他用法冲突。将一个更改为"."会使冲突消失,因为它们现在是词法分析器需要解决的两个不同的标记。当然,由于你的词法分析器可能永远不会返回"."标记,这可能不是你想要的。