forked from paceuniversity/cs361-paceuniversity-classroom-21e866-kay-parser-2024-Kay-Parser-Starter-Code-2023-1
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathConcreteSyntax.java
175 lines (156 loc) · 5.48 KB
/
ConcreteSyntax.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
// ConcreteSyntax.java
// Implementation of the Recursive Descent Parser algorithm
// Each method corresponds to a concrete syntax grammar rule,
// which appears as a comment at the beginning of the method.
// This code DOES NOT implement a parser for KAY. You have to complete
// the code and also make sure it implements a parser for KAY - not something
// else.
public class ConcreteSyntax {
public Token token; // current token being analyzed
public TokenStream input; // stream of tokens from lexical analysis
public ConcreteSyntax(TokenStream ts) {
input = ts;
token = input.nextToken();
}
private String SyntaxError(String expected) {
return "Syntax error - Expecting: " + expected + " But saw: " + token.getType() + ": " + token.getValue();
}
private void match(String expected) {
if (token.getValue().equals(expected)) {
token = input.nextToken();
} else {
throw new RuntimeException(SyntaxError(expected));
}
}
public Program program() {
// Program --> main '{' Declarations Statements '}'
Program p = new Program();
match("main");
match("{");
p.decpart = declarations(); // Parse declarations
p.body = statements(); // Parse statements block
match("}");
return p;
}
private Declarations declarations() {
Declarations ds = new Declarations();
while (token.getValue().equals("integer") || token.getValue().equals("bool")) {
declaration(ds);
}
return ds;
}
private void declaration(Declarations ds) {
Type t = type();
identifiers(ds, t);
match(";");
}
private Type type() {
Type t = null;
if (token.getValue().equals("integer")) {
t = new Type("integer");
} else if (token.getValue().equals("bool")) {
t = new Type("bool");
} else {
throw new RuntimeException(SyntaxError("integer | bool"));
}
token = input.nextToken();
return t;
}
private void identifiers(Declarations ds, Type t) {
Declaration d = new Declaration();
d.t = t;
if (token.getType().equals("Identifier")) {
d.v = new Variable();
d.v.id = token.getValue();
ds.addElement(d);
token = input.nextToken();
while (token.getValue().equals(",")) {
token = input.nextToken();
if (token.getType().equals("Identifier")) {
d = new Declaration();
d.t = t;
d.v = new Variable();
d.v.id = token.getValue();
ds.addElement(d);
token = input.nextToken();
} else {
throw new RuntimeException(SyntaxError("Identifier"));
}
}
} else {
throw new RuntimeException(SyntaxError("Identifier"));
}
}
private Block statements() {
Block b = new Block();
while (!token.getValue().equals("}")) {
b.blockmembers.addElement(statement());
}
return b;
}
private Statement statement() {
if (token.getValue().equals(";")) {
token = input.nextToken();
return new Skip();
} else if (token.getValue().equals("{")) {
token = input.nextToken();
Block b = statements();
match("}");
return b;
} else if (token.getType().equals("Identifier")) {
return assignment();
} else {
throw new RuntimeException(SyntaxError("Statement"));
}
}
private Assignment assignment() {
Assignment a = new Assignment();
if (token.getType().equals("Identifier")) {
a.target = new Variable();
a.target.id = token.getValue();
token = input.nextToken();
match(":=");
a.source = expression();
match(";");
} else {
throw new RuntimeException(SyntaxError("Identifier"));
}
return a;
}
private Expression expression() {
return factor();
}
private Expression factor() {
Expression e = null;
if (token.getType().equals("Identifier")) {
Variable v = new Variable();
v.id = token.getValue();
e = v;
token = input.nextToken();
} else if (token.getType().equals("Literal")) {
Value v = null;
if (isInteger(token.getValue())) {
v = new Value(Integer.parseInt(token.getValue()));
} else if (token.getValue().equals("True")) {
v = new Value(true);
} else if (token.getValue().equals("False")) {
v = new Value(false);
} else {
throw new RuntimeException(SyntaxError("Literal"));
}
e = v;
token = input.nextToken();
} else {
throw new RuntimeException(SyntaxError("Identifier | Literal"));
}
return e;
}
private boolean isInteger(String s) {
try {
Integer.parseInt(s);
return true;
} catch (NumberFormatException e) {
return false;
}
}
}