Antlr4實現簡單語言之整數比較表示式
阿新 • • 發佈:2019-01-10
例程
為先=1
為先 為2
=> 返回false
'為’作為關鍵詞, 與數字可以連寫, 但必須與變數名用空格間隔:
變數一=1
變數二=2
變數一×2為 變數二
實現
類似"求積表示式"語法規則模式, 新增如下:
表示式 : 等同判斷表示式; 等同判斷表示式 : 比較表示式 | 等同判斷表示式 '==' 比較表示式 | 等同判斷表示式 '為' 比較表示式 | 等同判斷表示式 '!=' 比較表示式 | 等同判斷表示式 '≠' 比較表示式 ; 比較表示式 : 求和表示式 | 比較表示式 '<' 求和表示式 | 比較表示式 '>' 求和表示式 | 比較表示式 '<=' 求和表示式 | 比較表示式 '>=' 求和表示式 | 比較表示式 '≤' 求和表示式 | 比較表示式 '≥' 求和表示式 ; 求和表示式 : 求積表示式 | 求和表示式 '+' 求積表示式 | 求和表示式 '-' 求積表示式 ;
"定製訪問器"中新增的部分如下, 由於語法規則模式相同, 構建樹演算法也相同:
@Override
public 節點 visit表示式(表示式Context 上下文) {
return visit(上下文.等同判斷表示式());
}
@Override
public 節點 visit等同判斷表示式(等同判斷表示式Context 上下文) {
return 以本身向右擴充套件為運算節點(上下文, 上下文.等同判斷表示式(), 上下文.比較表示式());
}
@Override
public 節點 visit比較表示式(比較表示式Context 上下文) {
return 以本身向右擴充套件為運算節點(上下文, 上下文.比較表示式(), 上下文.求和表示式());
}
@Override
public 節點 visit求和表示式(求和表示式Context 上下文) {
return 以本身向右擴充套件為運算節點(上下文, 上下文.求和表示式(), 上下文.求積表示式());
}
@Override
public 節點 visit求積表示式(求積表示式Context 上下文) {
return 以本身向右擴充套件為運算節點(上下文, 上下文.求積表示式(), 上下文.最小表示式());
}
...
private 節點 以本身向右擴充套件為運算節點(ParserRuleContext 上下文, ParserRuleContext 本身子節點, ParserRuleContext 擴充套件子節點) {
節點 比較節點 = visit(擴充套件子節點);
if (本身子節點 == null) {
return 比較節點;
} else {
return 構建運算節點(取運算子(上下文), 本身子節點, 比較節點);
}
}
// 第二個子節點為運算子
private 運算子號 取運算子(ParserRuleContext 原始表示式) {
int 最後運算子 = ((TerminalNodeImpl) 原始表示式.getChild(1)).symbol.getType();
switch (最後運算子) {
case 圈5Parser.T加:
return 運算子號.加;
case 圈5Parser.T減:
return 運算子號.減;
case 圈5Parser.T乘:
case 圈5Parser.T數乘:
return 運算子號.乘;
case 圈5Parser.T除:
case 圈5Parser.T數除:
return 運算子號.除;
case 圈5Parser.T相等:
case 圈5Parser.T為:
return 運算子號.相等;
default:
return null;
}
}
下面是需要細究的部分, 由於變數名包括了"為"字, 因此如果把這個詞-"為"定義在"T變數名"之後, 詞法分析就會有問題.
T為: '為';
另外, 如果不新增空格忽略規則, 如果程式碼裡帶空格, 也會詞法分析錯誤. 加了此規則之後就支援"為先 為2":
T空格: [ ]+ ->skip;
在"執行器"的"求值"方法中, 新增"相等"支援:
case 相等: return 左結果 == 右結果;
大於(等於), 小於(等於), 不等支援也是類似實現. 原始碼版本號: program-in-chinese/quan5