ANTLR3完全参考指南读书笔记[06]
前言
^(root ^(child1 leaf1 leaf2) child2)
forStat : 'for' '(' decl? ';' expr? ';' expr? ')' slit;
输入for(int i=0;;i++){...}的部分AST:
^(FOR ^(VARDEF int i 0) EXPR ^(++ i))
Tree getChild(int i); int getChildCount(); void addTree(Tree t); boolean isNil();
TreeAdaptor的实例见代码//TreeAdaptor编程示例
rule : <<alt1>> -> <<build-this-form-alt1>>
| <<alt2>> -> <<build-this-form-alt2>>
...
| <<altn>> -> <<build-this-form-altn>>
;
重写规则是描述如何生成树的文法,Parr列出了重写机制常用的场景
sample:
stat : 'break' ';' -> 'break' ;
expr : '(' expr ')' -> expr
| INT -> INT
;
(2)输入元素重排序
decl : 'var' ID ':' type -> type ID;
(3)将某输入元素作为其他元素的根节点
stat : 'return' expr ';' -> ^('return' expr);
decl : 'var' ID ':' type -> ^('var' type ID);//与默认机制一致
(4)添加虚构节点
decl :type ID ';' -> ^(VARDEF type ID); forLoopConditional : expression -> ^(EXPR expression) | -> EXPR //需添加此虚构节点,否则会造成信息丢失,压缩的IR不能过分压缩! ;
(5)收集输入元素一起提交
list : ID (',' ID)* -> ID+ ;
formalArgs : formalArg (',' formalArg)* -> formalArg+
|
;
decl : 'int' ID (',' ID)* -> ^('int' ID+);
compilationUnit : packageDef? importDef* typeDef+
-> ^(UNIT packageDef? importDef* typeDef+)
;
(6)复制节点和树
dup : INT -> INT INT;
decl : 'int' ID (',' ID)* -> ^('int' ID)+ ;
decl : type ID (',' ID)* -> ^(type ID)+ ;
decl : modifier? type ID (',' ID)* -> ^(type modifier? ID)+ ;
(7)运行时选择树结构:语义谓词
variableDefinition : modifiers types ID ('=' expression)? ';'
-> {inMethod}? ^(VARIABLE ID modifier* expression?)
-> ^(FIELD ID modifier* expression?)
;
a[int which] : ID INT -> {which==1}? ID
-> {which==2}? INT
->
;
forStat : 'for' '(' decl? ';' cond=expr? ';' iter=expr? ')' slist
-> ^('for' decl? ^(CONDITION $cond)? ^(ITERATE $iter)?)
;
(9)用任意动作创建节点
a : INT -> {new CommonTree(new CommonToken(FLOAT, $INT.text+".0"));} ;
typeDefinition : modifiers! classDefinition[$modifiers.tree]
| modifiers! iterfaceDefinition[$modifiers.tree]
;
classDefinition[CommonTree mod] ://parser规则的参数是CommonTree
'class' ID ('extend' sup=typename)?
('implements' i+=typename (',' i+=typename)*)?
'{'
(variableDefinition|methodDefinition|constructorDefiniton)*
'}'
-> ^('class' ID {$mod} ^('extends $sup)? ^('implements' $i+)?//这里$i+是汇总列表,对应多个子节点
variableDefinition* methodDefinition* constructorDefiniton*)
;
(10)重写规则元素的基数
intValue : expr? -> ^(EXPR expr)? ;
(11)子规则中的重写规则
ifStat : 'if' '(' equalityExpression ')' s1=statement
('else' s2=statement -> ^('if' ^(EXPR equalityExpression) $s1 $s2)
| -> ^('if' ^(EXPR equalityExpression) $s1)
)
;
decl : type
(ID '=' INT -> ^(DECL_WITH_INT type ID INT)
|ID -> ^(DECL type ID)
)
;
(12)在重写规则中引用之前规则生成的AST
expr : (INT -> INT ('+' i=INT -> ^('+' $expr $i))* ;
其部分AST: ^('+' $expr 3)
compoundStatement : lp='{' statement* '}' -> ^(SLIST[$lp] statement*) ;
(14)结合重写规则与自动默认的AST构造
primary : INT | FLOAT | '(' expression ')' -> expression ;
tree grammar
options {
tokenVocab=;
ASTLabelType=CommonTree;
}
char c;
int x;
int foo(int y, char d){
int i;
; i!=; i=i+){
x=;
y=;
}
}
(VAR char c) (VAR int x) (FUNC int foo (ARG int y) (ARG char d) (SLIT (VAR int i) (for (= i 0) (!= i 3) (= i (+ i 1)) (SLIT (= x 3) (= y 5)))))
java -classpath antlr-3.5-complete.jar org.antlr.Tool CMinus.g CMiusWalker.g
(b.3)生成的tree解析器验证代码见代码//tree解析器结果验证程序
dot ast.dot -Tpng -o ast.png
生成结果见下图
public class TreeAdaptorDemo {
public static void main(String[] args) {
// 定义虚构Token类型
int LIST = 1;
int ID = 2;
TreeAdaptor adaptor = new CommonTreeAdaptor();
// CommonTree root = (CommonTree) adaptor.nil();
CommonTree root = (CommonTree) adaptor.create(LIST, "LIST");
root.addChild((CommonTree) adaptor.create(ID, "x"));
root.addChild((CommonTree) adaptor.create(ID, "y"));
root.addChild((CommonTree) adaptor.create(ID, "z"));
System.out.println(root.toStringTree());
}
}
//combined grammar: CMinus
grammar CMinus;
options {output=AST;}
tokens { //用于生成AST中虚构节点的Token
VAR;FUNC;ARG;SLIST;
}
program : declaration+
;
declaration
: variable
| function
;
variable: type ID ';' -> ^(VAR type ID);
type : 'int'|'char';
function: type ID '(' (formalParameter (',' formalParameter)*)? ')' block
-> ^(FUNC type ID formalParameter* block)
;
formalParameter
: type ID -> ^(ARG type ID)
;
block : lb='{' variable* stat* '}' -> ^(SLIST[$lb, "SLIT"] variable* stat*)
;
stat : forStat
| expr ';'!
| assignStat ';'!
| ';'!
;
forStat : 'for' '(' init=assignStat ';' expr ';' inc=assignStat ')' block
-> ^('for' $init expr $inc block)
;
assignStat
: ID '=' expr -> ^('=' ID expr)
;
expr : condExpr;
condExpr: aexpr (('=='^|'!='^) aexpr)?;
aexpr : mexpr ('+'^ mexpr)*;
mexpr : atom ('*'^ atom)*;
atom : ID
| INT
| '('! expr ')'!
;
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
INT : '0'..'9'+
;
WS : ( ' '| '\t'| '\r'| '\n') {$channel=HIDDEN;}
;
public class ParserTest {
public static void main(String[] args) throws Exception {
InputStream is = new FileInputStream(new File("D:/workspace/maven/antlrv3/language/CMinus.test"));
// create a CharStream that reads from standard input
// ANTLRInputStream input = new ANTLRInputStream(System.in);
ANTLRInputStream input = new ANTLRInputStream(is);
// create a lexer that feeds off of input CharStream
CMinusLexer lexer = new CMinusLexer(input);
// create a buffer of tokens pulled from the lexer
CommonTokenStream tokens = new CommonTokenStream(lexer);
// create a parser that feeds off the tokens buffer
CMinusParser parser = new CMinusParser(tokens);
// begin parsing at rule program to get its return tree
CMinusParser.program_return program = parser.program();
CommonTree tree = (CommonTree) program.getTree();
System.out.println(tree.toStringTree());
System.out.println(tree.toString());// 仅显示root
}
}
//tree grammar: CMiusWalker
tree grammar CMiusWalker;
options {tokenVocab=CMinus; ASTLabelType=CommonTree;}
program : declaration+
;
declaration
: variable
| function
;
variable: ^(VAR type ID) {System.out.println("define "+$type.text +" "+ $ID.text);}
;
type : 'int'|'char';
function: ^(FUNC type ID formalParameter* block) {System.out.println("define " +$type.text + " " +$ID.text + "()");}
;
formalParameter
: ^(ARG type ID)
;
block : ^(SLIST variable* stat*)
;
stat : forStat
| expr
| assignStat
;
forStat : ^('for' assignStat expr assignStat block)
;
assignStat
: ^('=' ID expr)
;
expr : ^('==' expr expr)
| ^('!=' expr expr)
| ^('+' expr expr)
| ^('*' expr expr)
| ID
| INT
;
public class FinalTest {
public static void main(String[] args) throws Exception {
InputStream is = new FileInputStream(new File("D:/workspace/maven/antlrv3/language/CMinus.test"));
// create a CharStream that reads from standard input
// ANTLRInputStream input = new ANTLRInputStream(System.in);
ANTLRInputStream input = new ANTLRInputStream(is);
// create a lexer that feeds off of input CharStream
CMinusLexer lexer = new CMinusLexer(input);
// create a buffer of tokens pulled from the lexer
CommonTokenStream tokens = new CommonTokenStream(lexer);
// create a parser that feeds off the tokens buffer
CMinusParser parser = new CMinusParser(tokens);
// begin parsing at rule program to get its return tree
CMinusParser.program_return program = parser.program();
CommonTree tree = (CommonTree) program.getTree();
System.out.println(tree.toStringTree());
// DOT tree generate
DOTTreeGenerator dotTreeGenerator = new DOTTreeGenerator();
StringTemplate st = dotTreeGenerator.toDOT(tree);
System.out.println(st);
CommonTreeNodeStream nodes = new CommonTreeNodeStream(tree);
nodes.setTokenStream(tokens);
CMiusWalker walker = new CMiusWalker(nodes);
walker.program();
}
ANTLR3完全参考指南读书笔记[06]的更多相关文章
- ANTLR3完全参考指南读书笔记[01]
引用 Terence Parr. The Definitive ANTLR Reference, Building Domain Specific Languages(antlr3 version). ...
- ANTLR3完全参考指南读书笔记[02]
前言 程序语言是什么? 用wiki上的描述,程序语言是一种人工设计的语言,用于通过指令与机器交互:程序语言是编程程序的标记,而程序是一种计算或算法的描述.详细介绍和背景信息参考: Programmin ...
- ANTLR3完全参考指南读书笔记[08]
前言 不要让用户被那些“专业术语”吓住! 用心设计的提示和反馈信息是软件设计者的“职业良心”. 内容 1 存在哪些错误? 2 美化错误提示 3 错误恢复策略 1 存在哪些错误? 在DSL语言开 ...
- ANTLR3完全参考指南读书笔记[07]
前言 真正意义上的程序员都很懒,懒的连多余的一行代码也不写. 如果能将底层满手油污的活儿都可以交给别人去做,自己就扮演个智囊团成员的角色,生活会比想象中的还要惬意. 严格的按照指令执行长时间不知疲倦的 ...
- ANTLR3完全参考指南读书笔记[05]
前言 仅生成给出true/false的识别器是没有多大用处的,自然的就有在识别过程中遇到某一结构时执行一段代码.存储该结构中信息的想法. ANTLR提供了在文法中嵌入属性和动作超级混合“文法”,可以生 ...
- ANTLR3完全参考指南读书笔记[04]
前言 学习框架或第三方库的方法是什么 (1)少量的浏览manual或tutoral,只关注程序所需的特征,再完善其详细内容和特征的认识? (2)花大量的时间研究详细内容,再考虑程序实现? 这是个先有鸡 ...
- ANTLR3完全参考指南读书笔记[03]
前言 文中第4章内容有点多,有点枯燥,但不坚持一下,之前所做的工作就白做了. 再次确认一下总体目标: protege4编辑器中Class Definition中语法解析和错误提示: Java虚拟机规范 ...
- 强化学习读书笔记 - 06~07 - 时序差分学习(Temporal-Difference Learning)
强化学习读书笔记 - 06~07 - 时序差分学习(Temporal-Difference Learning) 学习笔记: Reinforcement Learning: An Introductio ...
- HTTP权威指南读书笔记
HTTP权威指南笔记 读书有两种境界,第一种境界是将书读薄,另一种是读厚.本篇文章就是HTTP权威指南的读书笔记,算是读书的第一重境界,将厚书读薄.文章对HTTP的一些关键概念做了比较详细的概述,通读 ...
随机推荐
- 利用开源框架Volley来下载文本和图片。
Android Volley是Android平台上很好用的第三方开源网络通信框架.使用简单,功能强大. 下载连接地址:http://download.csdn.net/detail/zhangphil ...
- 用PHP的socket实现客户端到服务端的通信
服务端 <?php error_reporting(E_ALL); set_time_limit(0); ob_implicit_flush(); //本地IP $address = 'loca ...
- Servlet初识
1.servlet的生命周期 servlet生命周期中的三大重要时刻 servlet从不存在状态迁移到初始化状态(能够为客户提供服务),首先是从构造函数开始,但是构造函数只是使其成为一个对象,而不是一 ...
- virtualbox安装提示出现严重错误解决办法
解决办法: 在服务里面启动1. Device Install Service2. Device Setup Manager 这两个服务就好了.也有可能只需要启动第一个.
- Android 之 数据存储
在Android操作系统中,提供了5种数据存储方式:SharedPreferences存储,文件存储,SQLite数据库存储,ContentProvider存储和网络存储. 一.SharedPrefe ...
- 解决python version 2.7 required,which was not find in the registry
程序自动写注册表 http://www.vvivv.com/post-143.html 手工写 http://blog.csdn.net/baikaishui525/article/details/9 ...
- KVO的内部实现原理
kvo概述 kvo,全称Key-Value Observing,它提供了一种方法,当对象某个属性发生改变时,允许监听该属性值变化的对象可以接受到通知,然后通过kvo的方法响应一些操作. kvo实现原理 ...
- 开源留言板 --wekan部署
1. 安装ubuntu--server-64位系统 2. 登录ubuntu系统 3. 下载自动安装脚本 #git clone https://github.com/anselal/wekan 4. 执 ...
- pager分页框架体会
<pg:pager> 元素的属性中: maxPageItems说的是每页偏移量是多少,这个并不是说每一页显示多少,而是第二页比第一页来说,在第一页的尾部增加多少,第一页又被覆盖多少,是决定 ...
- 巧用nginx屏蔽对用户不可见的文件
事情的起因是这样的--前端的项目中有一些.less之类的源文件,而为了方便迭代更新发布,直接就把整个工程放到了www目录下. 这样虽然方便了,但是会带来一些安全隐患——用户可以访问/盗取这些源文件. ...