-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathparser.y
More file actions
513 lines (427 loc) · 11.8 KB
/
Copy pathparser.y
File metadata and controls
513 lines (427 loc) · 11.8 KB
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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
%{
/* Parser.y
*
* Grammer for the JavaScript Language
*
* Part III Project at University of Southampton, UK
* Alex Walker - javascript@soton.net
* not very stable, just trying out...
*
* Created 980129
*/
#include "header.h"
#include <stdio.h>
void error(int, char *msg);
void report_errors();
%}
%{
/* Now follows all JavaScript keywords, reserved words, etc.
* These are all to be defined as tokens.
* If yacc is called with the -d flag, y.tab.h is generated
* to include these tokens. This file is then #include'd
* by the lexer.
*/
%}
%union
{
SYMB *symb;
}
%token ASSIGN_SYMBOL
%token BITWISE_AND
%token BITWISE_AND_EQUALS
%token BITWISE_EXCLUSIVE_OR
%token BITWISE_EXCLUSIVE_OR_EQUALS
%token BITWISE_OR
%token BITWISE_OR_EQUALS
%token BITWISE_SHIFT_LEFT
%token BITWISE_SHIFT_LEFT_EQUALS
%token BITWISE_SHIFT_RIGHT
%token BITWISE_SHIFT_RIGHT_EQUALS
%token BITWISE_SHIFT_RIGHT_ZERO_FILL
%token BITWISE_SHIFT_RIGHT_ZERO_FILL_EQUALS
%token BREAK
%token CLOSE_PARENTHESIS
%token CLOSE_SQ_BRACKETS
%token COLON
%token COMMA
%token CONTINUE
%token DECREMENT
%token DELETE
%token DIV
%token DIV_EQUALS
%token DOT
%token ELSE
%token END_BLOCK
%token EQUALS
%token FALSE
%token FOR
%token FUNCTION
%token GREATER_THAN
%token GT_EQUAL
%token IF
%token INCREMENT
%token INFINITY
%token IN
%token LESS_THAN
%token LINE_TERMINATOR
%token LOGICAL_AND
%token LOGICAL_OR
%token LOGICAL_NOT
%token LS_EQUAL
%token MINUS
%token MINUS_EQUALS
%token MOD
%token MOD_EQUALS
%token MULTIPLY
%token MULTIPLY_EQUALS
%token NEW
%token NOT_EQUAL
%token NULL_TOKEN
%token NUMBER
%token ONES_COMPLIMENT
%token OPEN_PARENTHESIS
%token OPEN_SQ_BRACKETS
%token PLUS
%token PLUS_EQUALS
%token QUERY
%token RETURN
%token SEMICOLON
%token START_BLOCK
%token STRING
%token THIS
%token TRUE
%token TYPEOF
%token UNDEFINED_TOKEN
%token VAR
%token <symb> VARIABLE
%token VOID_SYMBOL
%token WHILE
%token WITH
%left PLUS MINUS
%left MULTIPLY DIV MOD
%nonassoc FALSE
%nonassoc HIGHER_THAN_FALSE
%nonassoc ELSE
%nonassoc LOWER_THAN_CLOSE_PARENTHESIS
%nonassoc CLOSE_PARENTHESIS
%%
Program : SourceElements
;
SourceElements : SourceElement
| SourceElements SourceElement
;
SourceElement : Statement
| FunctionDeclaration
;
Statement : Block
| VariableStatement
| EmptyStatement
| ExpressionStatement
| IfStatement
| IterationExpression
| ContinueStatement
| BreakStatement
| ReturnStatement
| WithStatement
;
FunctionDeclaration : FUNCTION VARIABLE OPEN_PARENTHESIS FormalParameterList CLOSE_PARENTHESIS Block
{
if ($2->type == T_FUNCTION) {
error(ERROR, "Function with this name is already declared.");
} else if ($2->type != T_UNDECLARED) {
error(ERROR, "Function name is already in use as a variable.");
} else {
$2->type = T_FUNCTION;
}
}
| FUNCTION VARIABLE OPEN_PARENTHESIS CLOSE_PARENTHESIS Block
{
if ($2->type == T_FUNCTION) {
error(ERROR, "Function with this name is already declared.");
} else if ($2->type != T_UNDECLARED) {
error(ERROR, "Function name is already in use as a variable.");
} else{
$2->type = T_FUNCTION;
}
}
;
FormalParameterList : VARIABLE
| FormalParameterList COMMA VARIABLE
;
StatementList : Statement
| StatementList Statement
;
Block : START_BLOCK StatementList END_BLOCK;
| START_BLOCK END_BLOCK
;
VariableStatement : VAR VariableDeclarationList SEMICOLON
;
EmptyStatement : SEMICOLON
;
ExpressionStatement : Expression SEMICOLON
;
IfStatement : IF OPEN_PARENTHESIS Expression CLOSE_PARENTHESIS Statement %prec HIGHER_THAN_FALSE
| IF OPEN_PARENTHESIS Expression CLOSE_PARENTHESIS Statement ELSE Statement
| IF OPEN_PARENTHESIS FALSE CLOSE_PARENTHESIS Statement
{
error(ERROR, "Unreachable code portion");
}
| IF OPEN_PARENTHESIS LeftHandSideExpression AssignmentOperator AssignmentExpression CLOSE_PARENTHESIS Statement
{
error(WARNING, "Possible error in IF Expression (e.g. a=b instead of a==b)");
}
;
IterationExpression : WHILE OPEN_PARENTHESIS Expression CLOSE_PARENTHESIS Statement %prec HIGHER_THAN_FALSE
| WHILE OPEN_PARENTHESIS FALSE CLOSE_PARENTHESIS Statement
{
error(ERROR, "Unreachable code portion");
}
| WHILE OPEN_PARENTHESIS LeftHandSideExpression AssignmentOperator AssignmentExpression CLOSE_PARENTHESIS Statement
{
error(WARNING, "Possible error in WHILE Expression (e.g. a=b instead of a==b)");
}
| FOR OPEN_PARENTHESIS OptionalExpression SEMICOLON OptionalExpression SEMICOLON OptionalExpression CLOSE_PARENTHESIS Statement
| FOR OPEN_PARENTHESIS VAR VariableDeclarationList SEMICOLON OptionalExpression SEMICOLON OptionalExpression CLOSE_PARENTHESIS Statement
| FOR OPEN_PARENTHESIS LeftHandSideExpression IN Expression CLOSE_PARENTHESIS Statement
| FOR OPEN_PARENTHESIS VAR VARIABLE OptionalInitializer IN Expression CLOSE_PARENTHESIS Statement
;
ContinueStatement : CONTINUE SEMICOLON
;
BreakStatement : BREAK SEMICOLON
;
ReturnStatement : RETURN Expression SEMICOLON
| RETURN SEMICOLON
;
WithStatement : WITH OPEN_PARENTHESIS Expression CLOSE_PARENTHESIS Statement
;
VariableDeclarationList : VariableDeclaration
| VariableDeclarationList COMMA VariableDeclaration
;
VariableDeclaration : VARIABLE
{
if ($1->type == T_FUNCTION) {
error(ERROR, "Variable given same name as an existing function.");
} else $1->type = T_UNDEFINED;
}
| VARIABLE Initializer
{
if ($1->type == T_FUNCTION) {
error(ERROR, "Variable given same name as an existing function.");
} else $1->type = T_UNDEFINED;
}
;
Initializer : ASSIGN_SYMBOL AssignmentExpression
;
OptionalInitializer : Initializer
|
;
PrimaryExpression : THIS
| VARIABLE
{
if (($1->type == T_UNDECLARED) && (undeclared_flag == 1)) {
error(WARNING, "Possible use of undeclared variable");
}
}
| NUMBER
| STRING
| NULL_TOKEN
| TRUE
| FALSE
| OPEN_PARENTHESIS Expression CLOSE_PARENTHESIS
;
MemberExpression : PrimaryExpression
| MemberExpression OPEN_SQ_BRACKETS Expression CLOSE_SQ_BRACKETS
| MemberExpression DOT VARIABLE
| NEW MemberExpression Arguments
;
NewExpression : MemberExpression
| NEW NewExpression
;
CallExpression : MemberExpression Arguments
| CallExpression Arguments
| CallExpression OPEN_SQ_BRACKETS Expression CLOSE_SQ_BRACKETS
| CallExpression DOT VARIABLE
;
Arguments : OPEN_PARENTHESIS CLOSE_PARENTHESIS
| OPEN_PARENTHESIS ArgumentList CLOSE_PARENTHESIS
;
ArgumentList : AssignmentExpression
| ArgumentList COMMA AssignmentExpression
;
LeftHandSideExpression : NewExpression
| CallExpression
;
PostfixExpression : LeftHandSideExpression
| LeftHandSideExpression INCREMENT
| LeftHandSideExpression DECREMENT
;
UnaryExpression : PostfixExpression
| DELETE UnaryExpression
| VOID_SYMBOL UnaryExpression
| TYPEOF UnaryExpression
| INCREMENT UnaryExpression
| DECREMENT UnaryExpression
| PLUS UnaryExpression
| MINUS UnaryExpression
| ONES_COMPLIMENT UnaryExpression
| LOGICAL_NOT UnaryExpression
;
MultiplicativeExpression : UnaryExpression
| MultiplicativeExpression MULTIPLY UnaryExpression
| MultiplicativeExpression DIV UnaryExpression
| MultiplicativeExpression MOD UnaryExpression
;
AdditiveExpression : MultiplicativeExpression
| AdditiveExpression PLUS MultiplicativeExpression
| AdditiveExpression MINUS MultiplicativeExpression
;
ShiftExpression : AdditiveExpression
| ShiftExpression BITWISE_SHIFT_LEFT AdditiveExpression
| ShiftExpression BITWISE_SHIFT_RIGHT AdditiveExpression
| ShiftExpression BITWISE_SHIFT_RIGHT_ZERO_FILL AdditiveExpression
;
RelationalExpression : ShiftExpression
| RelationalExpression LESS_THAN ShiftExpression
| RelationalExpression GREATER_THAN ShiftExpression
| RelationalExpression LS_EQUAL ShiftExpression
| RelationalExpression GT_EQUAL ShiftExpression
;
EqualityExpression : RelationalExpression
| EqualityExpression EQUALS RelationalExpression
| EqualityExpression NOT_EQUAL RelationalExpression
;
BitwiseANDExpression : EqualityExpression
| BitwiseANDExpression BITWISE_AND EqualityExpression
;
BitwiseXORExpression : BitwiseANDExpression
| BitwiseXORExpression BITWISE_EXCLUSIVE_OR BitwiseANDExpression
;
BitwiseORExpression : BitwiseXORExpression
| BitwiseORExpression BITWISE_OR BitwiseXORExpression
;
LogicalANDExpression : BitwiseORExpression
| LogicalANDExpression LOGICAL_AND BitwiseORExpression
;
LogicalORExpression : LogicalANDExpression
| LogicalORExpression LOGICAL_OR LogicalANDExpression
;
ConditionalExpression : LogicalORExpression
| LogicalORExpression QUERY AssignmentExpression COLON AssignmentExpression
;
AssignmentExpression : ConditionalExpression
| LeftHandSideExpression AssignmentOperator AssignmentExpression %prec LOWER_THAN_CLOSE_PARENTHESIS
;
AssignmentOperator : ASSIGN_SYMBOL
| MULTIPLY_EQUALS
| DIV_EQUALS
| MOD_EQUALS
| PLUS_EQUALS
| MINUS_EQUALS
| BITWISE_SHIFT_LEFT_EQUALS
| BITWISE_SHIFT_RIGHT_EQUALS
| BITWISE_SHIFT_RIGHT_ZERO_FILL_EQUALS
| BITWISE_AND_EQUALS
| BITWISE_EXCLUSIVE_OR_EQUALS
| BITWISE_OR_EQUALS
;
Expression : AssignmentExpression
| Expression COMMA AssignmentExpression
;
OptionalExpression : Expression
|
;
%%
yyerror(s) char *s; {
error(ERROR, s);
}
void report_errors() {
ERRMSG *temp = errorlist;
ERRMSG *prev;
int i = 0;
while (temp != NULL) {
/* Increment counters */
if (temp->type == ERROR) {
numerrors++;
if (!errors_flag) {
prev = temp;
temp = temp->link;
free(prev);
continue;
}
}
if (temp->type == WARNING) {
numwarnings++;
if (!warnings_flag || !errors_flag) {
prev = temp;
temp = temp->link;
free(prev);
continue;
}
}
/* Print line number */
fprintf(stdout, "\nLine %d:\n", temp->lineno);
/* Print original code */
fprintf(stdout, "%s\n", linebuf);
/* Print arrow to point to offending token */
for (i=0;i<temp->offset-1;i++) {
if (linebuf[i] == '\t') {
fprintf(stdout,"\t");
}
else {
fprintf(stdout," ");
}
}
fprintf(stdout,"^----- ");
/* Print the type of error message */
if (temp->type == ERROR) {
fprintf(stdout, "Error: ");
} else if (temp->type == WARNING) {
fprintf(stdout, "Warning: ");
}
/* Print the error message */
if (strcmp(temp->message,"syntax error")) {
fprintf(stdout, "%s", temp->message);
}
else {
fprintf(stdout, "Syntax Error");
}
fprintf(stdout, "\n\n");
prev = temp;
temp = temp->link;
/* We're done with the old entry now, so free it up */
free(prev);
}
/* Set error list to NULL */
errorlist = NULL;
}
void error(int type, char *msg) {
/* Adds an entry to the list of errors for this line of code */
ERRMSG *e = (ERRMSG *)safe_malloc(sizeof(ERRMSG));
ERRMSG *temp;
/* Copy over the error message */
e->message = (char *)safe_malloc(strlen(msg)+1);
strcpy(e->message, msg);
/* Record the line number */
e->lineno = current_line;
/* Record the position in the line of the error */
e->offset = strlen(linebuf);
/* Record the error type */
e->type = type;
/* Set the link pointer to be NULL */
e->link = NULL;
/* Insert completed error structure into the error list */
/* Handles when list is empty */
if (errorlist == NULL) {
errorlist = e;
return;
}
/* Handles when list has one or more elements in it */
temp = errorlist;
while (1) {
if (temp->link == NULL) {
temp->link = e;
return;
}
else temp = temp->link;
}
}