1 / 15

Programmatic Building of Models Just for Pretty Printing

DSM 2006 22 October 2006 Tero Hasu tero.hasu@hiit.fi Helsinki Institute for Information Technology. Programmatic Building of Models Just for Pretty Printing. Outline. How to generate nicely laid out source code easily? Constructive pretty printing.

calla
Download Presentation

Programmatic Building of Models Just for Pretty Printing

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. DSM 200622 October 2006 Tero Hasutero.hasu@hiit.fiHelsinki Institute for Information Technology Programmatic Building of Models Just for Pretty Printing

  2. Outline How to generate nicely laid out source code easily? • Constructive pretty printing. • qretty – a tool to support constructive pretty printing.

  3. Constructive Pretty Printing • Programmatically construct a model defining what is to be printed – then do a pretty-printing traversal over it. • Models constructed imperatively from objects. • Models concern the domain of prettily printed programs – no extraneous information required. • (Yes, one might want programmatic model building in other domains, too.)

  4. Some Approaches to Pretty Printing Source Code • Have an abstract syntax tree (AST)? • Traverse that. • Don't have one? • Use a template engine. • Or build an AST-like model just so you can traverse it?

  5. Why Build Models Just for Pretty Printing? • To separate the specification of the content from the formatting rules. • when specifying what to print, one can focus on actual content, without needing to worry about indentation, line breaking, delimiters • one gets all formatting rules in one place (in the printing routine), not spread around in templates

  6. Approaches to Constructing Models • Declaratively: Just list model contents in some syntax, with variable value expressions accounting for variability. • model = parse(“... gc.DrawRect(<%= args %>); ...”) • (setq! model (... (call-meth (ident “gc”) “DrawRect” args) ...)) • Imperatively: Write code that builds a model incrementally by adding objects to a tree structure. • meth.Statements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression(“gc”), “DrawRect”, args));

  7. [:person, [:name, "Jim"], [:phone, "5551234"]] p = Person.newp.name = "Jim"p.phone = "5551234" Possible Reasons for Building Models Imperatively • Many currently popular languages lack sufficiently nice list syntax, but have concise syntax for manipulating objects. • Named object properties and their accessors make it easy to manipulate models, allowing one to • build a model in any convenient order • build a model incrementally, in multiple passes

  8. What Information to Include in a Model? • Less information to include generally means less work in building a model – best to have as little as possible • Must know enough about an object to print it correctly... • ...but not necessarily full target language semantics • (If an open-ended set of target languages must be supported, full language semantics required.) • Any two objects that can be printed in the same way can be added to the model in the same way; no need to specify that different treatment is required (say by using a different setter method)

  9. xm.div { xm.br } <div> <br/></div> What Kind of API to Use for Model Building? • General-purpose vs. domain-specific API? • General purpose APIs are tedious to use • Specializing the API by hand for a domain is one solution (e.g. Ruby's Builder for Markup for generating XML) • Better way: Generate the API for each domain from a grammar

  10. Introducing: qretty • A Ruby library • Supports constructive pretty printing by automating some of the implementation • takes an annotated grammar as input • produces a grammar-specific class hierarchy (for model building) and associated pretty-printing routines • http://pdis.hiit.fi/s4all/download/qretty/

  11. qretty Grammar Specifications • Must explicitly specify which non-terminals require a class • Hints influencing API generation can be included • Hints influencing pretty printing can be included

  12. Example Grammar Specification • class ExampleGrammar include Qretty::Dsl def initialize crule(:program, :exprs) arule(:exprs, opt(seplist(:expr, nl))) # all exprs go to same property to preserve order mfield(:expr, :pname => :@list) arule(:expr, choice(:call_expr, :if_expr)) crule(:call_expr, seq(ident(:func), "()")) # CallExpr ctor's first argument is function name cfield(:func) crule(:if_expr, seq("if ", :cond, " then", nl, indent(:exprs), nl, "end")) # condition is an instance of CallExpr mfield(:cond, :cname => :call_expr) finalize_grammar endend

  13. OpenWindow()DisplayGreeting()if IsNewUser() then DisplayHelp() CreateAccount()endMakeVisible() Model Building Example • model = ast::Program.newmodel.call_expr "OpenWindow"model.call_expr "DisplayGreeting"if0 = model.if_expr do |if0| if0.cond "IsNewUser" if0.call_expr "DisplayHelp"endmodel.call_expr "MakeVisible"unless $no_database if0.call_expr "CreateAccount"end

  14. qretty Evaluation • Implementation works, but could use redesign and more speed • Large existing grammars hard to adapt (e.g. C++) • hard to come up with memorable naming • a lot of work to make class hierarchy shallow enough • grammar specification language imperfections • Suggested feature: allow more declarative model building where convenient • program(call_expr(“OpenWindow”), call_expr(“DisplayGreeting”), ...)

  15. Summary • One approach to pretty printing in program generation: Construct a model, then print it • Benefits include: separation of concerns (what and how to print); model build order may differ from printing order • qretty helps by generating a model building API and a pretty printer based on an annotated grammar • Usable model building API is key, but API design is not easy – even with qretty

More Related