首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Antlr4中的Antr3规则重写

ANTLR(Another Tool for Language Recognition)是一种强大的工具,用于生成解析器和词法分析器。ANTLR4与ANTLR3在语法规则的定义和处理上有一些显著的变化。如果你有一个ANTLR3的语法规则,并希望将其迁移到ANTLR4,需要注意以下几点:

主要变化

  1. 语法文件头部声明
    • ANTLR3使用grammar关键字,而ANTLR4也使用grammar关键字,但有一些额外的选项和注释方式。
  2. 词法和语法规则的分离
    • 在ANTLR3中,词法规则和语法规则可以混合在一起。
    • 在ANTLR4中,词法规则(大写字母开头)和语法规则(小写字母开头)仍然可以混合,但推荐分开定义。
  3. 返回值和参数
    • ANTLR3使用returnsparameters来定义规则的返回值和参数。
    • ANTLR4使用->操作符来定义返回值,并且参数可以直接在规则中定义。
  4. 树结构
    • ANTLR3使用^!来构建抽象语法树(AST)。
    • ANTLR4不再使用这些符号,而是使用显式的树构建器和访问器。

示例

假设你有一个ANTLR3的语法文件Example.g,其中包含以下规则:

代码语言:javascript
复制
grammar Example;

options {
  output=AST;
}

tokens {
  PLUS = '+' ;
  MINUS = '-' ;
}

expr
  : term ( (PLUS^ | MINUS^) term )*
  ;

term
  : INT
  ;

INT
  : '0'..'9'+
  ;

重写为ANTLR4

以下是将上述ANTLR3语法重写为ANTLR4的示例:

代码语言:javascript
复制
grammar Example;

expr
  : term ( (PLUS | MINUS) term )*
  ;

term
  : INT
  ;

PLUS: '+';
MINUS: '-';
INT: [0-9]+;
WS: [ \t\r\n]+ -> skip;

详细解释

  1. 语法文件头部声明
    • 语法文件头部声明保持不变,但不再需要options块来指定output=AST,因为ANTLR4默认生成解析树。
  2. 词法和语法规则的分离
    • 词法规则(PLUS, MINUS, INT, WS)和语法规则(expr, term)仍然可以混合在一起,但推荐分开定义。
  3. 返回值和参数
    • 在ANTLR4中,不再需要显式地使用returnsparameters,可以直接在规则中定义。
  4. 树结构
    • ANTLR4不再使用^!来构建AST。相反,ANTLR4生成解析树,你可以使用访问器或监听器来遍历和处理解析树。

访问器和监听器

在ANTLR4中,你可以使用访问器(Visitor)或监听器(Listener)来处理解析树。以下是一个简单的访问器示例:

代码语言:javascript
复制
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;

public class ExampleVisitor extends ExampleBaseVisitor<Integer> {
    @Override
    public Integer visitExpr(ExampleParser.ExprContext ctx) {
        int left = visit(ctx.term(0));
        for (int i = 1; i < ctx.term().size(); i++) {
            if (ctx.getChild(2 * i - 1).getText().equals("+")) {
                left += visit(ctx.term(i));
            } else {
                left -= visit(ctx.term(i));
            }
        }
        return left;
    }

    @Override
    public Integer visitTerm(ExampleParser.TermContext ctx) {
        return Integer.parseInt(ctx.INT().getText());
    }

    public static void main(String[] args) throws Exception {
        CharStream input = CharStreams.fromString("3 + 5 - 2");
        ExampleLexer lexer = new ExampleLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        ExampleParser parser = new ExampleParser(tokens);
        ParseTree tree = parser.expr();
        ExampleVisitor visitor = new ExampleVisitor();
        int result = visitor.visit(tree);
        System.out.println("Result: " + result);
    }
}
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

JAVA重写equals()方法同时要重写hashcode()方法

object对象 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true;注意:当此方法被重写时...,通常有必要重写 hashCode 方法,以维护 hashCode 方法常规协定,该协定声明相等对象必须具有相等哈希码。...equals,那么比较将是对象引用是否指向同一块内存地址,重写之后目的是为了比较两个对象value值是否相等。...这样如果我们对一个对象重写了euqals,意思是只要对象成员变量值都相等那么euqals就等于true,但不重写hashcode,那么我们再new一个新对象,当原对象.equals(新对象)等于true...时,两者hashcode却是不一样,由此将产生了理解不一致,如在存储散列集合时(如Set类),将会存储了两个值一样对象,导致混淆,因此,就也需要重写hashcode()举例说明:  import

1.8K60
  • 【IT领域新生必看】 Java编程重写(Overriding)规则:初学者轻松掌握全方位指南

    引言 在Java编程重写(Overriding)是一个重要概念。它允许子类重新定义父类方法,从而实现多态性和灵活代码设计。理解并掌握重写规则,对于编写健壮和可维护代码至关重要。...对于初学者来说,了解重写基本规则和最佳实践,是成为Java编程高手关键一步。本篇文章将详细介绍Java重写规则,帮助你全面理解这一重要概念。 什么是方法重写(Overriding)?...当调用myDog.makeSound()时,执行是Dog类实现,而不是Animal类实现。 方法重写规则 1....通过本文介绍,你应该对Java重写规则有了全面的了解。希望你在编程学习过程不断进步,成为一名出色程序员!...无论你是在实现多态性、提供特定实现,还是改进父类方法,记住遵循重写规则和最佳实践,这将使你代码更加高效、可读和可靠。祝你编程愉快!

    17810

    java重载和重写区别

    区别点 重载方法 重写方法 参数列表 必须修改 一定不能修改 返回类型 可以修改 一定不能修改 异常 可以修改 可以减少或删除,一定不能抛出新或者更广异常 访问 可以修改 一定不能做更严格限制(可以降低限制...) 总结 方法重写(Overriding)和重载(Overloading)是java多态性不同表现,重写是父类与子类之间多态性一种表现,重载可以理解成多态具体表现形式。...(1)方法重载是一个类定义了多个方法名相同,而他们参数数量不同或数量相同而类型和次序不同,则称为方法重载(Overloading)。...(2)方法重写是在子类存在方法与父类方法名字相同,而且参数个数与类型一样,返回值也一样方法,就称为重写(Overriding)。...(3)方法重载是一个类多态性表现,而方法重写是子类与父类一种多态性表现。

    68530

    Java重载和重写区别

    重载就是同样一个方法能够根据输入数据不同,做出不同处理 重写就是当子类继承自父类相同方法,输入数据一样,但要做出有别于父类响应时,你就要覆盖父类方法 重载 发生在同一个类(或者父类和子类之间...下面是《Java 核心技术》对重载这个概念介绍: 综上:重载就是同一个类多个同名方法根据不同传参来执行不同逻辑处理。 案例:比较两个数据是否相等。...重写发生在运行期,是子类对父类允许访问方法实现过程进行重新编写。...构造方法无法被重写 综上:重写就是子类对父类方法重新改造,外部样子不能改变,内部逻辑可以改变 区别点 重载方法 重写方法 发生范围 同一个类 子类 参数列表 必须修改 一定不能修改 返回类型 可修改...编译期 运行期 方法重写要遵循 两同两小一大: “两同”即方法名相同、形参列表相同; “两小”指的是子类方法返回值类型应比父类方法返回值类型更小或相等,子类方法声明抛出异常类应比父类方法声明抛出异常类更小或相等

    60330

    Java重载与重写区别

    java重载与重写区别 1、重载发生在本类,重写发生在父类与子类之间; 2、重载方法名必须相同,重写方法名相同且返回值类型必须相同; 3、重载参数列表不同,重写参数列表必须相同。...比如,同一个类,写不同构造函数用于初始化不同参数。...重写(Overriding) 重写发生在父类子类之间,比如所有类都是继承与Object类,Object类本身就有equals,hashcode,toString方法等.在任意子类定义了重名和同样参数列表就构成方法重写...例如:如果父类一个方法被声明为public,那么在子类重写该方法就不能声明为protected。...(4):子类和父类在同一个包,那么子类可以重写父类所有方法,除了声明为private和final方法。

    73420

    Java命名规则

    Java命名规则 在查找java命名规则时,未在国内相关网站查找到较为完整文章,这是一篇国外程序开发人员写java命名规则文章,原文是英文写,为了便于阅读,遂翻译为汉语,以便帮助国内开发者有所了解...在较小层面上,这似乎没有意义,但考虑到工业层面,为了节省时间,有必要编写干净代码,因为已经制定了某些规则,其中一个因素是命名关键字这在Java中被称为命名约定。...尝试在末尾使用“able”,是的,据说是尝试,因为没有硬和快速绑定规则,就像我们考虑一个内置接口,比如“Remote”,它在末尾没有ble。...Java命名规则 在java,将类、变量和方法命名为它们实际应该做事情,而不是随机命名,这是一种很好做法。下面是java编程语言一些命名约定。...注意:请注意以下java驼峰大小写例外情况: 在包,即使我们在java组合两个或多个单词,一切都用小写 在常量,我们确实将所有内容都用作大写字母,即使我们在java组合两个或多个单词,也只使用

    99610

    Antlr4 语法解析器(下)

    Antlr4规则文法: 注释:和Java注释完全一致,也可参考C注释,只是增加了JavaDoc类型注释; 标志符:参考Java或者C标志符命名规范,针对Lexer 部分 Token 名定义,...Antlr4语法文件Antlr4语法,支持关键字有:import, fragment, lexer, parser, grammar, returns, locals, throws, catch..., finally, mode, options, tokens 基于IDEA调试Antlr4语法规则(文法可视化) ?...Spark & Antlr4 Spark SQL /DataFrame 执行过程是这样子: ? 我们看下在 Spark SQL 是如何使用Antlr4....我们可以通过继承这个类,重写对应节点visit方法,实现自己访问逻辑,Spark SQL这个继承类就是org.apache.spark.sql.catalyst.parser.AstBuilder

    3.5K20

    Java重载、重写和重构区别

    重载规则: (1)必须具有不同参数列表。 (2)可以有不同返回类型,只要参数列表不同就可以了。 (3)可以有不同访问修饰符。 (4)可以抛出不同异常。...示例中子类doIt()方法就使用了这个新功能,父类doIt()方法返回值类型为Parent类,而子类doIt()方法返回值类型为Children类,子类重写了父类doIt()方法。...这种重写方式需要遵循一个原则,即重写返回值类型必须是父类同一方法返回值类型子类,而Children类正是Parent类子类。...注意:当重写父类方法时,修改方法修饰权限只能从小范围到大范围改变,例如,父类dosomething()方法修饰权限为protected,继承后子类方法doSomething()修饰权限只能修改为...重写规则: (1)参数列表必须完全与被重写方法相同,否则不能称其为重写而是重载。

    1.4K20

    Java方法重载和重写(覆盖)

    方法重载(overload)  /*  * 方法重载判定:同一类,方法名相同,参数列表不同(参数个数不同,参数列表对应位置参数类型不同),其他方法返回值  * 和访问修饰符都随意。  ...:参数列表对应位置类型不同,与参数名字没有任何联系,所以在判断方法重载过程     // 不考虑参数顺序是否变化。     ...,不管是否进行了参数顺序改变,最后在方法记录过程,     // 还是会记录成上面报错信息提示那样,而这个参数列表与第一个函数参数列表一模一样。    ...方法重写(覆盖)  方法重写也叫方法覆盖,表示子类要对父类某一方法进行修改,方法重写比较简单,通常遵循以下原则:  1. 两同:方法名和方法参数列表相同  2....一大: 子类重写方法访问权限大于等于父类方法  3. 二小:子类重写方法抛出异常类型要小于等于父类;子类重写方法返回值类型小于等于父类

    2.2K20

    Web前端命名规则

    能以背景形式呈现图片, 尽量写入css样式; 13. 重要图片必须加上alt属性; 给重要元素和截断元素加上title; 14...., 此文件包含reset及头部底部样式, 此文件不可随意修改; 3. class与id使用: id是唯一并是父级, class是可以重复并是子级, 所以id仅使用在大模块上, class可用在重复使用率高及子级..., 请以自己代号加下划线起始, 比如i_clear; d)a,b两条, 适用于在2已建好框架页面, 如, 要在2已建好框架页面代码中加入新...原生JavaScript变量要求是纯英文字母, 首字母须小写, 如iTaoLun; jQuery变量要求首字符为'_', 其他与原生JavaScript 规则相同, 如: _iTaoLun; 另, 要求变量集中声明...开发过程严格按分工完成页面, 以提高css复用率, 避免重复开发; 2. 减小沉冗代码, 书写所有人都可以看代码. 简洁易懂是一种美德. 为用户着想, 为服务器着想.

    2.3K90

    python变量命名规则

    python变量命名规则 1.变量命名 2. 变量命名描述性 3.变量名尽量短,但是不要太短 4.合理使用变量 5. 变量定义尽量靠近使用 6. 合理使用namedtuple/dict 6....在一个函数,一个变量名叫做 photo, 那么在其他地方就不要改成image。 5. 变量定义尽量靠近使用 刚开始学习编程时,我们习惯把定义变量放在开头,或一些函数最前面。...合理使用namedtuple/dict Python函数可以返回多个值,如果某一天我们想让函数再多返回一个值怎么办呢?...控制单个函数内变量数量 当某一函数过长时,或者包含太多变量时,请及时把它拆分成多个小函数。 7. 删除掉没用变量 在一个函数,如果某一个定义变量没有被用到,请及时删除它。 8....平比嵌套好。 疏比密好。 可读性。 特殊情况并不特别到足以打破规则。 尽管实用性胜过纯洁。 错误不应该悄无声息地过去。 除非显式地沉默。 面对模棱两可,拒绝猜测诱惑。

    1.2K20

    【答疑解惑】Java重载和重写区别

    重载和重写属于Java面向对象多态基础知识点,下面就给大家说说多态。 什么叫做多态? 多态指的是在继承关系中子类继承父类行为,这种行为在子类具体实现时可以是不一样。...比如动物这一父类中有move()方法,在鸟类子类中和鱼类子类move实现是不一样。...在Java多态是通过重写(@Override:把父类方法重新实现)和重载(@Overload:通过方法参数不同在子类来重新创建名字相同方法)来实现。...重写: 重写(Override)是父类与子类之间多态性一种表现。如果在子类定义某方法与其父类有相同名称和参数,我们说该方法被重写 (Override)。...子类对象使用这个方法时,将调用子类定义,对它而言,父类定义如同被“屏蔽”了。 重载: 重载(Overload)是一个类多态性一种表现。

    67870

    Java继承类static成员函数重写

    在java,static成员函数是否可以被重写呢? 结论是,你可以在子类重写一个static函数,但是这个函数并不能像正常非static函数那样运行。...也就是说,虽然你可以定义一个重写函数,但是该函数没有多态特性。.../输出结果为 static in testClass1 16 tc2.SMothod(); //输出结果为 static in testClass2 17 } 18 } 从结果可以看到...,当我们用父类实例引用(实际上该实例是一个子类)调用static函数时,调用是父类static函数。...原因在于方法被加载顺序。 当一个方法被调用时,JVM首先检查其是不是类方法。如果是,则直接从调用该方法引用变量所属类中找到该方法并执行,而不再确定它是否被重写(覆盖)。

    1.7K40

    Java静态方法不能被子类重写

    参考链接: 可以在Java重载或重写静态方法吗 Java静态方法不能被子类重写 特点:静态方法属于类方法,也属于对象方法,但是静态方法随类存在。...结论:Java静态方法不能被子类重写,实际上,子类静态方法隐藏了父类静态方法,因此父类子类静态方法同时存在,只不过父类通过类名(或对象名)调用是父类静态方法,子类通过类名(或对象名)调用是子类静态方法...,不支持多态,所以此处调用父类静态方法         f1.doWork();            // 非static(静态)方法调用,支持多态         System.out.println...(final,private 方法也如此) (2)静态方法可通过类名直接调用,也可通过类实例化对象调用,因此Father 实例化对象f1调用是父类(不是子类)静态方法。...(3)静态方法绑定时期为代码编译器期,也叫前期绑定。非静态方法属于程序执行期绑定,也就运行期绑定。

    2.3K20
    领券