antlr 介绍以及脚本编写(一)
2017-04-16 22:40
176 查看
1、 介绍
ANTLR—Another Tool for Language Recognition,antlr是指可以根据输入自动生成语法树并可视化的显示出来的开源语法分析器。
antlr主要内容有三个: 词法分析器(Lexer)、语法分析器(Parser)、树分析器 (tree parser)。无论是Lexer还是Parser都是一种识别器,Lexer是字符序列识别器而Parser是Token序列识别器。他们在本质上是类似的东西,而只是在分工上有所不同而已;树分析器可以用于对语法分析生成的抽象语法树进行遍历,并能执行一些相关的操作
一般分成两个阶段;
第一阶段: 大脑会下意识的将字符组成单词,然后像查询字典一样识别它们的意思(词法分析 lexical analysis: lex)
第二阶段:大脑会根据已识别的单词去识别句子的结构(parser 默认为antlr会构建出一棵分析树(parser tree)或叫语法树(syntax tree));
2、 启动ui和运行
需要jar包为: antlr-3.1.3.jar(运行包)、antlrworks-1.4.jar(ui界面包)
启动ui: java -cp jar包的路径 org.antlr.works.IDE
运行: java -cp jar包的路径 org.antlr.Tool *.g
3、 运行计算方法:
1. 脚本里加入action
2. 构建AST(abstract syntax tree);
3、 脚本编写实例
实例1:
parser和lexer结合
实例2:
parser lexer tree三个结合
4、个人总结:
1. 编写.g脚本的时候,里面的语言可以java/c++等
2. 编写tree的脚本的时候,需要根据AST树的情况来确定最终的结果。一般需要设计成迭代执行。
3. parser rule 和tree rule 冒号左边都是方法名。
5、 java代码调用
ANTLR—Another Tool for Language Recognition,antlr是指可以根据输入自动生成语法树并可视化的显示出来的开源语法分析器。
antlr主要内容有三个: 词法分析器(Lexer)、语法分析器(Parser)、树分析器 (tree parser)。无论是Lexer还是Parser都是一种识别器,Lexer是字符序列识别器而Parser是Token序列识别器。他们在本质上是类似的东西,而只是在分工上有所不同而已;树分析器可以用于对语法分析生成的抽象语法树进行遍历,并能执行一些相关的操作
一般分成两个阶段;
第一阶段: 大脑会下意识的将字符组成单词,然后像查询字典一样识别它们的意思(词法分析 lexical analysis: lex)
第二阶段:大脑会根据已识别的单词去识别句子的结构(parser 默认为antlr会构建出一棵分析树(parser tree)或叫语法树(syntax tree));
2、 启动ui和运行
需要jar包为: antlr-3.1.3.jar(运行包)、antlrworks-1.4.jar(ui界面包)
启动ui: java -cp jar包的路径 org.antlr.works.IDE
运行: java -cp jar包的路径 org.antlr.Tool *.g
3、 运行计算方法:
1. 脚本里加入action
2. 构建AST(abstract syntax tree);
3、 脚本编写实例
实例1:
parser和lexer结合
grammar Expr; //parser rule expr returns [int value=0]: a=INT PLUS b=INT { int aValue = Integer.parseInt(a.getText()); int bValue = Integer.parseInt(b.getText()); $value = aValue + bValue; } // lexer rule PLUS: '+'; INT: ('0'..'9')+; 备注: lexer rule 要求字符首字母大写,一般默认整个单词都大写 parser rule 要求首字母小写,一般默认整个单词小写 字符串一般加单引号 每行结束符需要加分好 执行命令后会生成 Expr.tokens/ExprLexer.java/ExprParser.java
实例2:
parser lexer tree三个结合
// 分为两个.g文件 // 1. parser和lexer Expr.g grammar Expr; options { ASTLabelType = CommonTree; language = Java; output = AST; } // tokens 分词 构建AST需要 tokens { PROG; STAT; NUM; VAR; // AND = 'and'; } //parser rule prog: stat -> ^(PROG stat); //构建语法树 stat: expr EOF -> ^(STAT expr); expr: multiExpr (('+'^|'-'^) multiExpr)*; multiExpr : atom (('*'^|'/'^) atom)*; atom: '('expr')' -> expr | INT ->^(NUM INT) | ID -> ^(VAR ID ); // lexer rule ID: ('a'..'z'|'A'..'Z')+; INT: ('0'..'9')+; NEWLINE: '\r'?'\n'; WS: (' ' | '\t'|'\n'|'\r')+ {skip{};}; // 空行,一般执行跳过动作 // 2 tree 文件 Eval.g 执行命令后会生成Eval.tokens/Eval.java tree grammar Eval; options { tokenVocab = Expr; // parser文件名 ASTLabelType = CommonTree; language = Java; } // tokens 分词 构建AST需要 tokens { PROG; STAT; NUM; VAR; // AND = 'and'; } @header {import java.util.Random;} //tree parser rule prog: ^(PROG s=stat) { // prog要执行的方法体 System.out.println("Computer result:" + s.intValue()); }; stat returns [Integer value]: ^(STAT e=expr) { $value = e.intValue(); }; expr returns [Integer value]: ^('+' e1=expr e2=expr) {$value = e1.intValue() + e2.intValue();} | ^('-' e1=expr e2=expr) {$value = e1.intValue() - e2.intValue();} | a = atom {$value = a.intValue();}; atom returns [Integer value]: ^(NUM i=INT) {$value = Integer.parseInt(i.getText());}; //备注: 1. 整个两个文件在执行org.antlr.Tool 的时候,格式为org.antlr.Tool *.g,确保Expr.tokens 和 Eval.tokens一致才行
4、个人总结:
1. 编写.g脚本的时候,里面的语言可以java/c++等
2. 编写tree的脚本的时候,需要根据AST树的情况来确定最终的结果。一般需要设计成迭代执行。
3. parser rule 和tree rule 冒号左边都是方法名。
5、 java代码调用
String rule= "111=222 AND 333=444"; ANTLRStringStream input = new ANTLRStringStream(rule); // 生成的lexer类 FilterRuleLexer lexer = new FilterRuleLexer(input); CommonTokenStream tokens = new CommonTokenStream(lexer); // 生成的parser类 FilterRuleParser parser = new FilterRuleParser(tokens); // parser中的主规则, parser中的任何规则都可以返回commontree, 一般默认调用主规则 CommonTree tree = (CommonTree)parser.rule().getTree(); CommonTreeNodeStream nodes = new CommonTreeNodeStream(tree); nodes.setTokenStream(tokens); //生成的treerule类 FilterTreeRule treeRule = new FilterTreeRule(nodes); System.out.println(treeRule.rule());// tree rule类中的主规则 System.out.println(tree.token);
相关文章推荐
- 【网络】arp协议介绍以及Shell脚本进行arp的编写
- 用Python编写shell脚本时经常使用的函数的介绍
- Python编写shell脚本中常用的文件介绍
- nginx在windows下的安装,以及编写启动关闭nginx等操作的脚本
- AppleWatch开发教程之Watch应用对象新增内容介绍以及编写运行代码
- Shell脚本的编写,sed的使用以及一些正则表达式
- 在Robot中使用脚本调用,头文件以及DATAPOOL进行脚本编写
- iOS Sprite Kit教程之编写程序以及Xcode的介绍
- 【COCOS2DX-LUA 脚本开发之六】利用Lua强转函数解决使用CCNode报错或无法正常使用以及简单介绍 quick-cocos2d-x 与 OpenQuick 两款Lua免费开源框架
- 十五、动态链接库介绍以及静态库的编写
- iOS Sprite Kit教程之编写程序以及Xcode的介绍
- [Linux学习日记]Ubuntu推荐软件以及简单脚本编写
- JMeter的介绍和脚本录制以及对WEB进行测试
- 本附录介绍iOS系统包含的框架,它们为编写iOS平台的软件提供必要的接口。下面的表格尽可能地列出框架中的类、方法、函数、类型以及常量使用的关键前缀,请避免在您的符号名称中使用这些前缀。
- iptables防火墙详解(三)规则的导出、导入以及编写防火墙脚本
- 脚本侵入介绍以及错误处理
- SecureCRT自动登陆到服务器的脚本以及脚本编写简单说明
- 使用BASH编写Linux Shell脚本——1. Linux 介绍
- SecureCRT自动登陆到服务器的脚本以及脚本编写简单说明
- iOS Sprite Kit教程之编写程序以及Xcode的介绍