StringTemplate Terence Parr University of San Francisco [email protected].
-
Upload
elwin-thompson -
Category
Documents
-
view
217 -
download
1
Transcript of StringTemplate Terence Parr University of San Francisco [email protected].
StringTemplateStringTemplate
Terence ParrTerence Parr
University of San FranciscoUniversity of San Francisco
parrtparrt@[email protected]
OutlineOutline
What is StringTemplateWhat is StringTemplate OperationsOperations SemanticsSemantics Example Java/XML GenerationExample Java/XML Generation ANTLR 3.0 templateANTLR 3.0 template
What is StringTemplate?What is StringTemplate? Template engine designed with Tom Burns Template engine designed with Tom Burns
(CEO, jGuru.com) while building commercial (CEO, jGuru.com) while building commercial sites over many years sites over many years in response to JSPin response to JSP small: 170k uncompressed binary (w/o test rig)small: 170k uncompressed binary (w/o test rig)
Evolved from simple “document with holes” Evolved from simple “document with holes” into a functional language capable of into a functional language capable of generating large class of languagesgenerating large class of languages
Well suited to generative programming as well Well suited to generative programming as well as dynamic page generation; being used in new as dynamic page generation; being used in new ANTLR parser generator for code generationANTLR parser generator for code generation
Distinguishing characteristic: strictly enforces Distinguishing characteristic: strictly enforces separation of model and viewseparation of model and view
Argument for Argument for StringTemplateStringTemplate
Car aerodynamics mostly trumps style todayCar aerodynamics mostly trumps style today Similarly, the nature of generating text should Similarly, the nature of generating text should
dominate design decisions: use an output dominate design decisions: use an output grammargrammar
Don’t have output grammars, we have programs Don’t have output grammars, we have programs with print statements; template engines arose to with print statements; template engines arose to encourage separation of logic/display.encourage separation of logic/display.
Enforcing strict separation also leads to similar Enforcing strict separation also leads to similar grammar-like mechanismgrammar-like mechanism
Conclusion: if you’re generating text, you should Conclusion: if you’re generating text, you should be using something akin to StringTemplatebe using something akin to StringTemplate
Canonical OperationsCanonical Operations
Attribute reference:Attribute reference:<type><type>
Template references (possibly recursive):Template references (possibly recursive):<statementList()><statementList()>
Apply template to multi-valued attribute:Apply template to multi-valued attribute:<decls:decl()><decls:decl()> oror<decls:{<it.type> <it.name>;}><decls:{<it.type> <it.name>;}><items:red(), blue(), green()><items:red(), blue(), green()>
Conditional include:Conditional include:<if(superClass)>extends <superClass><endif><if(superClass)>extends <superClass><endif><if(name)>Name: <name><else>Guest<endif><if(name)>Name: <name><else>Guest<endif>
SemanticsSemantics
Side-effect free expressionsSide-effect free expressions No “state”No “state” No defined order of executionNo defined order of execution Lazy evaluation (Lazy evaluation (crucialcrucial!)!) Dynamically scoped; values inheritedDynamically scoped; values inherited Template inheritance: group to Template inheritance: group to
subgroupsubgroup Recursive template instantiationRecursive template instantiation
Template GroupsTemplate Groups
Set of mutually-referential templates Set of mutually-referential templates with formal argumentswith formal arguments
group javaTemplates;
method(type,name,args,body) ::= <<public <type> <name>( <args:arg(); separator=“,”> ) { <body>}>>assign(lhs,expr) ::= “<lhs> = <expr>;”if(expr,stat) ::= “if (<expr>) <stat>”call(name,args) ::= “<name>( <args; separator=“,”> );”…
Example: Dump Java Example: Dump Java ClassClass
Expected output:Expected output:
class Dump { public int i; public java.lang.String name; public int[] data; public void main(class java.lang.String[] arg1); public void foo(int arg1, float[] arg2); public class java.lang.String bar();}
Dump Java Class Dump Java Class TemplatesTemplatesgroup Java;
class(name,fields,methods) ::= <<class <name> { <fields:field(); separator="\n"> <methods:method(); separator="\n"> >}>>
field() ::= "public <type(t=it.type)> <it.name>;"
method() ::= <<public <it.returnType> <it.name> (<it.parameterTypes:{<type(t=it)> arg<i>}; separator=", ">);>>
type(t) ::= <<<if(t.componentType)><t.componentType>[]<else><t.name><endif>>>
Dump Java Class CodeDump Java Class Codepublic class Dump { public int i; public String name; public int[] data; public static void main(String[] args) throws IOException { StringTemplateGroup group = new StringTemplateGroup(new FileReader("Java.stg"), AngleBracketTemplateLexer.class); Class c = Dump.class; Field[] fields = c.getFields(); Method[] methods = c.getDeclaredMethods(); StringTemplate classST = group.getInstanceOf("class"); classST.setAttribute("name", c.getName()); classST.setAttribute("fields", fields); classST.setAttribute("methods", methods); System.out.println(classST); } public void foo(int x, float[] y) {;} public String bar() {return "";}}
Dump XML InsteadDump XML Insteadgroup XML;
class(name,fields,methods) ::= <<<class> <name>$name$</name> $fields:field()$ $methods:method()$</class>>>
field() ::= <<<field> <type>$type(t=it.type)$</type><name>$it.name$</name></field>>>
…
<class> <name>Dump</name> <field> <type>int</type><name>i</name> </field> …</class>
Sample ANTLR 3.0 Sample ANTLR 3.0 TemplateTemplate
parser(name, tokens, rules, DFAs) ::= <<class <name> extends Parser { <tokens: {public static final int <it.name>=<it.type>;} > public <name>(TokenStream input) { super(input); }
<rules; separator="\n">
<DFAs>}>>
ANTLR 3.0 Error ANTLR 3.0 Error TemplatesTemplates
Internationalization: use a template Internationalization: use a template group for each locale; load group for each locale; load appropriate templatesappropriate templates
RULE_REDEFINITION(file,line,col,arg) ::= "<loc()>rule <arg> redefinition”UNDEFINED_RULE_REF(file,line,col,arg) ::= "<loc()>reference to undefined rule: <arg>”loc() ::= "<file>:<line>:<col>: "
inherits file, line, col attributes from enclosing template
Language TranslationLanguage Translation MVC (parser + “unparser”)MVC (parser + “unparser”)
model -- input stream and/or ASTsmodel -- input stream and/or ASTs view -- templatesview -- templates controller -- parsercontroller -- parser
Controller extracts data from model, provides Controller extracts data from model, provides to view without worrying about details of to view without worrying about details of output structureoutput structure
Maps abstract input concept to output Maps abstract input concept to output concept like concept like assignmentassignment to to assignmentassignment..
Abstract concepts represented by one or more Abstract concepts represented by one or more rules in parser grammar and one or more rules in parser grammar and one or more templates in template filetemplates in template file
Translation grammar+STTranslation grammar+STvariable returns [StringTemplate code=null]{StringTemplate t=null,d=null;} : t=type d=declarator SEMI { if ( currentFunctionName==null ) { code = template("globalVariable"); } else { code = template("variable"); } code.setAttribute("type", t); code.setAttribute("name", d); } ; declarator returns [StringTemplate code=null] : id:ID {code=text(id.getText());} ;
Translation TemplatesTranslation Templates
JavaJavavariable(type,name)::="<type> <name>;”variable(type,name)::="<type> <name>;”globalVariable ::= variableglobalVariable ::= variable
PythonPythonvariable(type,name) ::= " ”variable(type,name) ::= " ”globalVariable ::= variableglobalVariable ::= variable
BytecodesBytecodesvariable(type,name) ::=variable(type,name) ::= ".var is <name> <type>" ".var is <name> <type>" globalVariable(type,name) ::=globalVariable(type,name) ::= ".field <name> <type><\n>" ".field <name> <type><\n>"
SummarySummary The nature of text generation and the enforcement The nature of text generation and the enforcement
of model-view separation dominate tool design-of model-view separation dominate tool design-decisions:decisions: tools should resemble output grammarstools should resemble output grammars
StringTemplate is a simple template engine that StringTemplate is a simple template engine that evolved while building dynamic sites. It is proving evolved while building dynamic sites. It is proving exceptionally well suited to code generation tasks exceptionally well suited to code generation tasks including ANTLR 3.0including ANTLR 3.0
Open-source Java, BSD license (also a C# port; Open-source Java, BSD license (also a C# port; python coming)python coming)
LinksLinks http://www.stringtemplate.orghttp://www.stringtemplate.org http://www.codegeneration.net/tiki-read_article.php?articleId=77http://www.codegeneration.net/tiki-read_article.php?articleId=77