-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParser.java
104 lines (96 loc) · 3.32 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
/**
* En rekursiv medåknings-parser för aritmetiska uttryck.
* Se README för mer info.
*
* Författare: Per Austrin
*/
public class Parser {
private Lexer lexer;
/** Variabler för att kunna ge pratig förklaring av vad som händer
* i parsningen. Om man inte har behov av denna feature kan koden
* som relaterar till dessa variabler tas bort.
*/
private boolean verbose;
private int depth;
/** Om verbose är satt till sann kommer Parsern att prata en massa
* medans den gör sitt jobb.
*/
public Parser(Lexer lexer, boolean verbose) {
this.lexer = lexer;
this.verbose = verbose;
}
private void talk(String s) {
if (verbose)
System.out.printf("%"+(3*depth+1)+"s%s\n", "", s);
}
public ParseTree parse() throws SyntaxError {
// Startsymbol är Expr
depth = 0;
talk("Start parse()");
++depth;
ParseTree result = Expr();
// Borde inte finnas något kvar av indata när vi parsat ett uttryck
if (lexer.nextToken().getType() != TokenType.EOF) {
throw new SyntaxError();
}
return result;
}
private ParseTree Expr() throws SyntaxError {
talk("Enter Expr()");
++depth;
ParseTree result = Term();
talk("[Expr()] Read term done");
while (lexer.peekToken().getType() == TokenType.PLUS ||
lexer.peekToken().getType() == TokenType.MINUS) {
Token operator = lexer.nextToken();
talk("[Expr()] Read operator " + operator);
ParseTree next = Term();
talk("[Expr()] Read term done");
result = new BinaryOperation(operator.getType(), result, next);
}
--depth;
talk("Leave Expr()");
return result;
}
private ParseTree Term() throws SyntaxError {
talk("Enter Term()");
++depth;
ParseTree result = Factor();
talk("[Term()] Read factor done");
while (lexer.peekToken().getType() == TokenType.TIMES ||
lexer.peekToken().getType() == TokenType.DIVIDE) {
Token operator = lexer.nextToken();
talk("[Term()] Read operator " + operator);
ParseTree next = Factor();
talk("[Term()] Read factor done");
result = new BinaryOperation(operator.getType(), result, next);
}
--depth;
talk("Leave Term()");
return result;
}
private ParseTree Factor() throws SyntaxError {
talk("Enter Factor()");
++depth;
Token t = lexer.nextToken();
talk("[Factor()] Got token " + t);
if (t.getType() == TokenType.NUM) {
talk("[Factor()] Use rule Factor -> Num");
--depth;
talk("Leave Factor()");
return new NumberNode((Integer)t.getData());
} else if (t.getType() == TokenType.LPAREN) {
talk("[Factor()] Use rule Factor -> (Expr)");
ParseTree result = Expr();
talk("[Factor()] Read expr done");
t = lexer.nextToken();
talk("[Factor()] Got token " + t);
if (t.getType() != TokenType.RPAREN)
throw new SyntaxError();
--depth;
talk("Leave Factor()");
return result;
}
throw new SyntaxError();
}
}