ANTLR3完全参考指南读书笔记[07]
前言
//demo.stg decl(type, name, value) ::= " ;" init(v) ::= " = "
decl(type, name, value)、init(v)为模板名和模板参数,为条件表达式(conditions),其它<...>为占位符。
STGroup group = new STGroupFile("demo.stg");//绝对路径 ST st = group.getInstanceOf("decl");//获取模板实例 st.add("type", "int");//填充占位符 st.add("name", "x"); st.add("value", 0); String result = st.render();//模板输出
语法 | 说明 |
%foo(a={}, b={},...) | 模板构建语法:创建模板foo,设置其属性a、b... |
%({<<nameExpr>>}(a={}...)) | 间接模板构造引用,nameExpr是计算出的模板名称,其他部分与模板构造语法相同 |
%x.y=<<z>> | 将模板x的属性y赋值为值z |
%{<<expr>>}.y=<<z>> | 将StringTemplate类型表达式expr的属性赋值为表达式z的值 |
%{<<stringExpr>>} | 从String类型stringExpr创建匿名模板 |
3+4*5
output:
; public class Calc extends Object { ...} .class public Calc .super java/lang/Object ; public Calc() { super(); } // calls java.lang.Object() .method public ()V aload_0 invokenonvirtual java/lang/Object/()V return .end method ; main(): Expr.g will generate bytecode in this method .method public static main([Ljava/lang/String;)V .limit stack ; how much stack space do we need? .limit locals ; how many locals do we need? getstatic java/lang/System/out Ljava/io/PrintStream; ; code translated from input stream ; compute 3+4*5 ldc ldc ldc imul iadd ; print result on top of stack invokevirtual java/io/PrintStream/println(I)V return .end method
int x; void foo(){ int y; y = 1; g(34, y); x = h(); }
int x; void foo(){ int y; y = 1; write_to("y", y) g(34, y); call("g"); x = eval_r("h", h()); write_to("x", x) }
grammar Expr; options{output=AST;ASTLabelType=CommonTree;} @header{ package template; import java.util.HashMap; } @members { int numOps = 0;//operation count HashMap locals = new HashMap();//local variable name-count map int localVarNum = 1;//local variable count } prog : stat+; stat : expr NEWLINE -> expr | ID '=' expr NEWLINE { if(locals.get($ID.text)==null){ locals.put($ID.text, new Integer(localVarNum++)); } } -> ^('=' ID expr) | NEWLINE -> ; expr : multExpr ('+'^|'-'^) multExpr {numOps++;} ; multExpr: atom ('*'^ atom {numOps++;})* ; atom : INT | ID | '('! expr ')'!; ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* ; INT : '0'..'9'+; WS : ( ' '| '\t'| '\r'| '\n') {$channel=HIDDEN;} ; NEWLINE : '\r'?'\n';
tree grammar Gen; options { tokenVocab=Expr; ASTLabelType=CommonTree; output=template; } @header { package template; import java.util.HashMap; } @members { HashMap locals; } prog[int numOps, HashMap locals] @init {this.locals= locals;} : (s+=stat)+ -> jasminFile(instructions={$s}, maxStackDepth={numOps+1+1}, maxLocals={locals.size()+1}) ; stat : expr -> exprStat(v={$expr.st}, descr={$expr.text}) | ^('=' ID expr) -> assign(id={$ID.text}, descr={$text}, varNum={locals.get($ID.text)}, v={$expr.st}) ; expr returns [int value] : ^('+' a=expr b=expr) -> add(a={$a.st}, b={$b.st}) | ^('-' a=expr b=expr) -> sub(a={$a.st}, b={$b.st}) | ^('*' a=expr b=expr) -> mult(a={$a.st}, b={$b.st}) | INT -> int(v={$INT.text}) | ID -> var(id={$ID.text}, varNum={locals.get($ID.text)}) ;
group ByteCode; jasminFile(maxStackDepth, maxLocals, instructions) ::= << ; public class Calc extends Object { ...} .class public Calc .super java/lang/Object ; public Calc() { super(); } // calls java.lang.Object() .method public \()V aload_0 invokenonvirtual java/lang/Object/\()V return .end method ; main(): Expr.g will generate bytecode in this method .method public static main([Ljava/lang/String;)V .limit stack ; how much stack space do we need? .limit locals ; how many locals do we need? getstatic java/lang/System/out Ljava/io/PrintStream; ; code translated from input stream ; print result on top of stack invokevirtual java/io/PrintStream/println(I)V return .end method >> assign(varNum, v ,descr, id) ::= << ;compute descr istore : id >> exprStat(v, descr) ::= << ; compute >> add(a, b) ::= << iadd >> sub(a, b) ::= << isub >> mult(a, b) ::= << imul >> int(v) ::= "ldc " var(id, varNum) ::= "iload ; "
package template; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.InputStream; import org.antlr.runtime.ANTLRInputStream; import org.antlr.runtime.CommonTokenStream; import org.antlr.runtime.tree.CommonTree; import org.antlr.runtime.tree.CommonTreeNodeStream; import org.antlr.stringtemplate.StringTemplate; import org.antlr.stringtemplate.StringTemplateGroup; public class ByteCodeGeneratorTest { public static void main(String[] args) throws Exception { FileReader groupFileReader = new FileReader("D:/workspace/maven/antlrv3/grammar/template/generator/ByteCode.stg"); StringTemplateGroup templateGroup = new StringTemplateGroup(groupFileReader); groupFileReader.close(); // [1]3+4*5 // [2]a=3+4 // a InputStream is = new FileInputStream(new File("D:/workspace/maven/antlrv3/language/template.test")); ANTLRInputStream inputStream = new ANTLRInputStream(is); ExprLexer lexer = new ExprLexer(inputStream); CommonTokenStream tokenStream = new CommonTokenStream(lexer); ExprParser parser = new ExprParser(tokenStream); ExprParser.prog_return r = parser.prog(); // tree walker to generate template's value CommonTree tree = (CommonTree) r.getTree(); CommonTreeNodeStream treeNodeStream = new CommonTreeNodeStream(tree); treeNodeStream.setTokenStream(tokenStream); Gen walker = new Gen(treeNodeStream); walker.setTemplateLib(templateGroup); Gen.prog_return r2 = walker.prog(parser.numOps, parser.locals); StringTemplate output = (StringTemplate) r2.getTemplate(); System.out.println(output.toString()); } }
grammar CMinus; options{output=template;rewrite=true;} program : declaration+; declaration : variable | function ; variable: type ID';'; function: type ID '(' (formalParameter (',' formalParameter)* )? ')' block; formalParameter : type ID; type : 'int'|'void'; stat scope{boolean isAssign;} : expr ';' | block | ID '=' {$stat::isAssign=true;} expr ';' -> template(id={$ID.text}, assign={$text}) " write_to(\"\", )" | ';' ; block : '{' variable* stat* '}'; expr : ID | INT | ID '(' (expr (',' expr)* )? ')' -> {$stat::isAssign}? template(id={$ID.text}, e={$text}) "eval_r(\"\", )" ->template(id={$ID.text}, e={$text}) "; call(\"\")" | '(' expr ')' ; ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* ; INT : '0'..'9'+ ; COMMENT : '' {$channel=HIDDEN;} ; WS : ( ' '| '\t'| '\r'| '\n') {$channel=HIDDEN;};
package template.rewriter; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import org.antlr.runtime.ANTLRInputStream; import org.antlr.runtime.TokenRewriteStream; public class Test { public static void main(String[] args) throws Exception { InputStream is = new FileInputStream(new File("D:/workspace/maven/antlrv3/language/rewriter/CMinus.test")); ANTLRInputStream input = new ANTLRInputStream(is); CMinusLexer lexer = new CMinusLexer(input); TokenRewriteStream tokens = new TokenRewriteStream(lexer); CMinusParser parser = new CMinusParser(tokens); parser.program(); System.out.println(tokens.toString()); } }
ANTLR3完全参考指南读书笔记[07]的更多相关文章
- ANTLR3完全参考指南读书笔记[01]
引用 Terence Parr. The Definitive ANTLR Reference, Building Domain Specific Languages(antlr3 version). ...
- ANTLR3完全参考指南读书笔记[06]
前言 这段时间在公司忙的跟狗似的,但忙的是没多少技术含量的活儿. 终于将AST IR和tree grammar过了一遍,计划明天写完这部分的读书笔记. 内容 1 内部表示AST构建 2 树文法 ...
- ANTLR3完全参考指南读书笔记[02]
前言 程序语言是什么? 用wiki上的描述,程序语言是一种人工设计的语言,用于通过指令与机器交互:程序语言是编程程序的标记,而程序是一种计算或算法的描述.详细介绍和背景信息参考: Programmin ...
- ANTLR3完全参考指南读书笔记[08]
前言 不要让用户被那些“专业术语”吓住! 用心设计的提示和反馈信息是软件设计者的“职业良心”. 内容 1 存在哪些错误? 2 美化错误提示 3 错误恢复策略 1 存在哪些错误? 在DSL语言开 ...
- ANTLR3完全参考指南读书笔记[05]
前言 仅生成给出true/false的识别器是没有多大用处的,自然的就有在识别过程中遇到某一结构时执行一段代码.存储该结构中信息的想法. ANTLR提供了在文法中嵌入属性和动作超级混合“文法”,可以生 ...
- ANTLR3完全参考指南读书笔记[04]
前言 学习框架或第三方库的方法是什么 (1)少量的浏览manual或tutoral,只关注程序所需的特征,再完善其详细内容和特征的认识? (2)花大量的时间研究详细内容,再考虑程序实现? 这是个先有鸡 ...
- ANTLR3完全参考指南读书笔记[03]
前言 文中第4章内容有点多,有点枯燥,但不坚持一下,之前所做的工作就白做了. 再次确认一下总体目标: protege4编辑器中Class Definition中语法解析和错误提示: Java虚拟机规范 ...
- 机器学习实战 - 读书笔记(07) - 利用AdaBoost元算法提高分类性能
前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习笔记,这次是第7章 - 利用AdaBoost元算法提高分类性能. 核心思想 在使用某个特定的算法是, ...
- HTTP权威指南读书笔记
HTTP权威指南笔记 读书有两种境界,第一种境界是将书读薄,另一种是读厚.本篇文章就是HTTP权威指南的读书笔记,算是读书的第一重境界,将厚书读薄.文章对HTTP的一些关键概念做了比较详细的概述,通读 ...
随机推荐
- 利用开源框架Volley来下载文本和图片。
Android Volley是Android平台上很好用的第三方开源网络通信框架.使用简单,功能强大. 下载连接地址:http://download.csdn.net/detail/zhangphil ...
- Zabbix页面遇到历史记录的乱码需要修改数据库
Zabbix页面遇到历史记录的乱码需要修改数据库: 解决办法: 1.将 zabbix 数据库中的表备份: 2.手动删除 zabbix 数据库: 3.重新创建 zabbix 库时手动指定字符集为 utf ...
- 6.1.1Linux下Socket编程
什么是Socket Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序.要学Internet上的TCP/IP网络编程, ...
- WDCP管理面板安装启动EXIF、bcmath完整步骤
一般我们网站建设的需要,如果使用WDCP面板默认的功能就足够使用,如果需要特殊程序的特定组件支持,就需要独立的安装支持组件.比如一位朋友的程序需要支持EXIF.bcmath组件,这不老蒋寻找解决方法, ...
- 交互式的Flash图表和仪表控件AnyChart
AnyChart使你可以创建出绚丽的交互式的Flash图表和仪表控件.是一款灵活的基于Adobe Flash和跨浏览器和跨平台的图表解决方案,被很多知名大公司所使用,可以用于仪表盘的创建.报表.数据分 ...
- 多功能节点连线绘图控件Nevron Diagram for .NET使用方法及下载地址
Nevron Diagram for .NET是一个功能强大,世界上顶级的.NET图表控件.可扩展的图形报表构架,可以帮您创建功能丰富的Winforms及Webforms图表解决方案.这个产品构建于N ...
- 推荐一款免安装的在线Visio流程工具ProcessOn
昨天收到一人的邮件,说某个软件叫ProcessOn是web版的visio,出于对技术知识的渴望以及自己的好奇所以对ProcessOn进行了一番体验.结果有点被这个软件给吸引上了,无论是在用户体验上,还 ...
- [转]ps/2键盘线序识别方法
from: http://www.360doc.com/content/11/0816/19/844619_140875056.shtml 经常看到有人询问ps/2线坏了,更换的时候如何测线序连线,或 ...
- java.lang.NoSuchMethodError: org.springframework.web.context.request.ServletRequestAttributes.<init>
今天学习 srping mvc 的配置 在核心版本对的情况下,把项目从Server中移除,然后重新加入即可.来源stack over flow
- POJ题目分类(按初级\中级\高级等分类,有助于大家根据个人情况学习)
本文来自:http://www.cppblog.com/snowshine09/archive/2011/08/02/152272.spx 多版本的POJ分类 流传最广的一种分类: 初期: 一.基本算 ...