zoukankan      html  css  js  c++  java
  • 2018-01-17 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 (最后运算符) {
          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

  • 相关阅读:
    如何使用php实现首页和子页面之间的交互
    用php实现,打开哪个页面哪个页面就有默认的样式
    后台链接前台有关显示不显示
    上传文件的最大值,post传值的最大值得修改
    linux 操作系统的安装,本地登录及远程登录,vnc连接操作详细步骤
    滑动组件
    Numpy简介
    java对象序列化
    集合类操作需要注意的地方
    TreeMap详解
  • 原文地址:https://www.cnblogs.com/program-in-chinese/p/10487790.html
Copyright © 2011-2022 走看看