-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrmr.y
198 lines (157 loc) · 7.32 KB
/
grmr.y
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
%{
#include "defs.h"
extern std::map<std::string, int> symbolTable;
void yyerror(char* v);
extern FILE * yyin;
extern int yylineno;
extern int yylex();
int error = 0;
// int yydebug = 1;
%}
%union {
char* dval;
}
%type <dval> Expression GeneralList Condition ConstAssignmentList
%type <dval> StatementList
// tokens
%token <dval> NUMBER IDENTIFIER
%token CONST
%token VAR
%token ARRAY
%token PROCEDURE
%token FUNCTION
%token CALL
%token BEGN END
%token IF THEN ELSE
%token WHILE
%token DO
%token FOR
%token UPTO DOWNTO
%token BREAK
%token RETURN
%token READ WRITE WRITELINE
%token ODD EQ IDK GT LT GEQ LEQ ASGN
%nonassoc IFX
%nonassoc ELSE
%left '+' '-'
%left '*' '/' '%'
%nonassoc UMINUS UPLUS
%%
// Rules
Program : TopBlock '.' ; // '>''='
TopBlock : ConstDecl VarDecl ArrayDecl ProcDecl FuncDecl Statement ;
Block : ConstDecl VarDecl ArrayDecl Statement ;
ConstDecl : CONST ConstAssignmentList ';'
|
| error ';' {yyerror("Invalid const declaration"); yyerrok;}
;
ConstAssignmentList :
IDENTIFIER EQ NUMBER {constAssign($1, $3);}
| ARRAY IDENTIFIER EQ '[' ConstArray ']'
| ConstAssignmentList ',' IDENTIFIER EQ NUMBER {constAssign($3, $5);}
| ConstAssignmentList ',' ARRAY IDENTIFIER EQ '[' ConstArray ']'
;
VarDecl:
VAR IdentifierList ';'
|
| error ';' {yyerror("Invalid variable declaration"); yyerrok;}
;
ArrayDecl:
ARRAY '{' NUMBER '}' IdentifierList ';' ArrayDecl
| error ';' {yyerror("Invalid array declaration"); yyerrok;}
|
;
IdentifierList:
IDENTIFIER // {setSymbol(std::string($1), scope);} declare()
| IdentifierList ',' IDENTIFIER // {setSymbol(std::string($3), scope);}
|
;
ProcDecl:
ProcDecl PROCEDURE IDENTIFIER ';' Block ';'
| error ';' {yyerror("Invalid procedure declaration"); yyerrok;}
|
;
FuncDecl:
FUNCTION IDENTIFIER '(' IdentifierList ')' ';' Block ';'
| error ';' {yyerror("Invalid function declaration"); yyerrok;}
|
;
Statement :
IDENTIFIER ASGN Expression {assignment($1, $3);}
// | IDENTIFIER ASGN '[' GeneralList ']'
| IDENTIFIER '[' Expression ']' ASGN Expression
| CALL IDENTIFIER
| FuncCall
| BEGN StatementList END
| ConditionalStatement // not done
| LoopStatement // not done
| ControlStatement // not done
| IOStatement // done
|
| error END {yyerror("Invalid statement"); yyerrok;}
| error ';' {yyerror("Invalid statement"); yyerrok;}
| error {yyerror("Invalid statement");}
;
// statement FOLLOW = [IDENTIFIER CALL BEGIN IF WHILE FOR BREAK RETURN WRITELINE READ READLINE %empty '.' ';' END ELSE]
ConditionalStatement: IF Condition THEN Statement %prec IFX
| IF Condition THEN Statement ELSE Statement
;
LoopStatement: WHILE Condition DO Statement
| FOR IDENTIFIER UPTO Expression DO Statement
| FOR IDENTIFIER DOWNTO Expression DO Statement
| WHILE error {yyerror("Invalid while construct"); yyclearin;} Statement
| FOR error {yyerror("Invalid for construct"); yyclearin;} Statement
;
IOStatement:
READ'(' IDENTIFIER ')' {read($3);}
| WRITE'(' IDENTIFIER ')' {write($3);}
| WRITELINE '(' IDENTIFIER ')' {writeline($3);}
| READ '(' error ')' {yyerror("Invalid read() call"); yyerrok;}
| WRITE '(' error ')' {yyerror("Invalid write() call"); yyerrok;}
| WRITELINE '(' error ')' {yyerror("Invalid writeline() call"); yyerrok;}
;
FuncCall:
CALL IDENTIFIER '(' GeneralList ')'
;
ControlStatement:
BREAK | RETURN | RETURN Expression ;
StatementList:
Statement
| StatementList ';' Statement
| StatementList error {yyerror("Missing semicolon"); yyerrok;} Statement
;
Condition :
ODD Expression {$$ = odd(string($2));}
| Expression EQ Expression {$$ = condition(string("eq"), string($1), string($3));}
| Expression IDK Expression {$$ = condition(string("ne"), string($1), string($3));}
| Expression GT Expression {$$ = condition(string("sgt"), string($1), string($3));}
| Expression LT Expression {$$ = condition(string("slt"), string($1), string($3));}
| Expression LEQ Expression {$$ = condition(string("sle"), string($1), string($3));}
| Expression GEQ Expression {$$ = condition(string("sge"), string($1), string($3));}
;
ConstArray: NUMBER
| ConstArray ',' NUMBER
| ConstArray error NUMBER {yyerror("Invalid list construct"); yyerrok;}
;
GeneralList: NUMBER
| IDENTIFIER {$$ = loadvariable(string($1));}
| GeneralList ',' NUMBER
| GeneralList ',' IDENTIFIER
| GeneralList error NUMBER {yyerror("Invalid list construct"); yyerrok;}
| GeneralList error IDENTIFIER {yyerror("Invalid list construct"); yyerrok;}
|
;
Expression : Expression '+' Expression {$$ = operation(string("add"), string($1), string($3));}
| Expression '-' Expression {$$ = operation(string("sub"),string($1),string($3)) ;}
| Expression '*' Expression {$$ = operation(string("mul"),string($1),string($3)) ;}
| Expression '/' Expression {$$ = operation(string("sdiv"),string($1),string($3)) ;}
| Expression '%' Expression {$$ = operation(string("srem"), string($1), string($3));}
| '+' Expression %prec UPLUS { $$ = $2; }
| '-' Expression %prec UMINUS { $$ = operation(string("sub"),string("0"),string($2)); }
| IDENTIFIER {$$ = loadvariable(string($1));}
| IDENTIFIER '[' Expression ']' {}
| NUMBER { $$ = $1 ; }
| '(' Expression ')' { $$ = $2 ; }
| FuncCall
;
%%