用ANTLR实现规则解析
来源:互联网 发布:js input 赋值 编辑:程序博客网 时间:2024/06/05 19:02
ANTLR(pronounced Antler) 是一个语言识别工具,Another Tool forLanguage Recognition 的缩写。ANTLR由旧金山大学(University of San Francisco)的教授 Terence Parr 开发并维护的,其始于1989年,到了现在过了20多年,一直都是一个很活跃的项目。
ANTLR 一般用于构建 Domain-Specific Languages (DSL)。用户编写好特定语言的语法文件后,ANTLR 会根据该语法文件生成相应的源代码来识别该语言。ANTLR 3.4 (截至2011-10-15最新的版本) 支持的编程语言(runtime)包括:ActionScript, Csharp2, Delphi,JavaScript, Perl5, Ruby , C, CSharp3, Java, ObjC, Python。其中 C runtime 由 Jim Idle 维护,C runtime 也是本文关注的部分。在早期的版本中提供有C++ 的runtime,但是在最新的版本中只提供 C 语言的 runtime。
很多的开源的软件都使用了ANTLR 作为自己的DSL 解析工具,比如: Hibernate,一个在javaEE 中运用非常广泛的ORM 框架,使用ANTLR解析 HQL –一种类似于SQL 的面向对象的数据库查询语言;Apache Hive,一个建于 Hadoop 之上的数据仓库查询语言,使用ANTLR解析HiveQL;TOra,Toolkit for Oracle,一个用 Qt写的Oracle 数据库管理工具,使用ANTLR解析Oracle SQL 和 PL/SQL。还有其他很多的软件也使用了ANTLR,比如 Esper,StreamBase,这两个都是用 Java 写的数据流处理引擎。
本文主要基于一个例子简单的讲解如果使用 ANTLR,介绍一些ANTLR的基本概念,本文不包括语言识别的理论知识,和ANTLR的一些高级应用,想了解这些知识应该学习编译理论相关知识,并阅读Terence Parr编写的The Definitive ANTLR Reference 。
ANTLR支持生成词法分析器,语法解析器和树解析器,同时也支持把代码和语法规则混合在一起编写,个人觉得两者混合在一起写对于开发会很方便,可是这样会影响语法的可读性,所以在本文中语法与代码不会混合在一起写。
本文将一步步的从头开始使用C语言构造一个简单的StreamSQL 解析器。该StreamSQL 解析器实现对 CREATE INPUT STREAM,CREATE OUTPUT STREAM,CREATE SCHEMA,CREATE WINDOW,SELECT 等语句的解析。
工具准备
1、首先下载 ANTLR3.4。http://www.antlr.org/download.html 我们要下载的是ANTLR 3.4 distribution (Source for tools, targets, complete binaries)
2、下载 ANTLRWorks。 ANTLRWorks 是一个可视化的开发工具,为语法的编写和调试提供了很大的方便。Antlrworks-1.4.3.jar下载地址:http://download.csdn.net/download/tesky0125/4680601
3、下载 ANTLR v3 plugin for eclipse。这是一个Eclipse的插件,可以在Eclipse 里为ANTLR语法文件提供语法高亮,也可以作为语法的调试工具,不 过它的调试功能没有 ANTLRWorks 强大。
注:ANTLR相关工具下载网址:https://github.com/antlr/website-antlr3/tree/gh-pages/download
语法描述
我们要解析的语言如下表所示。CREATE INPUT STREAM Packet PacketTuple;
CREATE OUTPUT STREAM Aggregate AggregateTuple;
CREATE SCHEMA PacketTuple (time INT,price DOUBLE );
CREATE SCHEMA AggregateTuple(
time INT,
maxprice DOUBLE ,
currenttime INT);
CREATE WINDOW Dimension1(SIZE 180 ADVANCE 10 ON time);
SELECT max(price) AS maxprice, max(time) AS currenttime
FROM Packet[Dimension1] INTO Aggregate;
用来解析上面语言的ANTLR语法。grammar StreamSQL;
options {
language=C;
ASTLabelType=pANTLR3_BASE_TREE;
output=AST;
}
tokens {
TOK_CREATE_SCHEMA;
TOK_CREATE_STREAM;
TOK_CREATE_WINDOW;
TOK_SELECT;
TOK_SCHEMA_LIST;
TOK_NAME_TYPE;
TOK_SELEXPR;
TOK_SELITEM;
TOK_SELLIST;
}
statement
: selectStatement EOF
| createStatement EOF
;
selectStatement
: KW_SELECT selectList
KW_FROM instreamName=Identifier LSQUARE windowName=Identifier RSQUARE KW_INTO outstreamName=Identifier
-> ^(KW_SELECT selectList $instreamName $windowName $outstreamName)
;
selectList
: selectColumn (COMMA selectColumn)*
-> ^(TOK_SELLIST selectColumn+)
;
selectColumn
: selectItem
| selectExpression
;
selectItem
: Identifier KW_AS Identifier
-> ^(TOK_SELITEM Identifier Identifier)
;
selectExpression
: functionName=Identifier LPAREN itemName=Identifier RPAREN KW_AS asName=Identifier
-> ^(TOK_SELEXPR $functionName $itemName $asName)
;
createStatement
: KW_CREATE KW_SCHEMA Identifier schemaList
-> ^(TOK_CREATE_SCHEMA Identifier schemaList)
| KW_CREATE streamType KW_STREAM streamName=Identifier schemaName=Identifier
-> ^(TOK_CREATE_STREAM streamType $streamName $schemaName)
| KW_CREATE KW_WINDOW
windowName=Identifier LPAREN KW_SIZE Number KW_ADVANCE Number KW_ON onWhat=Identifier RPAREN
-> ^(TOK_CREATE_WINDOW $windowName Number Number $onWhat)
;
schemaList
: LPAREN columnNameType (COMMA columnNameType)* RPAREN
-> ^(TOK_SCHEMA_LIST columnNameType+)
;
streamType
: (KW_INPUT | KW_OUTPUT)
;
columnNameType
: coluName=Identifier dataType
-> ^(TOK_NAME_TYPE $coluName dataType)
;
dataType
: KW_INT
| KW_DOUBLE
;
// Keywords
KW_FROM : 'FROM';
KW_AS : 'AS';
KW_SELECT : 'SELECT';
KW_ON : 'ON';
KW_CREATE: 'CREATE';
KW_INT: 'INT';
KW_DOUBLE: 'DOUBLE';
KW_INTO: 'INTO';
KW_SCHEMA: 'SCHEMA';
KW_INPUT: 'INPUT';
KW_OUTPUT: 'OUTPUT';
KW_STREAM: 'STREAM';
KW_WINDOW: 'WINDOW';
CREATE INPUT STREAM Packet PacketTuple;
CREATE OUTPUT STREAM Aggregate AggregateTuple;
CREATE SCHEMA PacketTuple (time INT,price DOUBLE );
CREATE SCHEMA AggregateTuple(
time INT,
maxprice DOUBLE ,
currenttime INT);
CREATE WINDOW Dimension1(SIZE 180 ADVANCE 10 ON time);
SELECT max(price) AS maxprice, max(time) AS currenttime
FROM Packet[Dimension1] INTO Aggregate;
- 用ANTLR实现规则解析
- ANTLR实现的SQL解析器 - OQL
- 用antlr实现将SQL转换成EQL(Ehcache Search Query)的语法解析器
- 用ANTLR3实现规则解析----1-安装
- Antlr 中 fragment词法规则
- ANTLR解析(一)
- 用ANTLR3实现规则解析----2-grammar概览
- 开源解析器--ANTLR
- ANTLR里迭代子规则的一个注意点
- ANTLR实现简单计算器[C#]
- Atitit.antlr实现词法分析
- Antlr
- antlr
- Antlr
- ANTLR
- Antlr
- 使用Eclipse/Antlr解析简单文本
- 基于antlr的表达式解析器
- Mac OS X 配置 Cocos2d-x 开发环境(iOS 和 Android)
- cocos2d-x部分函数介绍
- CCTMXTiledMap
- makefile项目管理读书笔记
- 指针和引用的区别
- 用ANTLR实现规则解析
- 详细解析Java中抽象类和接口的区别
- InstallShield注册控件(DLL、OCX)
- SQL查询分析器远程单步调试存储过程的解决之道?
- 尊重原创,请保证您的文章为原创作品
- 图解SQL的Join
- VC获取磁盘容量
- 面试的一点心得,失败的教训
- TS流相关知识