我有一个我用Yacc编写的语法。语法的相关部分在这里摘录
postfix
: primary
| postfix '[' expr ']'
| postfix '[' expr ':' expr ']'
| postfix "." STRING
| postfix '(' ')'
| postfix '(' args ')'
;
unary
: postfix
| '!' unary
| '-' unary
| '+' unary
;
如果查看后缀定义,您会注意到我在第四个规则的周期内有双引号。我不得不把它放进去,因为没有它我就会有一个转移/减少冲突。当我改变使用的引用类型时,我有点困惑为什么转移/减少冲突会消失,我怀疑这里有一些我错过的东西。如果有人能够解释这些引号的区别以及我应该使用哪一个,我会很感激。
答案 0 :(得分:4)
在野牛中,单引号和双引号的文字不同之处在于它们命名不同的标记 - 因此'.'
和"."
是两个不同的标记。在你的语法中使用两者都被认为是不好的形式,因为它非常混乱。
请注意,只有基于'
的单个字符令牌与引号之间的内容有任何实际关系。这样的标记获得的令牌代码等于该单个字符的字符代码。所有其他令牌都会获得由bison选择的唯一令牌值,只有这样才能使所有不同的令牌获得不同的令牌号,除非它们被声明为别名。
因此,当令牌'.'
将获得令牌代码46(假设为ascii)时,令牌"."
将获得一些其他代码(某些数字大于256)。除非您将"."
的别名声明为某个命名令牌,否则词法分析器无法轻松知道"."
的令牌代码是什么并将其返回。
以上所有内容仅适用于野牛; Berkeley yacc和AT& T yacc是不同的(彼此和野牛)。
因此,当您更改为"."
时,转换/减少冲突会消失,因为您的语法中有'.'
的其他用法,而'.'
的两种用法与其他用法冲突。将一个更改为"."
会使冲突消失,因为它们现在是词法分析器需要解决的两个不同的标记。当然,由于你的词法分析器可能永远不会返回"."
标记,这可能不是你想要的。