Eli   Documents

General Information

 o Eli: Translator Construction Made Easy
 o Global Index
 o Frequently Asked Questions
 o Typical Eli Usage Errors

Tutorials

 o Quick Reference Card
 o Guide For new Eli Users
 o Release Notes of Eli
 o Tutorial on Name Analysis
 o Tutorial on Scope Graphs
 o Tutorial on Type Analysis
 o Typical Eli Usage Errors

Reference Manuals

 o User Interface
 o Eli products and parameters
 o LIDO Reference Manual
 o Typical Eli Usage Errors

Libraries

 o Eli library routines
 o Specification Module Library

Translation Tasks

 o Lexical analysis specification
 o Syntactic Analysis Manual
 o Computation in Trees

Tools

 o LIGA Control Language
 o Debugging Information for LIDO
 o Graphical ORder TOol

 o FunnelWeb User's Manual

 o Pattern-based Text Generator
 o Property Definition Language
 o Operator Identification Language
 o Tree Grammar Specification Language
 o Command Line Processing
 o COLA Options Reference Manual

 o Generating Unparsing Code

 o Monitoring a Processor's Execution

Administration

 o System Administration Guide

Mail Home

Abstract Syntax Tree Unparsing

Next Chapter Table of Contents


Using an Unparser

In order to make the discussion concrete, we will use a trivial expression language as an example. That language is defined by the FunnelWeb file `example.fw':

@O@<example.lido@>==@{
RULE PlusExp: Expression ::=    Expression '+' Expression    END;
RULE StarExp: Expression ::=    Expression '*' Expression    END;
RULE Parens:  Expression ::=    '(' Expression ')'           END;
RULE IdnExp:  Expression ::=    Identifier                   END;
RULE IntExp:  Expression ::=    Integer                      END;

RULE CallExp: Expression ::=    Identifier '(' Arguments ')' END;
RULE ArgList: Arguments  LISTOF Expression                   END;
@}

@O@<example.gla@>==@{
Identifier: C_IDENTIFIER
Integer:    C_INT_DENOTATION
@}

@O@<example.con@>==@{
Axiom: Expression .
Expression: Expression '+' Term / Term .
Term: Term '*' Factor / Factor .
Factor: 
  Identifier / 
  Integer / 
  Identifier '(' Arguments ')' /
  '(' Expression ')' .
Arguments: Expression // ',' .
@}

@O@<example.map@>==@{
MAPSYM
Expression ::= Term Factor .
@}

The non-literal terminal symbols Integer and Identifier are defined by canned descriptions. According to their definitions (see Available Descriptions of Lexical Analysis), C_IDENTIFIER uses the token processor mkidn to establish the internal value of the terminal symbol, and C_INT_DENOTATION uses mkstr.

The concrete grammar and mapping specification together provide three precedence levels of Expression (Expression, Term and Factor) to disambiguate the dyadic computation rules. Parentheses can be used to override the defined precedence and association, and their presence is reflected in the tree.

Finally, the concrete grammar specifies the comma as the argument separator in procedure calls. This fact is not, however, explicit in the tree.

How could a pretty-printer for this language be constructed? Eli is capable of generating an unparser specification from the FunnelWeb file given above. That specification is, itself, a FunnelWeb file. These two FunnelWeb files, plus some additional information, provide a complete definition of the pretty-printer. Suppose that the additional information will be provided by a FunnelWeb file `Add.fw'. Here is a type-`specs' file that will define the pretty-printer:

example.fw
example.fw :idem
Add.fw

The first line describes the file defining the language, the second describes the textual unparser derived from the language definition (see Deriving an Unparser), and the last describes the file defining the additional information. A processor is derived from this type-`specs' file in the usual way (see exe -- Executable Version of the Processor of Products and Parameters Reference).

`Add.fw' must specify three additional pieces of information to complete the pretty-printer:

  • The formatting strategy.
  • Which node of the tree to print.
  • The argument list separators.

Our sample language involves only expressions, so the formatting strategy can be specified by instantiating a library module used to format C programs:

$/Output/C_Separator.fw

The generated unparser specification establishes a type-PTGNode value for the IdemPtg attribute of each of the tree nodes. Because this value was created with the help of the library module defined by `C_Separator.fw' it should be written to the standard output stream by applying the routine Sep_Out to it:

SYMBOL Axiom COMPUTE Sep_Out(THIS.IdemPtg); END;

Finally, we can ensure that commas separate the arguments by overriding the generated IdemPtg computation for the argument list. The complete FunnelWeb file `Add.fw' would be:

@O@<Add.specs@>==@{
$/Output/C_Separator.fw
@}

@O@<Add.lido@>==@{
SYMBOL Axiom COMPUTE Sep_Out(THIS.IdemPtg); END;

RULE: Arguments LISTOF Expression
COMPUTE
  Arguments.IdemPtg=
    CONSTITUENTS Expression.IdemPtg SHIELD Expression
      WITH (PTGNode, PTGArgSep, IDENTICAL, PTGNull);
END;
@}

@O@<Add.ptg@>==@{
ArgSep: $ { "," [Separator] } $
@}

The [Separator] function call insertion in the pattern allows the module defined by `C_Separator.fw' to provide appropriate layout characters between the elements of an expression to implement the desired formatting.


Next Chapter Table of Contents