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); }
|
;
The
expr:means an expr is one of the following options, which are separated by | below. If it can be seen as anINTEGERtoken, then it takes the first one. If it can be seen as anexprfollowed by the*character followed by anexprthen it takes the second option and so on.$$is the default return value, and$1is the first token,$2the 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 anexpr, so then it matches 11 as anINTEGERtoken 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.