1. 程式人生 > >Antlr4實現簡單語言之整數比較表示式

Antlr4實現簡單語言之整數比較表示式

續上文Antlr4: 修改語法規則更接近普通BNF格式.

例程

為先=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 (最後運算子) { case5Parser.T加: return 運算子號.; case5Parser.T減: return 運算子號.; case5Parser.T乘: case5Parser.T數乘: return 運算子號.; case5Parser.T除: case5Parser.T數除: return 運算子號.; case5Parser.T相等: case5Parser.T為: return 運算子號.相等; default: return null; } }

下面是需要細究的部分, 由於變數名包括了"為"字, 因此如果把這個詞-"為"定義在"T變數名"之後, 詞法分析就會有問題.

T為: '為';

另外, 如果不新增空格忽略規則, 如果程式碼裡帶空格, 也會詞法分析錯誤. 加了此規則之後就支援"為先 為2":

T空格: [ ]+ ->skip;

在"執行器"的"求值"方法中, 新增"相等"支援:

case 相等: return 左結果 == 右結果;

大於(等於), 小於(等於), 不等支援也是類似實現. 原始碼版本號: program-in-chinese/quan5