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的一些关键概念做了比较详细的概述,通读 ...
随机推荐
- 解决visualsvn监听ip 错误的问题
系统重启+休眠之类的,弄几次,莫名其妙的svn就连接不上了, 有时候启动不起,有时候是启动连接不上,发现监听的ip错了 TCP [::]:443 [::]:0 ...
- HDU 1828 扫描线(矩形周长并)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- ROS主题发布订阅控制真实的机器人下位机
先模拟控制小乌龟 新建cmd_node.ccpp文件: #include"ros/ros.h" #include"geometry_msgs/Twist.h" ...
- tabbarcontroller 内嵌导航 控制器,2层push hide tabbar 后 ,第二层直接返回根视图控制器选择tabbarcontroller的其它vc 无法显示 tabbar的 问题解决方案
场景如标题 这样不行: [self.navigationController popToRootViewControllerAnimated:YES]; MainViewController *mai ...
- DB2配置信息查看及其更新命令
获取DB2配置信息 db2 get dbm cfg 更新DB2链接配置信息 db2 update dbm cfg using authentication server db2stop db2star ...
- CodeForces 546B-Soldier and Badges
题意: 给出一些数字,要求每个数字都不一样需要增加几 思路: 先排序,然后一个个增加,最后求总和差 代码如下: #include <iostream> #include <cstdi ...
- [转]change the linux startup logo
1. Make sure that you have the kernel sources installed. As annoying as this may seem, you will need ...
- android平台手电筒开发源代码
android平台手电筒开发源代码,AndroidManifest.xml文件的入口是startapp,这个文件没上传上来,大家可以自己写. 1. [代码]android 1 2 3 4 5 6 7 ...
- 有关WAMPSERVER 环境搭建 如何修改端口,MySQL数据库的修改
环境搭建 http://share.weiyun.com/88896747fedd4e8b19afebea18f7684c 一.修改Apache的监听端口 1.在界面中选Apache,弹出隐藏菜单选项 ...
- 解决办法-错误:Access denied for user 'root'@'localhost' - java
如下更改密码即可 mysql> UPDATE user SET Password=PASSWORD('newpassword') where USER='root';mysql> FLUS ...