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的一些关键概念做了比较详细的概述,通读 ...
随机推荐
- Oracle 过程控制语句整理
分支语句/循环语句 v_case ) :; begin then dbms_output.put_line('条件成立'); elsif then then dbms_output.put_line( ...
- 6.1.2Linux下Socket编程
tcp简单实验 server.c #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include ...
- No module ata_piix found的解决方法
在一台as4u6的机器上升级内核到2.6.18时,最好make install的时候报了一个WARNING: No module ata_piix found for 2.6.18, 开始没有在意,重 ...
- 戴文的Linux内核专题:01介绍
转自Linux中国 译者按:本文作者戴文.科利尔.约翰逊(Devyn Collier Johnson)今年才19岁,但是他在Linux内核.人工智能.编程语言方面拥有丰富的经验,本文是其在linux. ...
- BPM与OA,选择好烦恼!
企业在信息化建设的过程中 难免遭遇BPM和OA之争, 难!难!难! 选择BPM吧, 有人觉得你“打肿脸充胖子”: 选择OA嘛, “行业大哥”们已经在BPM的路上越走越远… 其实, OA和BPM从某种意 ...
- VC单文档对话框添加托盘图标
一 单文档添加托盘 1. 在CMainFrame中定义NOTIFYICONDATA结构m_notify 2.在OnCreate中添加托盘初始化代码 int CMainFrame::OnCreate(L ...
- HTML参考
HTML Basic Document <html> <head> <title>Document name goes here</title> < ...
- fastboot 刷system.img 提示 sending 'system' (*KB)... FAILED (remote: data too large)
华为G6-C00卡刷提示OEMSBL错误,只能线刷 ,但是官方找不到线刷img镜像,无奈 网上下了个可以线刷的工具套件 流氓ROM . 使用HuaweiUpdateExtractor(工具百度)把官方 ...
- VMware-workstation-full-10.0.3-1895310 CN
Name: VMware-workstation-full-10.0.3-1895310.exe发行日期: 2014-07-01内部版本号: 1895310文件大小: 491 MB文件类型: exe ...
- KVO的内部实现原理
kvo概述 kvo,全称Key-Value Observing,它提供了一种方法,当对象某个属性发生改变时,允许监听该属性值变化的对象可以接受到通知,然后通过kvo的方法响应一些操作. kvo实现原理 ...