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的一些关键概念做了比较详细的概述,通读 ...
随机推荐
- hduacm 5104
http://acm.hdu.edu.cn/show #include <cstdio> #include <cstring> #include <algorithm&g ...
- regsvr32 注册.dll的用法
Regsvr 32命令是Windows中控件文件(如扩展名为DLL.OCX.CPL的文件)的注册和反注册工具. 命令格式 Regsvr32 [/s] [/n] [/i[:cmdline]] dllna ...
- SharePoint加K2,将Portal系统与BPM系统完美整合!
K2 blackPearl与Microsoft Office SharePoint 一起为解决人员和流程相互合作的解决方案而提供一个强大的平台. K2“blackpearl”根据企业的需求提供了设计, ...
- JDK的下载与安装
一.下载 在Oracle公司的官方网站(www.oracle.com)下载. 二.安装 1.双击运行JDK程序,弹出JDK安装导向窗口,点击“下一步” 2.点击“更改",将安装地址修改为 C ...
- 理解NSAttributedString
An NSAttributedString object manages character strings and associated sets of attributes (for exampl ...
- declare 关键字在Oracle中的应用。
一般用在trigger或匿名存储过程中使用.如 declare a number;begina:=1;end;
- hdu 2029
PS: 逻辑问题... 代码: #include "stdio.h"#include "string.h"int main(){ char a[110]; i ...
- 三、XML编程(CRUD)
DOM:W3C标准SAX:simple API for XMLDOM解析会把整个文档读入内存变成一个对象,会把标签变为Element对象,会把文本变成Text对象,会把属性变为Attribute对象, ...
- Planning for a period of time
After a period of struggle , i decided to follow the teacher Chen learning . Say true i really disli ...
- linux 任务调度 系统任务调度
linux at 针对运行一次的任务 crontab 控制计划任务的命令 crond系统服务 crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程, 与windows ...