-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParser.java
209 lines (193 loc) · 6.57 KB
/
Parser.java
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
package com.randommurican.Parsemer;
/**
* I apologize for this mess that is mostly hard coded. It hurt to type,
* but I spent way to much time studying for physics and it hurt me
* time-wise for this project. At least, I passed the physics test!
*
* I'm sad to say I didn't implement error catching or an AST. I was
* really looking forward to that :/
*
* @author ej Byrne
*
*/
public class Parser {
private Language lang = new Language();
private boolean result;
private int currentLexeme;
Parser(Language lang) {
this.lang = lang;
result = true;
currentLexeme = 0;
while(result && currentLexeme < lang.getLexemeCount()) {
result = isExpression();
next();
}
}
public boolean isExpression() { /******* Expression *******/
switch(lang.kind()) { // No terminals. Is the lexeme part of first(Expression)?
case "not":
case "true":
case "false":
case "NUM":
case "ID":
case "openParentheses":
return isBooleanExpression(); // If yes, then pass it on for further testing
default:
return false; // If not then it can't be anything else
}
}
public boolean isBooleanExpression() { /******* BooleanExpression *******/
boolean result = false;
switch(lang.kind()) { // No terminals. Is the lexeme part of first(BooleanExpression)?
case "not":
case "true":
case "false":
case "NUM":
case "ID":
case "openParentheses":
result = isBooleanTerm(); // If yes, then pass it on for further testing
break;
default:
return false; // If not then kill the process, it can't be anything else
}
while( lang.kind().equals("or") && // While we have an "or" chain going
result == true) { // and the checks are passing
next();
result = isBooleanTerm(); // Check that a BoolTerm follows
}
return result;
}
public boolean isBooleanTerm() { /******* BooleanTerm *******/
boolean result = false;
switch(lang.kind()) { // No terminals. Is the lexeme part of first(BooleanTerm)?
case "not":
case "true":
case "false":
case "NUM":
case "ID":
case "openParentheses":
result = isBooleanFactor(); // If yes, then pass it on for further testing
break;
default:
return false; // If not then it can't be anything else
}
while( lang.kind().equals("and") && // While we have an "and" chain going
result == true) { // and the checks are passing
next();
result = isBooleanFactor(); // Check that a BoolFactor follows
}
return result;
}
public boolean isBooleanFactor() { /******* BooleanFactor *******/
boolean result = false;
switch(lang.kind()) {
case "not": // Not is our only terminal and can simply be ignored
next();
case "true": // Is the next lexeme part of first(BooleanFactor) excluding not?
case "false":
case "NUM":
case "ID":
case "openParentheses":
result = isArithmeticExpression(); // If yes, then pass it on for further testing
break;
default:
return false; // If not then it can't be anything else
}
while(( lang.kind().equals("equal") || // While we have an "equal" chain
lang.kind().equals("lessThan")) && // or a "lessThan" chain going
result == true) { // and the checks are passing
next();
result = isArithmeticExpression(); // Check that a ArithmeticExpr follows
}
return result;
}
public boolean isArithmeticExpression() { /******* ArithmeticExpression *******/
switch(lang.kind()) { // No terminals. Is the lexeme part of first(ArithmeticExpression)?
case "true":
case "false":
case "NUM":
case "ID":
case "openParentheses":
result = isTerm(); // If yes, then pass it on for further testing
break;
default:
return false; // If not then it can't be anything else
}
while(( lang.kind().equals("plus") || // While we have an "plus" chain
lang.kind().equals("minus")) && // or a "minus" chain going
result == true) { // and the checks are passing
next();
result = isTerm(); // Check that a Term follows
}
return result;
}
public boolean isTerm() { /******* Term *******/
switch(lang.kind()) { // No terminals. Is the lexeme
case "true": // part of first(Term)?
case "false":
case "NUM":
case "ID":
case "openParentheses":
result = isFactor(); // If yes, then pass it on for further testing
break;
default:
return false; // If not then it can't be anything else
}
while(( lang.kind().equals("multiply") || // While we have an "multiply" chain
lang.kind().equals("divide")) && // or a "divide" chain going
result == true) { // and the checks are passing
next();
result = isFactor(); // Check that a Factor follows
}
return result;
}
public boolean isFactor() { /******* Factor *******/
switch(lang.kind()) {
case "ID": // Is the lexeme the ID terminal?
next(); // then move onto the next lexeme
return true; // and return true
case "openParentheses": // If the lexeme is "("
next(); // Check the next lexeme
result = isExpression(); // to see if it's an Expression
break;
case "true": // Otherwise see if the lexeme is part of first(Factor)
case "false":
case "NUM":
result = isLiteral(); // If yes, then pass it on for further testing
break;
default:
return false; // If not then it can't be anything else
}
if(lang.kind().equals("closeParentheses")) // Just picking up the straggling parentheses
next();
return result;
}
public boolean isLiteral() { /******* Literal *******/
switch(lang.kind()) {
case "NUM": // Is the lexeme the NUM terminal
next(); // then move on
return true; // and return true
case "true": // otherwise is the lexeme part of first(Literal)?
case "false":
return isBooleanLiteral(); // If so, check if its a BooleanLiteral even though it definitely is...
default:
return false; // Otherwise it can't be anything else
}
}
public boolean isBooleanLiteral() { /******* BooleanLiteral *******/
switch(lang.kind()) {
case "true": // Is the lexeme a terminal?
case "false":
next(); // then move on
return true; // and return true
default:
return false; // this shouldn't ever run...
}
}
public boolean getResult() {return result;} // Just because...
// I didn't feel like writing this out 100 times in my code
private void next() {
currentLexeme++;
lang.next();
}
}