-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathParser.java
112 lines (90 loc) · 2.25 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
package net.zerobone.knife.parser;
import java.lang.Object;
import java.util.Stack;
public final class Parser {
public static final int T_EOF = 0;
public static final int T_CODE = 4;
public static final int T_SEMICOLON = 3;
public static final int T_RIGHT_PAREN = 6;
public static final int T_ID = 1;
public static final int T_ASSIGN = 2;
public static final int T_LEFT_PAREN = 5;
public static final int T_TYPE = 7;
private static final int terminalCount = 8;
private static final int nonTerminalCount = 5;
private static final int startSymbol = -1;
private static final int[] table = {
1,2,0,0,0,0,0,2,
0,3,0,0,0,0,0,4,
0,6,0,5,0,0,0,0,
7,7,0,0,8,0,0,7,
0,9,0,9,0,10,0,0};
private static final int[][] actionTable = {
{},
{-2,-1},
{1,2,-3},
{7,1,1},
{3,-4},
{1,-5,-3},
{},
{4},
{},
{5,1,6}};
private Stack<ParseNode> stack;
private boolean success = false;
private ParseNode parseTree;
public Parser() {
reset();
}
public void parse(int tokenId, Object token) {
while (true) {
ParseNode prevRoot = stack.peek();
while (prevRoot.actionId != 0) {
prevRoot.reduce();
stack.pop();
if (stack.isEmpty()) {
if (tokenId != T_EOF) {
throw new RuntimeException("Expected end of input. Got: " + tokenId);
}
success = true;
return;
}
prevRoot = stack.peek();
}
if (prevRoot.symbolId > 0) {
if (tokenId != prevRoot.symbolId) {
throw new RuntimeException("Expected: " + prevRoot.symbolId + " Got: " + tokenId);
}
prevRoot.payload = token;
stack.pop();
return;
}
int actionId = table[(-prevRoot.symbolId - 1) * terminalCount + tokenId];
if (actionId == 0) {
throw new RuntimeException("Syntax error. Token: " + token);
}
int[] action = actionTable[actionId - 1];
prevRoot.actionId = actionId;
for (int i = action.length - 1; i >= 0; i--) {
ParseNode child = new ParseNode(action[i]);
prevRoot.children.add(child);
stack.push(child);
}
}
}
public void reset() {
success = false;
parseTree = new ParseNode(startSymbol);
stack = new Stack<>();
stack.push(parseTree);
}
public Object getValue() {
if (!success) {
return null;
}
return parseTree.payload;
}
public boolean successfullyParsed() {
return success;
}
}