Antlr4实现简单语言之整数比较表达式

简介: 为"圈2"语言, 添加整数比较功能. Add integer comparison to pretotype programming language quan2.

续上文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

2018-01-17

相关文章
|
2月前
|
存储 算法 程序员
【c 语言 】位操作符详解
【c 语言 】位操作符详解
57 0
N..
|
2月前
|
Dart
Dart语言中的条件表达式和运算符
Dart语言中的条件表达式和运算符
N..
8 0
|
2月前
|
存储 C语言
C 语言——表达式
C 语言——表达式
11 0
|
5月前
|
C语言
C 语言运算符详解
运算符用于对变量和值进行操作。 在下面的示例中,我们使用 + 运算符将两个值相加:
144 0
|
6月前
|
自然语言处理 Java
Antlr实现任意四则运算表达式求值
上面语法就是四则运算的巴科斯范式定义(EBNF),可能对初学者有点难理解,其实就是一个递归定义,一个表达式可能是有多个子表达式构成,但子表达式的尽头一定是数字。 antlr可以用EBNF所定义的规则,将某个输入串解析为一颗抽象语法树(AST)。我们以表达式((3+3)*(1+4))/(5-3) 为例
66 0
|
10月前
|
存储 数据处理 C语言
C语言实验二 数据类型、运算符和表达式
C语言实验二 数据类型、运算符和表达式
116 0
|
算法
表达式转换-中缀转后缀表达式后计算-数据结构与算法
表达式转换-中缀转后缀表达式后计算-数据结构与算法
336 0
表达式转换-中缀转后缀表达式后计算-数据结构与算法
|
SQL 算法 Java
【Go语言刷题篇】Go从0到入门2:类型转换、字符求和、运算符运算(加减乘除取余比较符)练习
本系列文章采用牛客的核心代码模式进行案例代码提供,帮助大家从0到入门的学习过程中进行配套的刷题~
【Go语言刷题篇】Go从0到入门2:类型转换、字符求和、运算符运算(加减乘除取余比较符)练习