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 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.