执行语义动作的问题
书上说语义动作可以在产生式右部的任何地方执行,比如这样的文法
1、E ==> TR
2、R ==> addop T {print1 (addop.lexeme)}R1
3、T ==> num{print(num.val)}
在上面第2个产生式的 print 的执行发生在 T 的规约结束后、R1 的规约开始前。
问题是这里在 T 规约后整个产生式还没有最终确定,怎么能确定使用 R ==> addop T {print1 (addop.lexeme)}R1 这个产生式对应的语义动作?
比如还有一个产生式
4、F ==> addop T {print2 (addop.lexeme)}R2
岂不是有二义性了?怎么区分到底执行print1还是print2?望达人指点
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你以上的文法中,(E,R,T,F)
当只遍历到addop T的时候,因为addop T的非唯一性是无法判断到底是R还是F的,执行动作(print1,print2)必须要发生在R/F分清楚之后
谢谢
那是说print1 的执行不可能发生在 T 的规约结束后、R1 的规约开始前,必须是
2、R ==> addop T {print1 (addop.lexeme)}R1
整个产生式形成后?
加入R1也有相关的语义动作
R1 ==> M{print3}
怎么保证print1在print3之前执行?
看到这样的解释:
用户有时希望把一个动作放在产生式的其它地方,而不是最右端。例如,在对条件语句Stmt→if Expr then {/*action1*/}Stmt{/*action2*/} 进行处理时,为了能够及时回填Expr的真出口,需在then后“嵌入”语义动作。一般说来,解决此类问题的方法,是对原文法进行语法变换。除此而外,YACC还提供了一种更简单的处理方法,即允许用户自由地在产生的右部的任何位置嵌入所希望的语义动作。但需指出,YACC将自动为其增加ε-产生式,以保证“动作”在进行“归约”时才被执行
这样的语法递归下降即可分析,不过yacc用的是自底向上LALF(1)
[ 本帖最后由 cjaizss 于 2007-10-30 13:19 编辑 ]
???