-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.cpp
More file actions
191 lines (179 loc) · 5.92 KB
/
parser.cpp
File metadata and controls
191 lines (179 loc) · 5.92 KB
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
#include "parser.h"
#include "mainwindow.h"
int precedence(QString op)
{
if(op=="**") return 3;
if(op=="*"||op=="/") return 2;
if(op=="+"||op=="-") return 1;
if(op=="(") return 0;
return -1;
}
parser::parser(evalstate *state)
{
this->state = state;
}
statement* parser::parse(QString line)
{
QList<QString> tokens = myTokenizer.toTokens(line);
statement * newStatement = nullptr;
if (remStmt::isLegal(tokens)) {
newStatement = new remStmt(tokens, state);
}
else if (letStmt::isLegal(tokens)) {
newStatement = new letStmt(tokens, state);
}
else if (printStmt::isLegal(tokens)) {
newStatement = new printStmt(tokens, state);
}
else if (inputStmt::isLegal(tokens)) {
newStatement = new inputStmt(tokens, state);
}
else if (gotoStmt::isLegal(tokens)) {
newStatement = new gotoStmt(tokens, state);
}
else if (ifStmt::isLegal(tokens)) {
newStatement = new ifStmt(tokens, state);
}
else if (endStmt::isLegal(tokens)) {
newStatement = new endStmt(tokens, state);
}
else if(inputsStmt::isLegal(tokens)) {
newStatement = new inputsStmt(tokens, state);
}
else if(printfStmt::isLegal(tokens)) {
newStatement = new printfStmt(tokens, state);
}
// if(!newStatement) {
// QString error("Illegal Statement!");
// throw error;
// }
return newStatement;
}
Expression* parser::parseExp(QString expString)
{
QList<QString> expTokens = myTokenizer.toExpTokens(expString);
expTokens = preprocessForNeg(expTokens);
QStack<QString> operators;
QStack<Expression*> operands;
Expression *newExpression = nullptr, *lexp, *rexp;
int i=0;
while (i<expTokens.length()) {
if(expTokens[i]==")") {
while (true) {
if (operators.isEmpty()) { //没找到左括号,抛出错误
QString error("Illegal Expression! Missing \"(\".");
throw error;
}
if (operators.top()=="(") {
operators.pop();
break;
}
if (operands.length()<2) { //是operator,但栈里操作数不够2个了,抛出错误
QString error("Illegal Expression! Missing Operands.");
throw error;
}
QString op = operators.pop();
rexp = operands.pop();
lexp = operands.pop();
newExpression = new CompoundExp(op, lexp, rexp);
operands.push(newExpression);
}
++i;
continue;
}
if(precedence(expTokens[i])==-1) {
bool ok;
int value = expTokens[i].toInt(&ok);
if(ok) {
newExpression = new ConstantExp(value);
}
else {
newExpression = new IdentifierExp(expTokens[i]);
}
operands.push(newExpression);
++i;
continue;
}
while (true) {
if(precedence(expTokens[i])==3) {
operators.push(expTokens[i]);
++i;
break;
}
if(operators.isEmpty()||precedence(expTokens[i])==0) {
operators.push(expTokens[i]);
++i;
break;
}
if(precedence(operators.top())>=precedence(expTokens[i])) {
if (operands.length()<2) { //需要出栈但栈里操作数不够2个了,抛出错误
QString error("Illegal Expression! Missing Operands.");
throw error;
}
QString op = operators.pop();
rexp = operands.pop();
lexp = operands.pop();
newExpression = new CompoundExp(op, lexp, rexp);
operands.push(newExpression);
}
else {
operators.push(expTokens[i]);
++i;
break;
}
}
}
while (!operators.isEmpty()) {
if (operands.length()<2) { //需要出栈但栈里操作数不够2个了,抛出错误
QString error("Illegal Expression! Missing Operands.");
throw error;
}
QString op = operators.pop();
rexp = operands.pop();
lexp = operands.pop();
newExpression = new CompoundExp(op, lexp, rexp);
operands.push(newExpression);
}
if(operands.length()==1) {
return operands.top();
}
else {
QString error("Illegal Expression! Missing Operators.");
throw error;
}
}
QList<QString> parser::preprocessForNeg(QList<QString> tokens)
{
for (int i=0;i<tokens.size();++i) {
if(tokens[i]=="-") {
if(i==0||(precedence(tokens[i-1])!=-1)) {
tokens.insert(i, "0");
tokens.insert(i, "(");
i+=2;
for (int j=i+1, count1=0, count2=0;j<tokens.size();++j) {
if(tokens[j]=="(") {
count1++;
continue;
}
if(tokens[j]==")") {
count2++;
if(count1==count2) {
tokens.insert(j+1, ")");
break;
}
else continue;
}
if(isVar(tokens[j])&&count1==count2&&count1==0) {
tokens.insert(j+1, ")");
break;
}
}
}
}
}
return tokens;
}
bool parser::isVar(QString var)
{
return (precedence(var)==-1&&var!=")");
}