-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjava.y
114 lines (90 loc) · 2.75 KB
/
java.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
%{
#include <stdio.h>
#include <stdlib.h>
#include "declarations.h"
#include "symtab.h"
#include "semantic.h"
#include "codeGen.h"
%}
/*
You dont have to declare a type for a token or declare a nonterminal at all if you dont
use the symbols value.
If there is a %union in the declarations, bison will give you an
error if you attempt to use the value of a symbol that doesnt have an assigned type.
*/
// value of symbol used by bison "yyval"
%union {
struct ast* a ;
double d ;
struct symbol *s ; /* pointer to the symbol in the symbol table */
struct symlist *sl ;
int fn ; /* which comparaison operator */
}
%token CLASS
%token <d> NUMBER
%token <s> NAME
%token IF ELSE WHILE MODIFIER TYPE RETURN
%nonassoc <fn> CMP
/* order of precedence from lowest to highest */
%right '='
%left '+' '-'
%left '*' '/'
%type <a> E list stmt assignment func_call args list_arg cond declaration
%type <sl> var_list vars
%%
// TODO : add print all functions after code Gen
program :
| CLASS NAME '{' list '}' { struct ast * res = $4 ; codeGen(res); add_function_bodies(); }
;
/* type ast */
stmt : IF '(' cond ')' '{' list '}' {$$ = newflow('I',$3,$6,NULL); }
| IF '(' cond ')' '{' list '}' ELSE '{' list '}' {$$ = newflow('I',$3,$6,$10);}
| WHILE '(' cond ')' '{' list '}' {$$ = newflow('W',$3,$6,NULL);}
| assignment ';'
| func_call ';'
| declaration ';'
;
list : { $$ = NULL; }
| stmt list { if($2==NULL)
$$ = $1;
else
$$ = newast('L',$1,$2);
}
| func_def list { $$ = $2 ; }
;
assignment : NAME '=' E { $$ = newasgn(undeclared_id($1->name),$3);}
;
declaration : TYPE NAME { $$ = newasgn(check_multiply_declared_id($2->name),NULL);}
| TYPE NAME '=' E { $$ = newasgn(check_multiply_declared_id($2->name),$4);}
;
E : E '+' E {$$ = newast('+',$1,$3);}
| E '-' E {$$ = newast('-',$1,$3);}
| E '*' E {$$ = newast('*',$1,$3);}
| E '/' E {$$ = newast('/',$1,$3);}
| '(' E ')' { $$ = $2 ; }
| NUMBER { $$ = newnum($1);}
| NAME { $$ = newref(undeclared_id($1->name));}
;
/* add not and AND oR */
cond : E CMP E {$$ = newcmp($2,$1,$3);}
;
func_def : MODIFIER TYPE NAME '(' vars ')' '{' list '}' {
def_func(check_multiply_declared_id($3->name),$5,$8);
}
;
// TODO : make vars return a linked list of symbol tables
vars : { $$ = NULL ; }
| var_list
;
var_list : TYPE NAME { $$ = newsymlist($2,NULL);}
| TYPE NAME ',' var_list { $$ = newsymlist($2,$4); }
;
func_call : NAME '(' args ')' { $$ = newfunc(undeclared_id($1->name),$3); } /* function call*/
;
args : { $$ = NULL; }
| list_arg { $$ = $1 ;} /*default */
;
list_arg : E {$$ = newast('L',$1,NULL);}
| E ',' list_arg {$$ = newast('L',$1,$3);}
;
%%