Introduction
Pretty-print tables are used to specify how language constructs have to be pretty-printed and are used in combination with
GenericPrettyPrinter front-ends. Pretty-print tables use
Box as language to specify formatting of language constructs. A pretty-print table contains mappings from constructor names of SDF language productions to
Box expressions.
For example, for the SDF production
f ( A ) -> B {cons("f")}
A pretty-print entry looks like:
f -- H [ "f" "(" _1 ")" ]
Pretty-print tables are ordered such that pretty-print rules occuring first take preceedence over overlapping pretty-print rules defined later. The syntax of pretty-print tables is available in the online Sdf.Trash.GrammarBase.
Rule Selectors
To be able to specify formattings for all nested constructs that are allowed in SDF productions, so called
selectors are used in pretty-print tables to refer to specific parts of an SDF production and to define a formatting for them. For example, the SDF prodcution
f ( A? ) -> B {cons("f")}
contains a nested symbol A?. To specify a formatting for this production, two pretty-print entries can be used:
f -- H [ "f" "(" _1 ")" ]
f.1:opt -- H [_1]
A selector consists of a constructor name followed by a list of number+type tuples. A number selects a particular subtree of an SDF construct, the type denotes the type of the selected construct (sequence, optional, separator list etc.). This rather verbose selector mechanism allows unambiguous selection of subtrees of SDF productions. Its verbosity (by specifying both the number of a subtree and its type), makes pretty-print tables easier to understand and, more importantly, it enables pretty-printing of AST's, because with type information, a concrete term can be correctly recontructed from an AST. Pretty-print tables can thus be used for both formatting of parse-trees
and AST's.
Below we summarize which selector types are available:
- opt
- For SDF optionals (S?).
- iter
- For non-empty SDF lists (S+).
- iter-star
- For possible empty SDF lists (S*).
- iter-sep
- For SDF separator lists ( {S_1 S_2}+). Observe that the symbol S_1 and the separator S_2 are ordinary subtrees of the iter-sep construct which can be refered to as first and second subtree, respectively.
- iter-star-sep
- For SDF separator lists ( {S_1 S_2}*). Its symbol and separator can be refered to as first and second sub tree.
- alt
- For SDF alternatives (A_1 | A_2 |A_3). According to the SDF syntax, alternatives are binary operators. The pretty-printer flattens all subsequent alternatives. Pretty-print rules can be specified for each alternative individually by specifying the number of each alternative. To be able to format literals in alternative, a special formatting rule can be defined for the construct (See the examples below).
- seq
- For SDF sequences ( (S_1 S_2 S_3) ).
Examples
Below we list a simple SDF module with productions containing all above constructs:
module Symbols
exports
context-free syntax
A? -> S {cons("ex1")}
A+ -> S {cons("ex2")}
A* -> S {cons("ex3")}
{S1 S2}+ -> S {cons("ex4")}
{S1 S2}* -> S {cons("ex5")}
"one" | "two" | S? -> S {cons("ex6")}
("one" "two" S? ) -> S {cons("ex7")}
The following pretty-print table shows which pretty-print rules can be defined for this syntax:
[
ex1 -- _1,
ex1.1:opt -- _1,
ex2 -- _1,
ex2.1:iter -- _1,
ex3 -- _1,
ex3.1:iter-star -- _1,
ex4 -- _1,
ex4.1:iter-sep -- _1 _2,
ex5 -- _1,
ex5.1:iter-star-sep -- _1 _2,
ex6 -- _1,
ex6.1:alt -- KW["one"] KW["two"] _1,
ex6.1:alt.1:opt -- _1,
ex7 -- _1,
ex7.1:seq -- KW["one"] KW["two"] _1,
ex7.1:seq.1:opt -- _1
]
The pretty-print rule 'ex6.1:alt' is a special case. It contains three
Box expressions, one for each alternative. It is used to specify a formatting for the non-nested literals "one" and "two". During pretty-printing one of the three BOX expressions is selected, depending on alternative contained the term to format.
Pretty-Print Table Generation
Pretty-print tables can be generated from SDF syntax definitions (see
ppgen?). Generated pretty-print rules can easiliy be customized by overruling them in additional pretty-print tables. The tool
pptable-diff notifies inconsistensies in pretty-print tables after the syntax definition has changed and can be used to brin inconsistent table up-to-date.
See Also
GenericPrettyPrinter,
asfix2abox,
ast2aboox?,
ppgen?,
pptable-diff