-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser.bison
182 lines (171 loc) · 3.13 KB
/
parser.bison
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
%token
INT
PLUS
LESS
MULT
DIV
REST
EQUAL
AND
OR
NOTEQUAL
GREATER_OR_EQUAL
LESSER_OR_EQUAL
GREATER
LESSER
ATRIB
INT_TYPE
INT_OP
WHILE
IF
ELSE
OPEN_BRACKETS
CLOSE_BRACKETS
OPEN_PARENTESIS
CLOSE_PARENTESIS
SEMICOLON
VAR
FUNC
MAIN
QUOTATION
COMMA
PRINTF
SCANF
// Operator associativity & precedence
%right ATRIB
%left AND OR
%left EQUAL NOTEQUAL
%left GREATER LESSER GREATER_OR_EQUAL LESSER_OR_EQUAL
%left PLUS LESS
%left MULT DIV
%left REST
// Root-level grammar symbol
%start program;
// Types/values in association to grammar symbols.
%union {
int intValue;
char* id;
Expr* exprValue;
CmdList* cmdListValue;
Cmd* cmdValue;
}
%type <intValue> INT
%type <id> VAR
%type <exprValue> expr
%type <cmdListValue> cmdlist
%type <cmdValue> cmd
// Use "%code requires" to make declarations go
// into both parser.c and parser.h
%code requires {
#include <stdio.h>
#include <stdlib.h>
#include "ast.h"
extern int yylex();
extern int yyline;
extern char* yytext;
extern FILE* yyin;
extern void yyerror(const char* msg);
CmdList* root;
}
%define parse.error verbose
%%
program: FUNC MAIN OPEN_PARENTESIS CLOSE_PARENTESIS OPEN_BRACKETS cmdlist CLOSE_BRACKETS { root = $6; }
cmdlist:
{ $$ = NULL; }
|
cmd cmdlist { $$ = ast_cmdlist($1, $2); root=$$; }
;
cmd:
INT_TYPE VAR ATRIB expr SEMICOLON {
$$ = ast_atribution($2,$4);
}
|
VAR ATRIB expr SEMICOLON {
$$ = ast_atribution($1,$3);
}
|
IF OPEN_PARENTESIS expr CLOSE_PARENTESIS OPEN_BRACKETS cmdlist CLOSE_BRACKETS {
$$ = ast_if($3, $6);
}
|
IF OPEN_PARENTESIS expr CLOSE_PARENTESIS OPEN_BRACKETS cmdlist CLOSE_BRACKETS ELSE OPEN_BRACKETS cmdlist CLOSE_BRACKETS {
$$ = ast_if_else($3 , $6, $10);
}
|
WHILE OPEN_PARENTESIS expr CLOSE_PARENTESIS OPEN_BRACKETS cmdlist CLOSE_BRACKETS {
$$ = ast_while($3, $6);
}
|
PRINTF OPEN_PARENTESIS QUOTATION INT_OP QUOTATION COMMA VAR CLOSE_PARENTESIS SEMICOLON {
$$ = ast_print($7);
}
|
SCANF OPEN_PARENTESIS QUOTATION INT_OP QUOTATION COMMA VAR CLOSE_PARENTESIS SEMICOLON {
$$ = ast_scan($7);
}
;
expr:
INT {
$$ = ast_integer($1);
}
|
VAR {
$$ = ast_id($1);
}
|
expr PLUS expr {
$$ = ast_operation(PLUS, $1, $3);
}
|
expr LESS expr {
$$ = ast_operation(LESS, $1, $3);
}
|
expr DIV expr {
$$ = ast_operation(DIV, $1, $3);
}
|
expr REST expr {
$$ = ast_operation(REST, $1, $3);
}
|
expr MULT expr {
$$ = ast_operation(MULT, $1, $3);
}
|
expr EQUAL expr {
$$ = ast_operation(EQUAL, $1, $3);
}
|
expr NOTEQUAL expr {
$$ = ast_operation(NOTEQUAL, $1, $3);
}
|
expr AND expr {
$$ = ast_operation(AND, $1, $3);
}
|
expr OR expr {
$$ = ast_operation(OR, $1, $3);
}
|
expr GREATER_OR_EQUAL expr {
$$ = ast_operation(GREATER_OR_EQUAL, $1, $3);
}
|
expr LESSER_OR_EQUAL expr {
$$ = ast_operation(LESSER_OR_EQUAL, $1, $3);
}
|
expr GREATER expr {
$$ = ast_operation(GREATER, $1, $3);
}
|
expr LESSER expr {
$$ = ast_operation(LESSER, $1, $3);
}
;
%%
void yyerror(const char* err) {
printf("Line %d: %s - '%s'\n", yyline, err, yytext );
}