Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

yacc

lex

Lex part :

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

Yacc part :

%token num 
%%
exp:num '+' num ; {$$ = $1 + $3;}
%%
  1. In this part of the code what do $$, $1 and $2 stand for?
  2. How can I print $$ now?
  3. And if I send 5+9 as input to this program 5 and 9 are identified by the lex program, but what about the +? Is the symbol + sent to lex or not?
like image 307
πTh0n Avatar asked Oct 15 '18 17:10

πTh0n


3 Answers

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

those $$ , $1 , $3 are the semantic values for for the symbols and tokens used in the rule in the order that they appear. The semantic value is that one that you get in yylval when the scanner gets a new token.

$1 has the semantic value of the first num.

$3 has the semantic value of the second num

$2 is not used as it is the token '+'. The lexical analyzer does send this token to the parser. Also it has semantic value '0'.

$$ identifies the semantic value of the 'exp' (the whole grouping under that rule).

Did you try something like:

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

Also check: why does $1 in yacc/bison has a value of 0

like image 166
MAP Avatar answered Sep 23 '22 06:09

MAP


  1. $$ stands for the result of the current rule. $1 and $3 stand for the results of the first and third components respectively. So in this case, $1 would hold the value of the left num token and $3 of the right one. $2 would hold the value of the '+' token (assuming it has one), but that one's not actually being used in the code.

  2. By adding printf("%d\n", $$); at the end of the action or by adding another rule that uses exp and prints its value like this:

    main: exp { printf("%d\n", $1); } ;
    
  3. If all you have is the code you posted, the + will be printed to stdout and otherwise ignore. Consequently the rule num '+' num will never match because the lexer does not generate a '+' token, so the parser does not see one.

like image 31
sepp2k Avatar answered Sep 23 '22 06:09

sepp2k


As an addition to the other answers, you probably want to add the lex rules:

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

The first rule here will ignore any whitespace in the input and discard it. The second rule (which should be after all other rules) will match any other character in the input and return it to the parser so it can be matched directly as a quoted character (as you do with '+')

like image 33
Chris Dodd Avatar answered Sep 22 '22 06:09

Chris Dodd