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的一些关键概念做了比较详细的概述,通读 ...
随机推荐
- [转载]java NIO详解
Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API.下面的文章写的很详细,还配有插图,有助于深入学习和理解java NIO 文 ...
- 获取checkbox数组 里面的值
echo '<td class="text-left"><input name="tids[]" type="checkbox&q ...
- 在JavaScript 自定义对象来模拟Java中的Map
直接看代码: //模拟一个Map对象 function Map(){ //声明一个容器 var container={}; //定义一个put方法,向容器中存值 this.put=function(k ...
- 基于K2的集成供应链流程解决方案
基于K2的集成供应链流程解决方案http://www.k2software.cn/zh-hans/scm-solution 一.详细功能模块 需求管理模块多渠道管理.需求计划.需求感知与传递市场营销及 ...
- Android中findViewById()获取EditText 空指针问题
因为EditText editText = (EditText)layout.findViewById(R.id.input_content);是从Dialog对话框布局layout中寻找ID为inp ...
- Android drawBitmapMesh扭曲图像
今天介绍一下在Android当中怎么扭曲图像,在Android系统中的Canvas提供了一个drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshH ...
- <select>标签使用方法
前台页面: <form id="form1" runat="server"> <select runat="server" ...
- vs2012 断点不能调试
调试ASP.NET时发现,设置的断点被视而不见 提示错误 debugging information for ‘iisexpress.exe’cannot be found or does not m ...
- 北大ACM题库习题分类与简介(转载)
在百度文库上找到的,不知是哪位大牛整理的,真的很不错! zz题 目分类 Posted by fishhead at 2007-01-13 12:44:58.0 -------------------- ...
- 上位机控制led
使用库函数,调试的结果在标红程序上,int main(void){ u8 a; u8 t; u8 len; u16 ti ...