1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
/*** definition section ***/
%{
/* C to be copied verbatim */
#include "lexer.h"
#include "node.h"
void yyerror(Node **root, const char *msg);
%}
%code requires {
#include "node.h"
}
%union {
Node *node;
int ival;
char *sval;
};
%locations
%start input
%parse-param {Node **root}
%token L_PAREN R_PAREN L_BRACK R_BRACK SEMI_COL COMP MULT DIV MOD MINUS PLUS INT VOID RET
%token <sval> WORD
%token <ival> NUMBER
%type <node> input
%type <node> func
%type <node> stmt
%type <node> exp
%type <node> term
%type <node> factor
%type <ival> un_op
/*** rules section ***/
%%
input: func {
*root = create_node(PROG);
add_child(*root, $1);
}
;
func: INT WORD L_PAREN VOID R_PAREN L_BRACK stmt R_BRACK {
$$ = create_function($2);
add_child($$, $7);
}
;
stmt: RET exp SEMI_COL {
$$ = create_node(STMT);
add_child($$, $2);
}
;
exp: term {
$$ = $1;
}
| exp PLUS term {
$$ = create_expr(PLUS_SYM);
add_child($$, $1);
add_child($$, $3);
}
| exp MINUS term {
$$ = create_expr(MINUS_SYM);
add_child($$, $1);
add_child($$, $3);
}
| un_op exp {
$$ = create_expr($1);
add_child($$, $2);
}
;
term: factor {
$$ = $1;
}
| term MULT factor {
$$ = create_expr(MULT_SYM);
add_child($$, $1);
add_child($$, $3);
}
| term DIV factor {
$$ = create_expr(DIV_SYM);
add_child($$, $1);
add_child($$, $3);
}
| term MOD factor {
$$ = create_expr(MOD_SYM);
add_child($$, $1);
add_child($$, $3);
}
;
factor: NUMBER {
$$ = create_const($1);
}
| L_PAREN exp R_PAREN {
$$ = $2;
}
;
un_op: COMP {
$$ = COMP_SYM;
}
| MINUS {
$$ = NEG_SYM;
}
;
%%
void yyerror(Node **root, const char *msg) {
printf("** Line %d: %s\n", yylineno, msg);
}
|