Search code examples
compiler-constructionsyntaxyacc

How does yacc work,can you explain it section by section?


How does this tiny yacc programe work?

What I know so far:

%{...%} is definition %% ... %% is rule,but how to interpret the rule? and stuff after %% is function definition. What's the section %token INTEGER between %} and %% ?

%{
#include <stdlib.h>
int yylex(void);
void yyerror(char *);
%}
%token INTEGER
%left '+' '-'
%left '*' '/'
%%
program:
program expr '\n' { printf("%d\n", $2); }
|
;
expr:
INTEGER { $$ = $1; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { $$ = $1 / $3; }
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
;
%%
void yyerror(char *s) {
printf("%s\n", s);
}
int main(void) {
yyparse();
return 0;
}

UPDATE

What I don't understand:

program:
program expr '\n' { printf("%d\n", $2); }
|
;

Solution

  • The expr: means an expr is one of the following options, which are separated by | below. If it can be seen as an INTEGER token, then it takes the first one. If it can be seen as an expr followed by the * character followed by an expr then it takes the second option and so on. $$ is the default return value, and $1 is the first token, $2 the second on and on.

    So if it were parsing 5 + 6, it sees it as expr '+' expr, so it takes the 4th definition. It returns 11 as an expr, so then it matches 11 as an INTEGER token and assigns 11 as the return value.

    If we were parsing a program token followed by 5 + 6, it would do the same thing to get program 11, then take the program expr rule and call the c code which would print to the screen.

    Left means that operator is left associative. As in a + b + c = (a + b) + c. The operators on the same line have the same precedence, and those below it have lower precedence.

    I admittedly haven't used yacc in a while so feel free to tell me I'm totally wrong.

    UPDATE:

    yacc generates c code, so you can put your own code directly into it. So as it's parsing, if it sees a "program expr", then it can directly input the code in the { } into the generated code.