This repository has been archived by the owner on Oct 28, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.y
198 lines (163 loc) · 9.99 KB
/
parser.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
%code requires{
#include "ast.h"
}
%{
#define YYERROR_VERBOSE 1
#include <iostream>
#include "ast.h"
using namespace std;
extern bool helper_isArray(string name);
Statement* code_tree;
extern int yylineno;
int yylex();
int yyerror(const char* msg){
cerr << yylineno << ": " << msg << endl;
exit(1);
}
%}
%union{
Expression* expression;
Statement* statement;
vector<Expression*>* array_values;
vector<struct function_parameter>* function_statement_params;
string* literal;
int integer;
bool boolean;
}
%token PARENTHESIS_LEFT PARENTHESIS_RIGHT BRACKET_LEFT BRACKET_RIGHT CURLY_LEFT CURLY_RIGHT COMA SEMICOLON COLON DOUBLE_COLON NEWLINE
%token OPERATOR_ADD OPERATOR_SUB OPERATOR_MUL OPERATOR_DIV OPERATOR_MOD OPERATOR_POW
%token OPERATOR_SAL OPERATOR_SLR OPERATOR_SAR OPERATOR_OR OPERATOR_XOR OPERATOR_AND OPERATOR_NOT
%token COMPARISON_GT COMPARISON_LT COMPARISON_EQ COMPARISON_GE COMPARISON_LE COMPARISON_NE COMPARISON_AND COMPARISON_OR OPERATOR_NEG
%token KW_PRINT KW_PRINTLN KW_ARRAY KW_IF KW_ELSEIF KW_ELSE KW_WHILE KW_FOR KW_FUNCTION KW_RETURN KW_END
%token LITERAL IDENTIFIER INTEGER BOOLEAN
%token TYPE OPERATOR_ASSIGN
%type<statement> optional_statements statement_list statement print print_params assign else
%type<expression> condition condition_ooo_l1 expression expression_ooo_l1 expression_ooo_l2 expression_ooo_l3 expression_ooo_l4 expression_ooo_l5 expression_ooo_l6 final_value optional_function_expression_params function_expression_params
%type<array_values> array
%type<function_statement_params> optional_function_statement_params function_statement_params
%type<literal> LITERAL IDENTIFIER
%type<integer> INTEGER TYPE
%type<boolean> BOOLEAN
%%
initial: optional_statements { code_tree = $1; }
;
optional_statements: optional_statement_separators statement_list optional_statement_separators { $$ = $2; }
| optional_statement_separators { $$ = new StatementBlock(); } //Set $$ = NULL to create no code.
;
optional_statement_separators: statement_separator
|
;
statement_separator: statement_separator NEWLINE
| statement_separator SEMICOLON
| NEWLINE
| SEMICOLON
;
optional_newlines: many_newlines
|
;
many_newlines: many_newlines NEWLINE
| NEWLINE
;
statement_list: statement_list statement_separator statement { $$ = $1; ((StatementBlock*)$$)->addStatement($3); }
| statement { $$ = new StatementBlock(); ((StatementBlock*)$$)->addStatement($1); }
;
statement: print { $$ = $1; }
| condition { $$ = new ExpressionStatement($1); }
| assign { $$ = $1; }
| KW_IF condition optional_statements else KW_END { $$ = new IfStatement($2, $3, $4); }
| KW_FUNCTION IDENTIFIER PARENTHESIS_LEFT optional_function_statement_params PARENTHESIS_RIGHT DOUBLE_COLON TYPE optional_statements KW_END { $$ = new FunctionStatement(*$2, $7, $4, $8); }
| KW_WHILE condition optional_statements KW_END { $$ = new WhileStatement($2, $3); }
| KW_FOR IDENTIFIER OPERATOR_ASSIGN condition COLON condition optional_statements KW_END { $$ = new ForStatement(*$2, $4, $6, $7); }
| KW_RETURN condition { $$ = new ReturnStatement($2); }
;
print: KW_PRINT PARENTHESIS_LEFT print_params PARENTHESIS_RIGHT { $$ = $3; ((PrintStatement*)$$)->printline(false); }
| KW_PRINTLN PARENTHESIS_LEFT print_params PARENTHESIS_RIGHT { $$ = $3; ((PrintStatement*)$$)->printline(true); }
;
print_params: print_params COMA optional_newlines LITERAL { $$ = $1; struct parameter_type parameter; parameter.type = TYPE_LITERAL; parameter.literal = new string(*$4); ((PrintStatement*)$$)->addParameter(parameter); }
| print_params COMA optional_newlines condition { $$ = $1; struct parameter_type parameter; parameter.type = -1; parameter.expression = $4; ((PrintStatement*)$$)->addParameter(parameter); }
| LITERAL { $$ = new PrintStatement(); struct parameter_type parameter; parameter.type = TYPE_LITERAL; parameter.literal = new string(*$1); ((PrintStatement*)$$)->addParameter(parameter); }
| condition { $$ = new PrintStatement(); struct parameter_type parameter; parameter.type = -1; parameter.expression = $1; ((PrintStatement*)$$)->addParameter(parameter); }
;
assign: IDENTIFIER DOUBLE_COLON TYPE { $$ = new DeclareStatement(*$1, $3, 1); }
| IDENTIFIER DOUBLE_COLON TYPE OPERATOR_ASSIGN optional_newlines condition { $$ = new AssignStatement(1, *$1, new IntegerExpression(1), $3, $6); }
| IDENTIFIER BRACKET_LEFT condition BRACKET_RIGHT OPERATOR_ASSIGN optional_newlines condition { $$ = new AssignStatement(2, *$1, $3, -1, $7); }
| IDENTIFIER DOUBLE_COLON KW_ARRAY CURLY_LEFT TYPE CURLY_RIGHT PARENTHESIS_LEFT INTEGER PARENTHESIS_RIGHT { $$ = new DeclareStatement(*$1, $5, $8); }
| IDENTIFIER OPERATOR_ASSIGN optional_newlines condition { $$ = new AssignStatement(3, *$1, new IntegerExpression(1), -1, $4); } //position useless
| IDENTIFIER DOUBLE_COLON KW_ARRAY CURLY_LEFT TYPE CURLY_RIGHT OPERATOR_ASSIGN optional_newlines IDENTIFIER { $$ = new AssignStatement(4, *$1, new IntegerExpression(0), $5, new IdentifierExpression(*$9)); } //position useless
| IDENTIFIER DOUBLE_COLON KW_ARRAY CURLY_LEFT TYPE CURLY_RIGHT OPERATOR_ASSIGN optional_newlines BRACKET_LEFT array BRACKET_RIGHT {
$$ = new StatementBlock();
((StatementBlock*)$$)->addStatement(new DeclareStatement(*$1, $5, $10->size()));
int position = 1;
for(Expression* expression : *$10)
((StatementBlock*)$$)->addStatement(new SetStatement(*$1, expression, new IntegerExpression(position++)));
}
;
array: array COMA optional_newlines condition { $$ = $1; $$->push_back($4); }
| condition { $$ = new vector<Expression*>; $$->push_back($1); }
;
else: KW_ELSEIF condition optional_statements else { $$ = new IfStatement($2, $3, $4); }
| KW_ELSE optional_statements { $$ = $2; }
| { $$ = new StatementBlock(); }
;
optional_function_statement_params: function_statement_params { $$ = $1; }
| { $$ = new vector<function_parameter>; }
;
function_statement_params: function_statement_params COMA optional_newlines IDENTIFIER DOUBLE_COLON TYPE { $$ = $1; struct function_parameter fp; fp.name = *$4; fp.type = $6; fp.size = 1; $$->push_back(fp); }
| IDENTIFIER DOUBLE_COLON TYPE { $$ = new vector<function_parameter>; struct function_parameter fp; fp.name = *$1; fp.type = $3; fp.size = 1; $$->push_back(fp); }
;
condition: condition_ooo_l1 { $$ = $1; }
| condition COMPARISON_AND optional_newlines condition_ooo_l1 { $$ = new ComparisonAndExpression($1, $4); }
| condition COMPARISON_OR optional_newlines condition_ooo_l1 { $$ = new ComparisonOrExpression($1, $4); }
;
condition_ooo_l1: expression { $$ = $1; }
| condition_ooo_l1 COMPARISON_GT optional_newlines expression { $$ = new GTExpression($1, $4); }
| condition_ooo_l1 COMPARISON_LT optional_newlines expression { $$ = new LTExpression($1, $4); }
| condition_ooo_l1 COMPARISON_EQ optional_newlines expression { $$ = new EQExpression($1, $4); }
| condition_ooo_l1 COMPARISON_GE optional_newlines expression { $$ = new GEExpression($1, $4); }
| condition_ooo_l1 COMPARISON_LE optional_newlines expression { $$ = new LEExpression($1, $4); }
| condition_ooo_l1 COMPARISON_NE optional_newlines expression { $$ = new NEExpression($1, $4); }
;
expression: expression_ooo_l1 { $$ = $1; }
| expression OPERATOR_ADD optional_newlines expression_ooo_l1 { $$ = new AddExpression($1, $4); }
| expression OPERATOR_SUB optional_newlines expression_ooo_l1 { $$ = new SubExpression($1, $4); }
;
expression_ooo_l1: expression_ooo_l2 { $$ = $1; }
| expression_ooo_l1 OPERATOR_OR optional_newlines expression_ooo_l2 { $$ = new OrExpression($1, $4); }
| expression_ooo_l1 OPERATOR_XOR optional_newlines expression_ooo_l2 { $$ = new XorExpression($1, $4); }
;
expression_ooo_l2: expression_ooo_l3 { $$ = $1; }
| expression_ooo_l2 OPERATOR_SAL optional_newlines expression_ooo_l3 { $$ = new SalExpression($1, $4); }
| expression_ooo_l2 OPERATOR_SAR optional_newlines expression_ooo_l3 { $$ = new SarExpression($1, $4); }
| expression_ooo_l2 OPERATOR_SLR optional_newlines expression_ooo_l3 { $$ = new SlrExpression($1, $4); }
;
expression_ooo_l3: expression_ooo_l4 { $$ = $1; }
| expression_ooo_l3 OPERATOR_AND optional_newlines expression_ooo_l4 { $$ = new AndExpression($1, $4); }
;
expression_ooo_l4: expression_ooo_l5 { $$ = $1; }
| expression_ooo_l4 OPERATOR_MUL optional_newlines expression_ooo_l5 { $$ = new MulExpression($1, $4); }
| expression_ooo_l4 OPERATOR_DIV optional_newlines expression_ooo_l5 { $$ = new DivExpression($1, $4); }
| expression_ooo_l4 OPERATOR_MOD optional_newlines expression_ooo_l5 { $$ = new ModExpression($1, $4); }
;
expression_ooo_l5: expression_ooo_l6 { $$ = $1; }
| expression_ooo_l6 OPERATOR_POW optional_newlines expression_ooo_l5 { $$ = new PowExpression($1, $4); }
;
expression_ooo_l6: final_value { $$ = $1; }
| OPERATOR_NOT expression_ooo_l6 { $$ = new NNExpression($2); }
| OPERATOR_NEG expression_ooo_l6 { $$ = new NegExpression($2); }
| OPERATOR_ADD expression_ooo_l6 { $$ = $2; }
| OPERATOR_SUB expression_ooo_l6 { $$ = new MulExpression(new IntegerExpression(-1), $2); }
;
final_value: PARENTHESIS_LEFT condition PARENTHESIS_RIGHT { $$ = $2; }
| BOOLEAN { $$ = new BooleanExpression($1); }
| INTEGER { $$ = new IntegerExpression($1); }
| IDENTIFIER { $$ = new IdentifierExpression(*$1); }
| IDENTIFIER BRACKET_LEFT condition BRACKET_RIGHT { $$ = new IdentifierExpression(*$1, $3); }
| IDENTIFIER PARENTHESIS_LEFT optional_function_expression_params PARENTHESIS_RIGHT { $$ = $3; ((FunctionExpression*)$$)->addName(*$1); }
;
optional_function_expression_params: function_expression_params { $$ = $1; }
| { $$ = new FunctionExpression(); }
;
function_expression_params: function_expression_params COMA optional_newlines condition { $$ = $1; ((FunctionExpression*)$$)->addParameter($4); }
| condition { $$ = new FunctionExpression(); ((FunctionExpression*)$$)->addParameter($1); }
;
%%