17
StringTemplate StringTemplate Terence Parr Terence Parr University of San University of San Francisco Francisco parrt parrt @cs. @cs. usfca usfca .edu .edu

StringTemplate Terence Parr University of San Francisco [email protected]

Embed Size (px)

Citation preview

Page 1: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

StringTemplateStringTemplate

Terence ParrTerence Parr

University of San FranciscoUniversity of San Francisco

parrtparrt@[email protected]

Page 2: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

OutlineOutline

What is StringTemplateWhat is StringTemplate OperationsOperations SemanticsSemantics Example Java/XML GenerationExample Java/XML Generation ANTLR 3.0 templateANTLR 3.0 template

Page 3: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

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

Page 4: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

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

Page 5: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

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>

Page 6: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

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

Page 7: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

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=“,”> );”…

Page 8: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

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();}

Page 9: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

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>>>

Page 10: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

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 "";}}

Page 11: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

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>

Page 12: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

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>}>>

Page 13: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

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

Page 14: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

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

Page 15: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

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());} ;

Page 16: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

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>"

Page 17: StringTemplate Terence Parr University of San Francisco parrt@cs.usfca.edu

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