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的一些关键概念做了比较详细的概述,通读 ...
随机推荐
- AngularJS recursive(递归)
工作中我们经常要遍历多层数据,如果数据是已知层级的话,用 ng-repeat 就搞定了,要是数据深度是无限的呢,或者我们要实现一个无限层级的 tree 的时候,该怎么办? 答案是使用 ng-inclu ...
- 数据结构-Stack和Queue
实现: #include "c2_list.h" template <typename object> class Stack{ public: bool isEmpt ...
- 腾讯微博数据抓取(java实现)
不多说,同样贴出相关代码 参数实体: package token.def; import java.io.Serializable; import java.util.Properties; publ ...
- 踏着前人的脚印学Hadoop——结构、重点
HDFS作为一个分布式文件系统,是所有这些项目的基础.分析好HDFS,有利于了解其他系统.由于Hadoop的HDFS和MapReduce是同一个项目,我们就把他们放在一块,进行分析. 如果把整个had ...
- C++学习之类的构造函数、析构函数
在C++的类中,都会有一个或多个构造函数.一个析构函数.一个赋值运算操作符.即使我们自己定义的类中,没有显示定义它们,编译器也会声明一个默认构造函数.一个析构函数和一个赋值运算操作符.例如: //声明 ...
- jQuery 常用动画
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- <转>用thinkPHP实现验证码的功能
许多系统的登录都有验证码,而如果使用thinkPHP框架搭建网站的话,验证码的生成和验证就比较容易了 1.生成验证码 thinkPHP有对应生成验证码的方法 要使用验证码,需要导入扩展类库中的ORG. ...
- 2013年7月底至8月初51Aspx源码发布详情
兼职人员信息管理系统源码 2013-8-2 [VS2008]2013.8.2更新内容:修改了一级菜单不能修改的bug.功能介绍:兼职人员信息管理:添加,修改,删除,查询,支持数据导出Excel,按多 ...
- HashMap简单理解
1. hashmap基于哈希表的map接口实现,此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable ...
- Linksys WRT120N路由器备份文件解析
Perusing the release notes for the latest Linksys WRT120N firmware, one of the more interesting comm ...