yacc中的$$ = $ 1 + $ 3是什么意思?

时间:2018-10-15 17:07:17

标签: yacc lex

Lex部分:

%%
[0-9]+ { yyval = atoi (yytext); return num; }
%%

Yacc部分:

%token num 
%%
exp:num '+' num ; {$$ = $1 + $3;}
%%
  1. 在代码的这一部分,$$$1$2代表什么?
  2. 如何立即打印$$
  3. 如果我将5+9作为输入发送到该程序,则59由lex程序标识,但是+呢?符号+是否已发送给lex?

3 个答案:

答案 0 :(得分:2)

exp:num ‘+’ num ; {$$ = $1 + $3;} 

这些 $$ $ 1 $ 3 是规则中使用的符号和标记的语义值,其顺序为出现。语义值是当扫描程序获得新令牌时在yylval中获得的值。

$ 1 具有第一个数字的语义值。

$ 3 具有第二个数字的语义值

$ 2 未被使用,因为它是令牌“ +”。词法分析器确实将此令牌发送到解析器。而且它的语义值为“ 0”。

$$ 标识“ exp”(该规则下的整个分组)的语义值。

您尝试过以下方法吗:

exp:num ‘+’ num ; {$$ = $1 + $3;printf("%d", $$);}

还要检查:why does $1 in yacc/bison has a value of 0

答案 1 :(得分:1)

  1. convert doge.png -alpha set -virtual-pixel transparent -background blue \ -channel RG -morphology Distance Euclidean:1,20\! +channel _doge.png 代表当前规则的结果。 $$$1分别代表第一部分和第三部分的结果。因此,在这种情况下,$3将保留左侧的$1令牌和右侧的num的值。 $3将保留$2令牌的值(假设它有一个),但是代码中并未实际使用该令牌。

  2. 通过在操作结束时添加'+'或添加另一条使用printf("%d\n", $$);并按如下所示打印其值的规则:

    exp
  3. 如果您所拥有的只是您发布的代码,则main: exp { printf("%d\n", $1); } ; 将被打印到标准输出,否则将被忽略。因此,规则+将永远不会匹配,因为词法分析器不会生成“ +”令牌,因此解析器看不到该令牌。

答案 2 :(得分:1)

作为其他答案的补充,您可能想要添加lex规则:

[ \t\r\n]    ;
.          { return *yytext; }  /* should be the LAST rule */

这里的第一条规则将忽略输入中的任何空格并将其丢弃。第二个规则(应该在所有其他规则之后)将与输入中的任何其他字符匹配,并将其返回到解析器,以便可以直接将其作为带引号的字符进行匹配(就像对'+'一样)