-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.ypp
More file actions
157 lines (136 loc) · 4.67 KB
/
Copy pathparser.ypp
File metadata and controls
157 lines (136 loc) · 4.67 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
%{
#include <stdio.h>
#include <iostream>
#include <string>
#include <fstream>
#include "../memory.h"
#include "../code_generator.h"
#include "../code_writer.h"
#include "../instruction_generators.h"
#include "../tokens.h"
using namespace std;
Memory* memory;
CodeGenerator* codeGen;
CodeWriter* code;
extern FILE* yyin;
extern int yylineno;
int yylex (void);
void yyerror (string);
%}
%union values{
unsigned long long num;
std::string* pid;
Identifier* id;
Value* val;
CommandList* cmdList;
Command* cmd;
Expression* exp;
Condition* cond;
}
%start program
%token DECLARE MY_BEGIN END
%token IF THEN ELSE ENDIF
%token WHILE DO ENDWHILE
%token REPEAT UNTIL
%token FOR FROM TO DOWNTO ENDFOR
%token IS EQ DIF LT GT EQLT EQGT
%token READ WRITE
%token <pid> pidentifier
%token <num> num
// helper
%type <val> value
%type <id> identifier
%type <cmd> command
%type <cmdList> commands
%type <cond> condition;
%type <exp> expression;
// arithmetic operations
%left SUB ADD
%left MUL DIV MOD
%%
program
: DECLARE declarations MY_BEGIN commands END {codeGen->setCommandList($4);}
| MY_BEGIN commands END {codeGen->setCommandList($2);}
;
declarations
: declarations ',' pidentifier {memory->declareVariable(*$3);}
| declarations ',' pidentifier'('num':'num')' {memory->declareArray(*$3, $5, $7);}
| pidentifier {memory->declareVariable(*$1);}
| pidentifier'('num':'num')' {memory->declareArray(*$1, $3, $5);}
;
commands
: commands command {$1->push_back($2); $$ = $1;}
| command {CommandList* commandList = new CommandList();commandList->push_back($1); $$ = commandList;}
;
command
: identifier IS expression ';' {$$ = new IsCommand($1, $3);}
| IF condition THEN commands ELSE commands ENDIF {$$ = new IfElseCommand($2, $4, $6);}
| IF condition THEN commands ENDIF {$$ = new IfCommand($2, $4);}
| WHILE condition DO commands ENDWHILE {$$ = new WhileCommand($2, $4);}
| REPEAT commands UNTIL condition ';' {$$ = new RepeatCommand($4, $2);}
| FOR pidentifier FROM value TO value {memory->declareIterator(*$2);}
DO commands ENDFOR {$$ = new ForCommand(*$2, $4, $6, $9);memory->getIterator(*$2)->isInsideLoop=false;}
| FOR pidentifier FROM value DOWNTO value {memory->declareIterator(*$2);}
DO commands ENDFOR {$$ = new ForDowntoCommand(*$2, $4, $6, $9);memory->getIterator(*$2)->isInsideLoop=false;}
| READ identifier ';' {$$ = new ReadCommand($2);}
| WRITE value ';' {$$ = new WriteCommand($2);}
;
expression
: value {$$ = new ValueExpression($1);}
| value ADD value {$$ = new AddExpression($1, $3);}
| value SUB value {$$ = new SubExpression($1, $3);}
| value MUL value {$$ = new MulExpression($1, $3);}
| value DIV value {$$ = new DivExpression($1, $3);}
| value MOD value {$$ = new ModExpression($1, $3);}
;
condition
: value EQ value {$$ = new EqualCondition($1, $3);}
| value DIF value {$$ = new DiffCondition($1, $3);}
| value LT value {$$ = new LessThanCondition($1, $3);}
| value GT value {$$ = new GreaterThanCondition($1, $3);}
| value EQLT value {$$ = new LessEqualCondition($1, $3);}
| value EQGT value {$$ = new GreaterEqualCondition($1, $3);}
;
value
: num {$$ = new Value($1);}
| identifier {$$ = new Value($1);}
;
identifier
: pidentifier {$$ = new Identifier(*$1);}
| pidentifier'('pidentifier')' {$$ = new Identifier(*$1, *$3);}
| pidentifier'('num')' {$$ = new Identifier(*$1, $3);}
;
%%
void yyerror(std::string s){
cout /*<< "Error in line " << yylineno << ": "*/ << s << endl;
exit(1);
return;
}
int main(int argc, char* argv[]){
if (argc < 3)
{
cout << "Not enough arguments" << endl;
return 1;
} else {
yyin = fopen(argv[1], "r");
if (yyin == NULL)
{
cout << "File " << argv[1] << " does not exist" << endl;
return 1;
}
try
{
memory = new Memory();
codeGen = new CodeGenerator();
code = new CodeWriter();
yyparse();
codeGen->generateMachineCode();
code->halt(); // TODO put it inside code generator somehow
code->writeOutput(argv[2]);
}
catch (string error)
{yyerror(error);
}
}
return 0;
}