-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathminijava.cup
174 lines (154 loc) · 6.86 KB
/
minijava.cup
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
/* Minijava Grammar */
import java_cup.runtime.ComplexSymbolFactory;
import java_cup.runtime.ScannerBuffer;
import java.io.*;
parser code {:
public Parser(Lexer lex, ComplexSymbolFactory sf) {
super(lex,sf);
}
public static void main(String[] args) throws Exception {
// initialize the symbol factory
ComplexSymbolFactory csf = new ComplexSymbolFactory();
// create a buffering scanner wrapper
ScannerBuffer lexer = new ScannerBuffer(new Lexer(new BufferedReader(new FileReader(args[0])),csf));
// start parsing
Parser p = new Parser(lexer,csf);
System.out.println(p.parse().value.toString());
}
:};
// terminals
terminal CLASS, WHILE, READLN, PRINTLN, IF, ELSE, THIS, NEW, NULL;
terminal Integer INTCONST;
terminal Boolean BOOLCONST;
terminal String STRING_LITERAL;
terminal MAINFUNC;
terminal PLUS, MINUS, TIMES, DIV, UMINUS;
terminal LT, GT, GEQ, LEQ, EQ, NEQ;
terminal OR, AND, NOT;
terminal LPAREN, RPAREN, LBLOCK, RBLOCK;
terminal COMMA, DOT, ENDSTMT;
terminal RETURN;
terminal ASSIGN;
terminal String IDNAME, CLASSNAME;
// non-terminals
non terminal ProgramAST program;
non terminal ClassAST mainclass;
non terminal FuncDeclAST mainfunction;
non terminal ListAST<ClassAST> classes;
non terminal Pair<ListAST<VarDeclAST>, ListAST<FuncDeclAST>> varsmethods, vars;
non terminal ListAST<FuncDeclAST> methods;
non terminal ListAST<VarDeclAST> params, paramlist, nonemptyparamlist, restparamlist;
non terminal BlockAST block;
non terminal Pair<ListAST<VarDeclAST>, ListAST<StmtAST>> blockvars;
non terminal ListAST<StmtAST> stmts, reststmts, whileblock;
non terminal AST atom;
non terminal AST exp, aexp, bexp, bop;
non terminal ListAST<AST> explist, nonemptyexplist, restexplist;
non terminal IntAST intconst;
non terminal BoolAST boolconst;
non terminal StringAST stringliteral;
// precedence
precedence left ASSIGN;
precedence left AND;
precedence left OR;
precedence left NOT;
precedence left LT, GT, LEQ, GEQ, EQ, NEQ;
precedence left PLUS, MINUS;
precedence left TIMES, DIV;
precedence left UMINUS;
precedence left LPAREN, RPAREN;
// program handling
program ::= mainclass:mc classes:cs {: RESULT = new ProgramAST(mc, cs); :};
// main class handling
mainclass ::= CLASS CLASSNAME:c LBLOCK mainfunction:f RBLOCK {: RESULT = new ClassAST(c, new ListAST<VarDeclAST>(), new ListAST(f)); :} ;
mainfunction ::= MAINFUNC params:ps block:b {: RESULT = new FuncDeclAST("Void", "main", ps, b); :};
// general class handling
classes ::= {: RESULT = new ListAST<ClassAST>(); :}
| CLASS CLASSNAME:c varsmethods:r classes:cs {: RESULT = new ListAST(new ClassAST(c, r.head, r.tail), cs); :}
;
varsmethods ::= LBLOCK vars:vs {: RESULT = vs; :}
;
vars ::= CLASSNAME:c IDNAME:i ENDSTMT vars:r {: RESULT = new Pair(new ListAST(new VarDeclAST(c, i), r.head), r.tail); :}
| methods:m {: RESULT = new Pair(new ListAST<VarDeclAST>(), m); :}
;
methods ::= RBLOCK {: RESULT = new ListAST<FuncDeclAST>(); :}
| CLASSNAME:c IDNAME:i params:ps block:b methods:m {: RESULT = new ListAST(new FuncDeclAST(c, i, ps, b), m); :}
;
params ::= LPAREN paramlist:ps RPAREN {: RESULT = ps; :}
;
paramlist ::= {: RESULT = new ListAST<VarDeclAST>(); :}
| nonemptyparamlist:ps {: RESULT = ps; :}
;
nonemptyparamlist ::= CLASSNAME:t IDNAME:x restparamlist:ps {: RESULT = new ListAST(new VarDeclAST(t, x), ps); :}
;
restparamlist ::= {: RESULT = new ListAST<VarDeclAST>(); :}
| COMMA nonemptyparamlist:ps {: RESULT = ps; :}
;
// method body handling
block ::= LBLOCK blockvars:bv RBLOCK {: RESULT = new BlockAST(bv.head, bv.tail); :};
blockvars ::= stmts:s {: RESULT = new Pair(new ListAST<VarDeclAST>(), s); :}
| CLASSNAME:c IDNAME:i ENDSTMT blockvars:r {: RESULT = new Pair(new ListAST(new VarDeclAST(c, i), r.head), r.tail); :}
;
stmts ::= RETURN ENDSTMT reststmts:ss {: RESULT = new ListAST(new ReturnStmtAST(), ss); :}
| RETURN exp:e ENDSTMT reststmts:ss {: RESULT = new ListAST(new ReturnStmtAST(e), ss); :}
| IDNAME:i ASSIGN exp:e ENDSTMT reststmts:ss {: RESULT = new ListAST(new AssignStmtAST(new RefAST(i), e), ss); :}
| atom:a DOT IDNAME:i ASSIGN exp:e ENDSTMT reststmts:ss {: RESULT = new ListAST(new AssignStmtAST(new MemberAccessAST(a, i), e), ss); :}
| atom:a LPAREN explist:es RPAREN ENDSTMT reststmts:ss {: RESULT = new ListAST(new FuncCallAST(a, es), ss); :}
| IF LPAREN exp:e RPAREN LBLOCK stmts:ssif RBLOCK ELSE LBLOCK stmts:sselse RBLOCK reststmts:ss {: RESULT = new ListAST(new IfStmtAST(e, ssif, sselse), ss); :}
| WHILE LPAREN exp:e RPAREN whileblock:blk reststmts:ss {: RESULT = new ListAST(new WhileStmtAST(e, blk), ss); :}
| READLN LPAREN IDNAME:i RPAREN ENDSTMT reststmts:ss {: RESULT = new ListAST(new ReadlnAST(new RefAST(i)), ss); :}
| PRINTLN LPAREN exp:e RPAREN ENDSTMT reststmts:ss {: RESULT = new ListAST(new PrintlnAST(e), ss); :}
;
reststmts ::= {: RESULT = new ListAST<StmtAST>(); :}
| stmts:ss {: RESULT = ss; :}
;
whileblock ::= LBLOCK RBLOCK {: RESULT = new ListAST<StmtAST>(); :}
| LBLOCK stmts:ss RBLOCK {: RESULT = ss; :}
;
exp ::= atom:a {: RESULT = a; :}
| stringliteral:s {: RESULT = s; :}
| intconst:n {: RESULT = n; :}
| boolconst:b {: RESULT = b; :}
| aexp:e {: RESULT = e; :}
| bexp:e {: RESULT = e; :}
| bop:e {: RESULT = e; :}
;
explist ::= {: RESULT = new ListAST<AST>(); :}
| nonemptyexplist:es {: RESULT = es; :}
;
nonemptyexplist ::= exp:e restexplist:es {: RESULT = new ListAST<AST>(e, es); :}
;
restexplist ::= {: RESULT = new ListAST<AST>(); :}
| COMMA nonemptyexplist:es {: RESULT = es; :}
;
aexp ::= MINUS exp:e {: RESULT = new UnOpAST("-", e); :} %prec UMINUS
| exp:a PLUS exp:b {: RESULT = new BinOpAST("+", a, b); :}
| exp:a MINUS exp:b {: RESULT = new BinOpAST("-", a, b); :}
| exp:a TIMES exp:b {: RESULT = new BinOpAST("*", a, b); :}
| exp:a DIV exp:b {: RESULT = new BinOpAST("/", a, b); :}
;
bexp ::= NOT exp:e {: RESULT = new UnOpAST("!", e); :}
| exp:a AND exp:b {: RESULT = new BinOpAST("&&", a, b); :}
| exp:a OR exp:b {: RESULT = new BinOpAST("||", a, b); :}
;
bop ::= exp:a LT exp:b {: RESULT = new BinOpAST("<", a, b); :}
| exp:a GT exp:b {: RESULT = new BinOpAST(">", a, b); :}
| exp:a LEQ exp:b {: RESULT = new BinOpAST("<=", a, b); :}
| exp:a GEQ exp:b {: RESULT = new BinOpAST(">=", a, b); :}
| exp:a EQ exp:b {: RESULT = new BinOpAST("==", a, b); :}
| exp:a NEQ exp:b {: RESULT = new BinOpAST("!=", a, b); :}
;
atom ::= NULL {: RESULT = new NullPtrAST(); :}
| THIS {: RESULT = new ThisPtrAST(); :}
| NEW CLASSNAME:c LPAREN RPAREN {: RESULT = new ConstructionAST(c); :}
| LPAREN exp:e RPAREN {: RESULT = e; :}
| IDNAME:i {: RESULT = new RefAST(i); :}
| atom:a LPAREN explist:es RPAREN {: RESULT = new FuncCallAST(a, es); :}
| atom:a DOT IDNAME:i {: RESULT = new MemberAccessAST(a, i); :}
;
intconst ::= INTCONST:n {: RESULT = new IntAST(n); :}
;
boolconst ::= BOOLCONST:b {: RESULT = new BoolAST(b); :}
;
stringliteral ::= STRING_LITERAL:s {: RESULT = new StringAST(s); :}
;