Eli   Documents Get Eli: Translator Construction Made Easy at SourceForge.net.
    Fast, secure and Free Open Source software downloads

General Information

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


 o Quick Reference Card
 o Guide For new Eli Users
 o Release Notes of Eli
 o Tutorial on Name Analysis
 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


 o Eli library routines
 o Specification Module Library

Translation Tasks

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


 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


 o System Administration Guide

Mail Home

Pattern-based Text Generator

Previous Chapter Next Chapter Table of Contents

Influencing PTG Output

The usage of PTG Patterns functions is a very flexible way to construct the output of a program. However, some desirable effects can not be achieved using pattern functions only:

Pretty Printing
A pattern function does not have access to the current column position. Therefore, it cannot know where to insert line breaks to get the output formatted properly.
Output destination
It can be desirable to write the output of PTG patterns to a destination other than a file, for example to redirect the output into a string buffer or to postprocess the output through a filter.

To solve such tasks, PTG does not write its output directly into a file. Instead, a set of macros is defined that can be adjusted to change the behavior of PTG. If these macros are not defined, PTG supports default definitions that process the contents of a PTGNode into a named file or a given file pointer. In the following, those macros are explained and small examples are given:

This macro defines the type name of the file parameter of the other macros, the output functions defined in Output Functions, and the function call insertions. If no definition is supplied, its value is defined to be FILE *. Its value must be assignable by the C-operator =. If the definition of PTG_OUTPUT_FILE is changed, a suitable definition for PTG_OUTPUT_STRING must also be provided.

This macro is called to write a string value into an output file. It is used by default for every text written by PTG. Hence, redefining this macro suffices to change the default behavior of PTG, for instance to support pretty printing. This macro has to be redefined if PTG_OUTPUT_FILE is redefined.

These macros are used to write typed insertions into an output file. By default, they are set up in a way that they convert their second argument into a string and call PTG_OUTPUT_STRING to process the output. So, when redefining PTG_OUTPUT_FILE, you need not to supply a definition for these macros.

Of course, there may be more efficient ways to output values of the various data types other than to convert them into strings and send the result to the string handling function. If you want to supply such an alternative for writing characters, for example, redefine the default behavior of PTG_OUTPUT_CHAR to print the character directly. These macros are provided for efficiency purposes only.

To override the default implementations for these macros, implement a substitution function in a type .c file. Include the file ptg_gen.h to supply your new function with definitions for the other macros, especially PTG_OUTPUT_FILE. Write cpp directives that define the desired macro(s) into a type .ptg.phi file and include it in your specification. Eli will then concatenate all those definitions and supply it as a header file ptg.h to your processor.

As an application of these macros, the following section shows a simple and easy way to implement pretty printing of the output generated by PTG.

Changing Default Output for Limited Line Length

Sometimes it is necessary to postprocess PTG generated output. For example, the length of the generated output lines may be limited by an upper bound, so that certain restricted tools can process the output. Without postprocessing of the output, there is no way to determine the current position in a line for a PTG structure being written. Hence, we adapt the definitions of the output macros to solve that task.

As all output is finally handled by the macro PTG_OUTPUT_STRING, it is sufficient to modify it such that it controls the current position in the line. With some more effort, it would be possible do complete line breaking by buffering one line of output and looking for suitable break points when the end of the line is encountered.

The following code keeps track of the current column position and implements a function, that conditionally inserts a line break if the line is longer than 65 chars.


#include <string.h>
#include "ptg_gen.h"
static col = 0;

void InitCol(void)
   col = 0;

void OutputLine(FILE *f, char *s)
   int l;
   char *nl;

   if (!s) return;

   l = strlen(s);
   nl = strrchr(s, '\n');

   if (!nl)
      col += l;
      col = (l - 1 - (nl - s)); 
   fputs(s, f);

void CondNl(FILE *f)
   if (col > 65)
      OutputLine(f, "\n");
This macro is attached to a product file.

The function InitCol serves as initialization, if more than one output file should be generated. The function CondNl inserts a line break, if the current line is longer than 65 characters. The function OutputLine overrides the default implementation of PTG_OUTPUT_STRING.


#define PTG_OUTPUT_STRING(file,param) OutputLine(file,param)
This macro is attached to a product file.

This can be used for example in the following PTG specification:


CommaSeq:       $ ", " [CondNl] $
This macro is attached to a product file.

Now, in a large iteration of calls to PTGCommaSeq(), a line break is inserted automatically, if a line exceeds 65 characters.

Using the online documentation, one can obtain a copy of the attached files.

Previous Chapter Next Chapter Table of Contents