执行语义动作的问题

发布于 2022-09-26 12:57:02 字数 395 浏览 17 评论 0

书上说语义动作可以在产生式右部的任何地方执行,比如这样的文法
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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

烟织青萝梦 2022-10-03 12:57:02

你以上的文法中,(E,R,T,F)
当只遍历到addop T的时候,因为addop T的非唯一性是无法判断到底是R还是F的,执行动作(print1,print2)必须要发生在R/F分清楚之后

巴黎盛开的樱花 2022-10-03 12:57:02

谢谢
那是说print1 的执行不可能发生在 T 的规约结束后、R1 的规约开始前,必须是
2、R ==> addop T {print1 (addop.lexeme)}R1
整个产生式形成后?

加入R1也有相关的语义动作
R1 ==> M{print3}
怎么保证print1在print3之前执行?

誰認得朕 2022-10-03 12:57:02

看到这样的解释:
用户有时希望把一个动作放在产生式的其它地方,而不是最右端。例如,在对条件语句Stmt→if Expr then {/*action1*/}Stmt{/*action2*/} 进行处理时,为了能够及时回填Expr的真出口,需在then后“嵌入”语义动作。一般说来,解决此类问题的方法,是对原文法进行语法变换。除此而外,YACC还提供了一种更简单的处理方法,即允许用户自由地在产生的右部的任何位置嵌入所希望的语义动作。但需指出,YACC将自动为其增加ε-产生式,以保证“动作”在进行“归约”时才被执行
这样的语法递归下降即可分析,不过yacc用的是自底向上LALF(1)

[ 本帖最后由 cjaizss 于 2007-10-30 13:19 编辑 ]

ゞ记忆︶ㄣ 2022-10-03 12:57:02

???

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文