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

What does $$ = $1 + $3 mean in yacc?

词法部分:

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

Yacc 部分:

%token num 
%%
exp:num '+' num ; {$$ =  + ;}
%%
  1. 在这部分代码中,$$</code> 和 <code> 代表什么?
  2. 现在如何打印 $$
  3. 如果我发送 5+9 作为该程序的输入 59 由 lex 程序识别,但是 + 呢?符号 + 是否发送到 lex?
exp:num ‘+’ num ; {$$ =  + ;} 

那些 $$ , $1 , $3 是符号的语义值和规则中使用的标记按它们出现的顺序排列。语义值是当扫描器获得新令牌时您在 yylval 中获得的值。

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

$3具有第二个num

的语义值

$2 未使用,因为它是标记“+”。词法分析器确实将此标记发送给解析器。它还具有语义值“0”。

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

你有没有尝试过类似的东西:

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

同时检查:为什么 yacc/bison 中的 $1 的值为 0

  1. $$代表当前规则的结果。 </code>和<code>分别代表第一个和第三个分量的结果。因此,在这种情况下,</code> 将保存左侧 <code>num 令牌的值和右侧 </code> 令牌的值。 <code> 将保存 '+' 令牌的值(假设它有一个),但实际上并没有在代码中使用。

  2. 通过在操作结束时添加 printf("%d\n", $$); 或添加另一个使用 exp 的规则并像这样打印其值:

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

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

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

此处的第一条规则将忽略输入中的任何空格并将其丢弃。第二条规则(应该在所有其他规则之后)将匹配输入中的任何其他字符,并将其 return 传递给解析器,以便它可以直接作为带引号的字符进行匹配(就像使用 '+' )