我需要yacc的一些帮助。 我正在使用中缀/后缀翻译器,后缀部分的中缀非常简单,但我有一些关于后缀到中缀翻译的问题。 这是一个关于我将要做什么的例子(只是翻译一个简单的ab + c-或abc + - )
exp: num {printf("+ ");} exp '+'
| num {printf("- ");} exp '-'
| exp {printf("+ ");} num '+'
| exp {printf("- ");} num '-'
|/* empty*/
;
num: number {printf("%d ", $1);}
;
很明显它不起作用,因为我在实际身体之前要求一个动作(使用printfs),所以在编译时,我得到很多
警告:由于冲突,规则在解析器中无效
问题是printfs正是我需要它们的地方(或者我的输出不是中缀表达式)。有没有办法让打印操作保持在那里,让yacc识别它需要使用哪一个?
答案 0 :(得分:1)
基本上,没有。问题在于,为了解决你所拥有的问题,yacc必须具有无限量的前瞻性。这是有问题的,因为yacc是一个相当简单的工具,所以相反它需要一个(坏)猜测并抛出一些警告的规则。您需要更改语法,以便yacc可以决定如何处理只有极少量前瞻的令牌(单个令牌IIRC)。执行此操作的常用方法是将值的解释附加到标记,并使用后期操作,或者更实际地,构建一个您作为单独步骤遍历的树(从其语法中打印出中缀表达式)树是微不足道的。)
请注意,当您收到来自yacc的警告时,这通常意味着您的语法错误,并且生成的解析器将执行非常意外的操作。优化它直到你从那个阶段得到 no 警告。也就是说,将语法警告视为错误;别的,你会后悔的。