forked from Ritaja/BlueCompiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser.y
141 lines (108 loc) · 5.2 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
%error-verbose /* instruct bison to generate verbose error messages*/
%{
#include "astgen.h"
#define YYDEBUG 1
/* Since the parser must return the AST, it must get a parameter where
* the AST can be stored. The type of the parameter will be void*. */
struct AstElement* astDest;
extern int yylex();
%}
%union {
double val;
char* op;
char* name;
struct AstElement* ast; /* this is the new member to store AST elements */
}
%token TOKEN_BEGIN TOKEN_END TOKEN_WHILE TOKEN_DO BOX_OPEN BOX_CLOSE
%token TOKEN_IF TOKEN_ELSE TOKEN_COMMA TOKEN_VECTOR TOKEN_RETURN
%token TOKEN_POW TOKEN_FACTORIAL TOKEN_ACOS TOKEN_SQRT TOKEN_MIN BEGIN_FUNC
%token TOKEN_ROTATEZ TOKEN_MAGNITUDESQR TOKEN_TRANSFORM TOKEN_DOT TOKEN_CROSS
%token TOKEN_VECTOR2d
%token<name> TOKEN_ID
%token<val> TOKEN_NUMBER
%token<op> TOKEN_OPERATOR
%type<ast> program block statements statement assignment expression arrExpression whileStmt call ifStmt func
%type<ast> signature signatures array vector vector2d vectors return
%start program
%{
/* Forward declarations */
void yyerror(const char* const message);
%}
%%
program: statement';' { astDest = $1; };
block: TOKEN_BEGIN statements TOKEN_END{ $$ = $2; };
statements: {$$=0;}
| statements statement ';' {$$=makeStatement($1, $2);}
| statements block';' {$$=makeStatement($1, $2);};
statement:
whileStmt {$$=$1;}
| ifStmt{$$=$1;}
| block {$$=$1;}
| call {$$=$1;}
| func {$$=$1;}
| vector {$$=$1;}
| vector2d {$$=$1;}
| return {$$=$1;}
| assignment {$$=$1;}
assignment: TOKEN_ID '=' expression {$$=makeAssignment($1, $3);}
| TOKEN_ID {$$=makeAssignment($1);};
| TOKEN_ID BOX_OPEN TOKEN_NUMBER BOX_CLOSE '=' expression {$$=makeVecAssignment($1, $3, $6);}
| TOKEN_ID BOX_OPEN TOKEN_NUMBER BOX_CLOSE BOX_OPEN TOKEN_NUMBER BOX_CLOSE '=' expression {$$=makeVec2dAssignment($1, $3, $6, $9);}
| TOKEN_ID '=' call{$$=makeFuncAssignment($1, $3);}
/* see how to support x=a[]+b[]*/
expression: TOKEN_ID {$$=makeExpByName($1);}
| TOKEN_NUMBER {$$=makeExpByNum($1);}
| TOKEN_OPERATOR expression {$$=makeExp(NULL,$2,$1);}
| expression TOKEN_OPERATOR expression {$$=makeExp($1, $3, $2);}
| TOKEN_ID BOX_OPEN TOKEN_NUMBER BOX_CLOSE {$$=makeVec1delement($1, $3);};
| TOKEN_ID BOX_OPEN TOKEN_NUMBER BOX_CLOSE BOX_OPEN TOKEN_NUMBER BOX_CLOSE {$$=makeVec2delement($1, $3, $6);};
| TOKEN_POW '(' expression TOKEN_COMMA expression ')'{$$=makePow($3, $5);};
| TOKEN_FACTORIAL '(' expression ')'{$$=makeFact($3);};
| TOKEN_ACOS '(' expression ')'{$$=makeAcos($3);};
| TOKEN_SQRT '(' expression ')'{$$=makeSqrt($3);};
| TOKEN_ROTATEZ '(' expression TOKEN_COMMA expression ')'{$$=makeRotatez($3,$5);};
| TOKEN_MAGNITUDESQR '(' expression ')'{$$=makeMagnitudesqr($3);};
| TOKEN_MIN '(' expression TOKEN_COMMA expression TOKEN_COMMA expression ')'{$$=makeMin($3,$5,$7);};
| TOKEN_DOT '(' expression TOKEN_COMMA expression ')'{$$=makeDot($3,$5);};
| TOKEN_CROSS '(' expression TOKEN_COMMA expression ')'{$$=makeCross($3,$5);};
| TOKEN_TRANSFORM '(' expression ')'{$$=makeTransform($3);};
| '(' expression TOKEN_OPERATOR expression ')' {$$=makeExp($2, $4, $3);}
arrExpression: TOKEN_ID {$$=makeExpByName($1);}
| TOKEN_NUMBER {$$=makeExpByNum($1);}
| arrExpression TOKEN_OPERATOR arrExpression {$$=makeExp($1, $3, $2);}
array: {$$=0;}
| array TOKEN_COMMA arrExpression {$$=makeArray($1,$3);}
| array arrExpression {$$=makeArray($1,$2);}
vector: TOKEN_VECTOR TOKEN_ID '=' '(' array ')' {$$=makeVector($2,$5);}
| TOKEN_VECTOR TOKEN_ID '=' '(' ')' {$$=makeNullVector($2);}
| TOKEN_VECTOR TOKEN_ID '=' arrExpression {$$=makeAssignment($2, $4);}
vector2d: TOKEN_VECTOR2d TOKEN_ID '=' BOX_OPEN vectors BOX_CLOSE {$$=makeVector2d($2,$5);}
| TOKEN_VECTOR2d TOKEN_ID '=' arrExpression {$$=makeAssignment($2, $4);}
/*check null vectors creation*/
vectors: {$$=0;}
| vectors TOKEN_COMMA '(' array ')' {$$=makeVectors($1,$4);}
| vectors '(' array ')' {$$=makeVectors($1,$3);}
| vectors '(' ')' {$$=makeNullVectors();}
whileStmt: TOKEN_WHILE '(' expression ')' TOKEN_DO statement{$$=makeWhile($3, $6);};
/*if multiple else if support is required create a separate structure*/
ifStmt: TOKEN_IF '(' expression ')' TOKEN_DO statement{$$=makeIf($3, $6);};
| TOKEN_IF '(' expression ')' TOKEN_DO statement TOKEN_ELSE TOKEN_DO statement{$$=makeIf($3, $6, $9);};
| TOKEN_IF '(' expression ')' TOKEN_DO statement TOKEN_ELSE TOKEN_IF '(' expression ')' TOKEN_DO statement TOKEN_ELSE TOKEN_DO statement{$$=makeElseIf($3, $6, $10, $13, $16);};
func: BEGIN_FUNC TOKEN_ID '(' ')' statement {$$=makeFunc($2, $5);};
| BEGIN_FUNC TOKEN_ID '(' signatures ')' statement {$$=makeFunc($2, $4, $6);};
signatures: {$$=0;}
|signature signatures{$$=makeSignatures($2,$1);}
signature:
TOKEN_COMMA TOKEN_ID assignment{$$=makeSignature($2,$3);}
|TOKEN_ID assignment{$$=makeSignature($1,$2);}
call: TOKEN_ID '(' array ')' {$$=makeCall($1, $3);};
return: TOKEN_RETURN expression{$$=makeReturnByExp($2);}
%%
#include "astexec.h"
#include <stdlib.h>
void yyerror(const char* const message)
{
extern int yylineno;
fprintf(stderr, "Error occurred near line: %d\n", yylineno);
fprintf(stderr, "Parse error:%s\n", message);
}