ANTLR语法层的选项

ANTLR语法层的选项中可以设置一系列的键值从而影响ANTLR输出的代码。这些选项是全局的,除非在某条规 则中覆盖了这些选项,否则这些选项会影响到该语法中的所有元素。选项应该紧跟在语法头后面,具有如下的形式:

options {
name1 = value1;
name2 = vaule2;
...
}

选项中的名字必须使用标识符(identifiers),但是其值可以为标识符、单引号括起来的字串、整 数或者特殊的字串——*(目前仅对选项K起作用)。
目前的ANTLR支持的语法层的选项主要包括:语言选项(Language)、输出选项 (output)、回溯选项(backtrack)、记忆选项(memorize)、记号词库(tokenVocab)、重写选项(rewrite)、超 类选项(superClass)、过滤选项(Filter)、AST标签类型(ASTLabelType)以及K选项。

1. 语言选项
语 言选项指定了ANTLR将要产生的代码的目标语言,默认情况下该选项设置为了Java。需要注意的是,ANTLR中的嵌入的动作必须要使用目标语言来写。 如下面的例子:
grammar T;
options {
language=Java;
}
a : ... {《action-in-Java-language》} ... ;

ANTLR使用了特有的基于字串模板 (StringTemplate-based)代码生成器,构建一个新的目标语言显得较为简单,因此我们可以构建多种语言,诸如 Java,C,C++,C#,Python,Objective-C,Ruby等等。语言选项让ANNTLR去模板目录(例如org/antlr
/codegen/templates/Java or org/antlr/codegen/templates/C)下寻找合适的模板,并使用模板来构建语言。该目录下包含大量的模板,我们可以向其中加入其 他的模板以满足我们的需求。但需要注意,这些模板所在路径应该在CALSSPATH这个环境变量中已经指明。

2. 输出选项
输出 选项控制了ANTLR输出的数据结构,目前支持两种输出:抽象语法树——AST(Abstract Syntax Trees)和字串模板(StringTemplates)——template。当output这个选项被设置后,所有的规则都被输出成了AST或者
template。

output=AST允许我们使用树构造运算符或者重写规则。下面是一个简单的语法,它构造了一个虚拟的根节点—— DECL,并用输入的记号ID来为这个根节点创建一个子节点:

grammar T;

options {
output=AST;
}

decl    :    ID -> ^(DECL ID) ;
ID        :    'a'..'z'+ ;

关于输出模板的问题在后面,暂时还没有看到。

3. 回溯选项
当回溯选项打开的时候,在执行一个LL(K)失败的时候,ANTLR会返回至LL(K)开始而尝试其他的规则。

4.记 忆选项
memoize选项打开以后,每条解析方法(Paser Method)开始之前,ANTLR会首先检测以前的尝试结果,并在该方法执行完成之后记录该规则是否执行成功。但是注意,对于单条的规则打开此选项经常 比在全局上打开该规则效率更高。

5. tokenVocab选项
大型的工程中常常利用AST作为中间产物对输入进行多次分析并最 终生成代码。对AST的遍历时需要经常使用树语法(tree grammar),而tree grammar中经常需要将符号与其他的文件中的符号进行同步或者更新。tokenVocab实现了这个功能。
例如我们定义了下面的一个语法文 件:

grammar P;
options {
output=AST;
}
expr: INT ('+' ^ INT)* ;
INT : '0'..'9' +;
WS : ' ' | '\r' | '\n' ;
利 用该文件生成了一个标记:P.token,并生成了语法树(AST)。这时我们需要一个用于遍历该AST的tree grammar,并通过tree grammar 中的tokenVocab选项来向其中更新tokens:

tree grammar Dump;
options {
tokenVocab=P;
ASTLabelType=CommonTree;
}
expr: ^( '+' expr {System.out.print('+' );} expr )
| INT {System.out.print($INT.text);}
;

编译tree grammar的时候ANTLR默认会在当前目录下寻找.token文件,我们可以通过-lib选项来设置用于寻找.token文件的目录,例如:
java org.antlr.Tool -lib . Dump.g

6. 重写选项
通过重写选项可以改变ANTLR对输入的默认处理规 则,一般用在输出为template的情况下。将该选项使能之后,ANTLR将一般的输入直接拷贝至输出,而将适于模板重写规则的输入做其他的处理。

7. 超类选项
用于指定一个超类。

8. 过滤选项
用于过滤一些感兴趣的输入。但是一般在词法分析上不常用到。

9. AST标签类型

10. TokenLabelType

11. K选项
K选项用于限制对LL(K)进行语法分 析的次数,从而提高了ANTLR的解析速度。K只能为*或者数字,默认为*。

××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

属 性和动作

动作(Actions)实际上是用目标语言写成的、嵌入到规则中的代码(以花括号包裹)。它们通常直接操作输入的标号,但是他们也可以 用来调用相应的外部代码。属性,到目前为止我的理解还不多,感觉像是C++中类里面的成员,一会看完应该会更清楚一些。

1. 语法动作(Grammar Actions)
动作(Actions)是指嵌在语法中的、用目标语言写成的代码片段。ANTLR则把这些代码(除了 用$或%标记的以外)逐字地插入到生成的识别器中。
动作可以放到规则的外边,也可以嵌入到某条规则当中。当动作位于规则之外时候,这些动作同城定 义了一些全局的或者是类的成员(变量或者成员函数);而当其嵌入规则之中时,则用于执行某些特定的命令,这些命令在识别器识别了其预订的字符的时候就会开 始执行。例如下面的例子:

parser grammar T;
@header {
package p;
}
@members {
int i;
public TParser(TokenStream input, int foo) {
this(input);
i = foo;
}
}
a[int x] returns [int y]
@init {int z=0;}
@after {System.out.println("after matching rule; before finally");}
: {《action1》} A {《action2 》}
;
catch[RecognitionException re] {
System.err.println("error");
}
finally { 《do-this-no-matter-what 》 }

从中可以看出,前面的两个动作,@head and @members是两个处于规则之外的全局的动作,定义了一些变量和类;而后两个则分别在a这个规则的前后执行(@init在前,@after在后,这个 在前面提到过)。 这里针对两种类型详细叙述。

1.1 全局动作
ANTLR提供了几个全局动作以便让用户填充代码,这些全局动作 已经预先定义了名字和执行条件,例如前面代码中的head和members等等,其含义分别为:
header ——这里的代码段将会出现在识别器的类定义之前。通常,也就是程序开始时候的包的定义和引入之前。
members ——指定了实例变量和方法。
rulecatch —— 用来取代默认的、进行出错处理的程序。
synpredgate ——用于改变默认的syntax predict date

1.2 嵌入动作——基本上前面已经全了。

ANTLR语法层的选项及动作 - ANTLR的更多相关文章

  1. ANTLR 语法设计

    下面学习如何编写语法. 如何定义语法规则 一种语言模式就是一种递归的语法结构. 我们需要从一系列有代表性的输入文件中归纳出一门语言的结构.在完成这样的归纳工作后,我们就可以正式使用ANTLR语法来表达 ...

  2. antlr 4新特性总结及与antlr v3的不同

    antlr 4新特性总结及与antlr v3的不同 学习曲线低.antlr v4相对于v3,v4更注重于用更接近于自然语言的方式去解析语言.比如运算符优先级,排在最前面的规则优先级最高: 层次更清晰. ...

  3. Antlr语法优化过程记录

    背景 Modelica Spec中的语法文件在Antlr下表现很糟糕,至少是1个数量级的糟糕的性能表现 理论 语义谓词减慢速度 ATN图中多分支转换为单分支 可选放在词法开头和语法的结尾 避免前导可选 ...

  4. 开源语法分析器--ANTLR

      序言 有的时候,我还真是怀疑过上本科时候学的那些原理课究竟是不是在浪费时间.比方学完操作系统原理之后我们并不能自己动手实现一个操作系统:学完数据库原理我们也不能弄出个像样的DBMS出来:相同,学完 ...

  5. 开源解析器--ANTLR

      序言 有的时候,我还真是怀疑过上本科时候学的那些原理课究竟是不是在浪费时间.比方学完操作系统原理之后我们并不能自己动手实现一个操作系统:学完数据库原理我们也不能弄出个像样的DBMS出来:相同,学完 ...

  6. ANTLR 简介

    <ANTLR 4权威指南>由机械工业出版社出版,有兴趣的读者推荐购买阅读. 本专题大多内容来源于我读<ANTLR 4权威指南>的随手笔记以及个人实践,仅供参考学习,请勿用于任何 ...

  7. Linux正则与文本处理工具(10)

    正则表达式 (Regular Expression, RE, 或称为常规表达式)是通过一些特殊字符的排列,用于『查找/替换/删除』一行或多行文字或字符串,简单的说,正则表达式就是用在字串的处理上面的一 ...

  8. Linux_Shell脚本

    Shell脚本 shell基础 shell变量 shell扩展 shell基础 shell简介 1.什么是shell? shell是一种命令解释器 shell也是一种编程语言 shell,python ...

  9. 探索Antlr(Antlr 3.0更新版)

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明 http://www.blogbus.com/dreamhead-logs/10756716.html <探索Antlr> ...

  10. 如何用 ANTLR 4 实现自己的脚本语言?

    ANTLR 是一个 Java 实现的词法/语法分析生成程序,目前最新版本为 4.5.2,支持 Java,C#,JavaScript 等语言,这里我们用 ANTLR 4.5.2 来实现一个自己的脚本语言 ...

随机推荐

  1. C#/.NET/.NET Core技术前沿周刊 | 第 3 期(2024年8.26-8.31)

    前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录.追踪C#/.NET/.NET Core领域.生态的每周最新.最实用.最有价值的技术文章.社区动态.优质项目和学习资源等. ...

  2. mybatis-plus批量增加、批量修改样例+建表语句+postman接口

    使用mybatis-plus开发中会遇到数据量多的情况下,插入和修改效率低,主要原因是"新增"和"修改"方法是对一条数据进行处理的,如果有一万条数据就会和数据库 ...

  3. cesium中添加建筑白模

    1.在cesium中添加模型依赖于Cesium ion帐户的资产id,在这里创建账户. 2.上传模型(模型文件类型在Cesium ion中有说明,模型的提取办法可在这里查看)到账户中并平铺为3D Ti ...

  4. kubernetes删除ns异常状态为:Terminating

    在部署kuboard控制平台的时候,不规范删除,导致ns状态为Terminating [root@master01 ~]# kubectl delete namespace kuboard ^C ro ...

  5. C++ | 每一个C++程序员都应该知道的RAII

    导读:RAII是C++中一种管理资源.避免资源泄漏的惯用法,利用栈的特点来实现.本文较为详细介绍了RAII的原理.使用方法和优点,并且通过实例讲解了RAII在C++ STL中的应用,如智能指针和互斥锁 ...

  6. Go日志管理库zap

    一.zap介绍 在许多Go语言项目中,我们需要一个好的日志记录器能够提供下面这些功能: 1.能够将事件记录到文件中,而不是应用程序控制台. 2.日志切割-能够根据文件大小.时间或间隔等来切割日志文件. ...

  7. 交通网络分析性能再升级,SuperMap iServer新增开启SSC分析模型

    导语 SSC分析模型,全名SuperMap Short Cut,底层采用Contraction Hierarchies(简称CH)算法,该算法旨在通过对图形进行预处理和优化来降低最佳路径分析的时间复杂 ...

  8. Android libusb

    一.环境:配置NDK环境 1.下载libusb源码: https://github.com/libusb/libusb/releases,如下图所示 2.删除一些和Android平台无关的文件,删除后 ...

  9. ChatGPT “眼”中的开源数据库

    开源作为数据库发展的未来趋势之一,被冠以"数据库弯道超车的法宝"的称号.中国开源数据库产品正处于蓬勃发展的趋势,根据 墨天轮中国数据库流行度 ,截止2023年2月底已有46款开源数 ...

  10. js中,什么是数组 , 数组有几种创建方式?

    1. 什么是数组? 数组是可以把一组相关的数据一起存放,并提供方便的访问(存取) 数组是指一组数据的集合,其中每个数据被称作元素(数组单元),数组单元可以是任意类型的数据,数组是一种将一组数据存储在单 ...