0

可以说我的 .y 语法的一部分是这样的:

stmt : expr { $$ = $1; }
      | stmt expr { $$ = insert_stmt_list($1, $2); }

我可以有一个给出一个表达式的语句,或者我可以有几个表达式来生成一个语句列表。关于后者,我通过 insert_stmt... 函数存储它,但是第一个我将它发送到堆栈的顶部。

我的问题是:我该如何处理 $$ = $1 ?我的意思是,insert_stmt_list 将所有内容都放在一个结构中,我知道它在那里,我可以打印它们的值等等,但是 $$ = S1 到底去哪里了?怎么读?:-)

谢谢!

4

2 回答 2

1

回复:怎么读?

你有一个左递归语法,它首先必须识别一个expr. 这被归结stmt为由 产生的语义值make_new_stmt_list变成了stmt1by的语义值$$ = $1;

这只是意味着“从右侧(恰好是唯一一个)获取第一个符号的语义值并将其作为左侧的语义值传播”。

然后,如果expr看到另一个,解析将继续另一个产生:

stmt : ...
     | stmt expr { $$ = insert_stmt_list($1, $2); }

在这里,$1来自stmt右侧的 是$$在产生的先验归约中分配给的语义值stmt

您已经设计了系统,以便expra 用作stmt. 此外, anexpr产生的值适合作为 : 的任一参数insert_stmt_list。表达式是列表。

所以:

  1. 如果您的输入只有一个表达式 E,那么stmt出现的就是那个表达式。

  2. 如果您有两个表达式 E1 和 E2,则stmtwhich emeges 是以下结果:

    insert_stmt_list(E1, E2)
    
  3. 如果你有三个表达式,那么整体stmt就是这些调用的结果:

    insert_stmt_list(insert_stmt_list(E1, E2), E3)
    

等等。这是否有意义取决于此“插入”操作的语义。

于 2012-04-23T22:58:32.533 回答
0

写这样的东西更惯用:

stmt : expr { $$ = make_new_stmt_list($1); }
      | stmt expr { $$ = insert_stmt_list($1, $2); }

一种或另一种方式,您需要将表达式数据结构包装在语句列表数据结构中。

于 2012-04-23T19:26:13.233 回答