Skip to content

Commit 2372892

Browse files
committed
Switch Parser
1 parent b1cdf72 commit 2372892

File tree

6 files changed

+301
-1
lines changed

6 files changed

+301
-1
lines changed

src/main/java/com/compiler/StmtParser.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public ASTStmtListNode parseStmtlist() throws Exception {
4242
Token curToken = m_lexer.lookAhead();
4343
final List<ASTStmtNode> stmtList = new ArrayList<>();
4444

45-
while (curToken.m_type != com.compiler.TokenIntf.Type.RBRACE) {
45+
while (curToken.m_type != com.compiler.TokenIntf.Type.RBRACE && curToken.m_type != Type.CASE) { // RBrace and Case in Follow set of Statementlist
4646
stmtList.add(parseStmt());
4747
curToken = m_lexer.lookAhead();
4848
}
@@ -81,6 +81,10 @@ public ASTStmtNode parseStmt() throws Exception {
8181
return parseNumericIfStmt();
8282
}
8383

84+
if (type == Type.SWITCH) {
85+
return parseSwitchStmt();
86+
}
87+
8488
m_lexer.throwCompilerException("Invalid begin of statement", "DECLARE or IDENTIFIER or PRINT or NUMERIC_IF");
8589
return null; // unreachable
8690
}
@@ -230,4 +234,39 @@ ASTStmtNode parseExecuteNTimesStmt() throws Exception {
230234

231235
return new ASTExecuteNTimesNode(count, stmtlistNode);
232236
}
237+
238+
private ASTStmtNode parseSwitchStmt() throws Exception {
239+
// switch_statement -> SWITCH LPAREN expression RPAREN LBRACE case_list RBRACE
240+
m_lexer.expect(Type.SWITCH);
241+
m_lexer.expect(Type.LPAREN);
242+
ASTExprNode expression = m_exprParser.getQuestionMarkExpr();
243+
m_lexer.expect(Type.RPAREN);
244+
m_lexer.expect(Type.LBRACE);
245+
ASTCaseListNode caseList = parseCaseList();
246+
m_lexer.expect(Type.RBRACE);
247+
return new ASTSwitchStmtNode(expression, caseList);
248+
}
249+
250+
private ASTCaseListNode parseCaseList() throws Exception {
251+
// case_list -> case_item case_list | epsilon
252+
Token curToken = m_lexer.lookAhead();
253+
final List<ASTCaseNode> caseList = new ArrayList<>();
254+
255+
while (curToken.m_type == Type.CASE) {
256+
caseList.add(parseCaseStmt());
257+
curToken = m_lexer.lookAhead();
258+
}
259+
return new ASTCaseListNode(caseList);
260+
}
261+
262+
private ASTCaseNode parseCaseStmt() throws Exception {
263+
// case_item -> CASE LITERAL COLON statement_list
264+
m_lexer.expect(Type.CASE);
265+
Token curToken = m_lexer.lookAhead();
266+
m_lexer.expect(Type.INTEGER);
267+
ASTIntegerLiteralNode value = new ASTIntegerLiteralNode(curToken.m_value); //Integer
268+
m_lexer.expect(Type.DOUBLECOLON); // should be renamed to COLON as double colon is "::"
269+
ASTStmtListNode stmtList = parseStmtlist();
270+
return new ASTCaseNode(value, stmtList);
271+
}
233272
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.compiler.ast;
2+
3+
import com.compiler.CompileEnvIntf;
4+
5+
import java.io.OutputStreamWriter;
6+
import java.util.List;
7+
8+
public class ASTCaseListNode extends ASTStmtNode {
9+
10+
List<ASTCaseNode> m_caseList;
11+
public ASTCaseListNode(List<ASTCaseNode> caseList) {
12+
m_caseList = caseList;
13+
}
14+
15+
@Override
16+
public void execute(OutputStreamWriter out) {
17+
m_caseList.forEach(caseItem->caseItem.execute(out));
18+
}
19+
20+
@Override
21+
public void codegen(CompileEnvIntf env) {
22+
m_caseList.forEach(caseItem->caseItem.codegen(env));
23+
}
24+
25+
@Override
26+
public void print(OutputStreamWriter outStream, String indent) throws Exception {
27+
outStream.write(indent);
28+
outStream.write("ASTCaseListNode\n");
29+
m_caseList.forEach(caseItem -> {
30+
try {
31+
caseItem.print(outStream, indent + " ");
32+
outStream.write("\n");
33+
} catch (final Exception e) {
34+
throw new RuntimeException(e);
35+
}
36+
});
37+
}
38+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.compiler.ast;
2+
3+
import java.io.OutputStreamWriter;
4+
5+
public class ASTCaseNode extends ASTStmtNode {
6+
7+
ASTIntegerLiteralNode m_value;
8+
ASTStmtListNode m_stmtList;
9+
10+
int expressionValue; // Value gets written on Execution of Switch Block
11+
12+
public ASTCaseNode(ASTIntegerLiteralNode value, ASTStmtListNode stmtList) {
13+
m_stmtList = stmtList;
14+
m_value = value;
15+
16+
}
17+
18+
@Override
19+
public void execute(OutputStreamWriter out) {
20+
if(m_value.eval()==expressionValue) m_stmtList.execute(out);
21+
}
22+
23+
@Override
24+
public void print(OutputStreamWriter outStream, String indent) throws Exception {
25+
outStream.write(indent);
26+
outStream.write("ASTCaseNode\n");
27+
m_stmtList.print(outStream, indent + " ");
28+
}
29+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.compiler.ast;
2+
3+
import java.io.OutputStreamWriter;
4+
5+
public class ASTSwitchStmtNode extends ASTStmtNode {
6+
7+
ASTExprNode m_expression;
8+
ASTCaseListNode m_caseList;
9+
10+
int evaluatedExpression;
11+
12+
public ASTSwitchStmtNode(ASTExprNode expression, ASTCaseListNode caseList) {
13+
m_expression = expression;
14+
m_caseList = caseList;
15+
}
16+
17+
@Override
18+
public void execute(OutputStreamWriter out) {
19+
evaluatedExpression = m_expression.eval();
20+
m_caseList.m_caseList.forEach(caseItem-> caseItem.expressionValue = evaluatedExpression);
21+
m_caseList.execute(out);
22+
}
23+
24+
@Override
25+
public void print(OutputStreamWriter outStream, String indent) throws Exception {
26+
outStream.write(indent);
27+
outStream.write("ASTSwitchStmtNode\n");
28+
m_expression.print(outStream, indent + " ");
29+
m_caseList.print(outStream, indent + " ");
30+
}
31+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package com.compiler;
2+
3+
import org.junit.Test;
4+
5+
public class InterpreterSwitchStmtTest extends InterpreterTestBase{
6+
@Test
7+
public void testSwitchProgram01() throws Exception {
8+
String program = """
9+
{
10+
DECLARE in;
11+
DECLARE out;
12+
in = 2;
13+
out = 0;
14+
SWITCH(in) {
15+
CASE 1:
16+
out = 2;
17+
CASE 2:
18+
out = 3;
19+
}
20+
PRINT out;
21+
}
22+
""";
23+
testInterpreter(program, "3\n");
24+
}
25+
26+
27+
@Test
28+
public void testSwitchProgram02() throws Exception {
29+
String program = """
30+
{
31+
DECLARE in;
32+
DECLARE out;
33+
in = 3;
34+
out = 0;
35+
SWITCH(in) {
36+
CASE 1:
37+
out = 2;
38+
CASE 2:
39+
out = 3;
40+
CASE 4:
41+
out = 3;
42+
CASE 3:
43+
out = 5;
44+
CASE 5:
45+
out = 2;
46+
}
47+
PRINT out;
48+
}
49+
""";
50+
testInterpreter(program, "5\n");
51+
}
52+
53+
54+
@Test
55+
public void testSwitchProgram03() throws Exception {
56+
String program = """
57+
{
58+
DECLARE in;
59+
DECLARE out;
60+
in = 3;
61+
out = 0;
62+
SWITCH(in + 1) {
63+
CASE 1:
64+
out = 2;
65+
CASE 2:
66+
out = 3;
67+
CASE 4:
68+
out = 3;
69+
in = 4;
70+
CASE 3:
71+
out = 5;
72+
CASE 5:
73+
out = 2;
74+
}
75+
PRINT in;
76+
PRINT out;
77+
}
78+
""";
79+
testInterpreter(program, "5\n");
80+
}
81+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.compiler;
2+
3+
import org.junit.Test;
4+
5+
public class StmtSwitchStmtParserTest extends StmtParserTestBase{
6+
7+
@Test
8+
public void testSwitchProgram01() throws Exception {
9+
String program = """
10+
{
11+
DECLARE in;
12+
DECLARE out;
13+
in = 2;
14+
out = 0;
15+
SWITCH(in) {
16+
CASE 1:
17+
out = 2;
18+
CASE 2:
19+
out = 3;
20+
}
21+
PRINT out;
22+
}
23+
""";
24+
testParser(program, "3\n");
25+
}
26+
27+
28+
@Test
29+
public void testSwitchProgram02() throws Exception {
30+
String program = """
31+
{
32+
DECLARE in;
33+
DECLARE out;
34+
in = 3;
35+
out = 0;
36+
SWITCH(in) {
37+
CASE 1:
38+
out = 2;
39+
CASE 2:
40+
out = 3;
41+
CASE 4:
42+
out = 3;
43+
CASE 3:
44+
out = 5;
45+
CASE 5:
46+
out = 2;
47+
}
48+
PRINT out;
49+
}
50+
""";
51+
testParser(program, "5\n");
52+
}
53+
54+
55+
@Test
56+
public void testSwitchProgram03() throws Exception {
57+
String program = """
58+
{
59+
DECLARE in;
60+
DECLARE out;
61+
in = 3;
62+
out = 0;
63+
SWITCH(in + 1) {
64+
CASE 1:
65+
out = 2;
66+
CASE 2:
67+
out = 3;
68+
CASE 4:
69+
out = 3;
70+
in = 4;
71+
CASE 3:
72+
out = 5;
73+
CASE 5:
74+
out = 2;
75+
}
76+
PRINT in;
77+
PRINT out;
78+
}
79+
""";
80+
testParser(program, "5\n");
81+
}
82+
}

0 commit comments

Comments
 (0)