建構支援完整運算子優先級、括號巢狀、負號處理的表達式求值引擎。採編譯器前端經典三階段:詞法分析 → 語法分析 (遞迴下降) → 執行階段 (雙堆疊求值)。
+ - * / ( )、一元正負號#-25*(56+15)#輸入字元集:{0-9, ., +, -, *, /, (, ), #}
輸出 Token 序列:
輸入: -25*(56+15)#
Token: [-25, *, (, 56, +, 15, ), #]
類型: [NUM, OP, LP, NUM, OP, NUM, RP, END]
E → N E' | (E) E'
E' → + E E' | - E E' | * E E' | / E E' | ε
double ParseE() { // 解析 E
double val = ParsePrimary();
return ParseEPrime(val);
}
double ParsePrimary() { // N 或 (E)
if (CurrentToken == NUM) return ConsumeNumber();
if (CurrentToken == LP) {
Consume(LP);
double val = ParseE();
Expect(RP);
return val;
}
Error("語法錯誤");
}
double ParseEPrime(double left) { // E'
while (true) {
if (CurrentToken == ADD) { Consume(ADD); left += ParsePrimary(); }
else if (CurrentToken == SUB) { Consume(SUB); left -= ParsePrimary(); }
else if (CurrentToken == MUL) { Consume(MUL); left *= ParsePrimary(); }
else if (CurrentToken == DIV) { Consume(DIV); left /= ParsePrimary(); }
else break;
}
return left;
}
完整程式碼包含錯誤處理、Token 串流管理、一元運算子處理。
語法分析同時產生後序表示 (RPN) 或直接雙堆疊計算:
while (tokens remain) {
if (token is number) operandStack.push(token.value);
else if (token is operator) {
while (!opStack.empty() &&
precedence(opStack.top()) >= precedence(token)) {
ApplyOperator(operandStack, opStack.pop());
}
opStack.push(token);
}
else if (token == '(') opStack.push(token);
else if (token == ')') {
while (opStack.top() != '(') ApplyOperator(...);
opStack.pop(); // 彈出 '('
}
}
while (!opStack.empty()) ApplyOperator(...);
return operandStack.top();
( 後、運算子後) → 產生負數 Token^ 只需擴充文法與優先級表| 表達式 | 結果 |
|---|---|
| -25*(56+15)# | -1775 |
| 3+4*2/(1-5)# | 1 |
| 2^3^2# (右結合) | 512 |
完整專案含詞法分析器、遞迴下降解析器、堆疊計算器、測試主程式。