让我说我的.y语法的一部分是这样的:
stmt : expr { $$ = $1; }
| stmt expr { $$ = insert_stmt_list($1, $2); }
其中我可以有一个给出表达式的语句,或者我可以有几个表达式来生成一个语句列表。 关于后者我通过insert_stmt ...函数存储它,但是第一个我将它发送到堆栈的顶部。
我的问题是:我如何处理$$ = $ 1? 我的意思是,insert_stmt_list将所有内容都放在一个结构中,我知道它就在那里,我可以打印它们的值等等,但是在地狱中,$$ = S1会去哪里?怎么看? : - )
谢谢!
答案 0 :(得分:1)
Re:如何阅读?
你有一个左递归语法,首先必须识别expr
。这减少到stmt
,make_new_stmt_list
生成的语义值通过stmt1
变为$$ = $1;
的语义值。
这只是意味着“从右侧(恰好是唯一的一个)获取第一个符号的语义值,并将其作为左侧的语义值传播”。
然后,如果看到另一个expr
,则解析继续进行另一个生成:
stmt : ...
| stmt expr { $$ = insert_stmt_list($1, $2); }
此处,来自右侧$1
的{{1}}是在先前缩减中分配给stmt
的语义值,其产生$$
。
您已设计了系统,以便stmt
可用作expr
。此外,stmt
生成的值适合作为expr
的任一参数:表达式是列表。
所以:
如果你的输入只有一个表达式E,那么出现的insert_stmt_list
就是那个表达式。
如果您有两个表达式E1和E2,则stmt
的emeges是以下结果:
stmt
如果您有三个表达式,那么整体insert_stmt_list(E1, E2)
就是这些调用的结果:
stmt
等等。这是否有意义取决于此“插入”操作的语义。
答案 1 :(得分:0)
写这样的东西更加惯用:
stmt : expr { $$ = make_new_stmt_list($1); }
| stmt expr { $$ = insert_stmt_list($1, $2); }
无论如何,您需要将表达式数据结构包装在语句列表数据结构中。