General Information
Tutorials
Reference Manuals
Libraries
Translation Tasks
Tools
Administration
|
Pattern-based Text GeneratorA Complete ExampleIn this chapter we demonstrate the use of PTG for translating a simple assignment language into C code. This example shows PTG techniques in the context of a complete translator specification. It especially demonstrates how PTG patterns are applied in LIDO specifications.
When this manual is read online, the browser's
PtgEx.fw :exe >. or to derive the set of files described below:
PtgEx.fw :fwGen >.
Source Language StructurePrograms of this example language are sequences of assignments, input statements, and output statements, like simple[1]== input a; output a; x := a + 1; y := x - 5; output x; output y + x; This macro is attached to a product file.
The values of variables and expressions are integral numbers.
There are only the binary operators simple.out[2]== #include <stdio.h> int a = 0, x = 0, y = 0; int main (void) { scanf ("%d", &(a)); printf ("%d\n",a); x = a+1; y = x-5; printf ("%d\n",x); printf ("%d\n",y+x); exit (0); } This macro is attached to a product file. The structure of the source programs is specified by the following concrete grammar: Program.con[3]== Program: Statement*. Statement: Variable ':=' Expression ';'. Statement: 'input' Variable ';'. Statement: 'output' Expression ';'. Expression: Expression Operator Operand / Operand. Operator: '+' / '-'. Operand: Variable. Operand: IntLit. Variable: Ident. This macro is attached to a product file.
In the tree grammar Expr.sym[4]== Expression ::= Operand . This macro is attached to a product file.
Identifier tokens, number literals, and comments are denoted as
in Pascal, as stated by the following type Mini.gla[5]== Ident: PASCAL_IDENTIFIER IntLit: PASCAL_INTEGER PASCAL_COMMENT This macro is attached to a product file.
Program FrameIn this section the overall structure of the target programs is specified, the name of the output file is determined, and its contents is produced by a PTG output function. We first specify a pattern for target program frame: Frame.ptg[6]== Frame: "#include <stdio.h>\n\n" $1 /* declarations */ "\nint main (void) {\n\n" $2 /* statements */ "\nexit (0);\n}\n" This macro is attached to a product file.
It has two insertion points, one for variable declarations
and one for the statement sequence.
The text to be inserted is obtained from the attributes
TransProg.lido[7]== ATTR DeclPtg, StmtPtg: PTGNode; SYMBOL Program COMPUTE PTGOutFile (CatStrStr(SRCFILE, ".c"), PTGFrame (THIS.DeclPtg, THIS.StmtPtg)); END; This macro is attached to a product file.
The above call of the output function TransProg.specs[8]== $/Tech/Strings.specs This macro is attached to a product file.
The macro TransProg.head[9]== #include "source.h" This macro is attached to a product file.
ExpressionsIn this section we specify the translation of expressions. Target expressions are composed by applications of patterns that construct the text in a bottom-up way, i.e. from the leaves up to the complete expression. In our simple example this translation is one-to-one as specified by the three patterns: TransExpr.ptg[10]== BinOperation: $ $ $ Number: $ int String: $ string This macro is attached to a product file.
The
These patterns are applied in computations of TransExpr.lido[11]== ATTR Ptg: PTGNode; RULE: Expression ::= Expression Operator Expression COMPUTE Expression[1].Ptg = PTGBinOperation ( Expression[2].Ptg, Operator.Ptg, Expression[3].Ptg); END; RULE: Operator ::= '+' COMPUTE Operator.Ptg = PTGString ("+"); END; RULE: Operator ::= '-' COMPUTE Operator.Ptg = PTGString ("-"); END; RULE: Expression ::= Variable COMPUTE Expression.Ptg = Variable.Ptg; END; RULE: Expression ::= IntLit COMPUTE Expression.Ptg = PTGNumber (IntLit); END; RULE: Variable ::= Ident COMPUTE Variable.Ptg = PTGString (StringTable (Ident)); END; ATTR Sym: int; This macro is attached to a product file.
The last two computations use values obtained from named terminal
symbols:
Using LIDO CHAINs
In this sections the translation of statement sequences is shown.
The LIDO Assignments, input statements, and output statements are translated by the following patterns: TransStmt.ptg[12]== AssignStmt: $1 /* lhs */ " = " $2 /* rhs */ ";\n" InputStmt: "scanf (\"%d\", &(" $1 /* variable */ "));\n" OutPutStmt: "printf (\"%d\\n\"," $1 /* expression */ ");\n" Seq: $ $ This macro is attached to a product file. The last pattern is used to combine two text components (statement sequences in this case) into one (see See Output of Sequences).
A TransStChn.lido[13]== CHAIN StmtChn: PTGNode; SYMBOL Program COMPUTE CHAINSTART HEAD.StmtChn = PTGNULL; SYNT.StmtPtg = TAIL.StmtChn; END; This macro is attached to a product file.
In each of the three statement contexts the translation
is produced by application of the corresponding pattern
and appended to the end of the TransStmt.lido[14]== RULE: Statement ::= Variable ':=' Expression ';' COMPUTE Statement.StmtChn = PTGSeq (Statement.StmtChn, PTGAssignStmt (Variable.Ptg, Expression.Ptg)); END; RULE: Statement ::= 'input' Variable ';' COMPUTE Statement.StmtChn = PTGSeq (Statement.StmtChn, PTGInputStmt (Variable.Ptg)); END; RULE: Statement ::= 'output' Expression ';' COMPUTE Statement.StmtChn = PTGSeq (Statement.StmtChn, PTGOutPutStmt (Expression.Ptg)); END; This macro is attached to a product file.
Using LIDO CONSTITUENTS
In this section the construction of a declarator sequence is
described using the LIDO The source language does not have declarations; variables are introduced by just using them. Hence, we have to generate declarations in the target program, one for each variable that occurs in the source. A variable may occur several times, but its declaration must be generated only once. For that purpose each variable is identified by a key which is associated to every occurrence of the variable.
This task is an instance of a name analysis task. We
can use the ScopeLib.specs[15]== $/Name/AlgScope.gnrc:inst This macro is attached to a product file.
The computational role Scope.lido[16]== SYMBOL Variable INHERITS IdDefScope COMPUTE SYNT.Sym = TERM; END; This macro is attached to a product file.
The computations of that module yield an attribute
We now associate a property Decl.pdl[17]== IsDeclared: int; This macro is attached to a product file.
It describes a state of that variable with respect to the
translation process: A declaration is only produced if
VarDecl.lido[18]== RULE: Variable ::= Ident COMPUTE Variable.DeclPtg = IF (GetIsDeclared (Variable.Key, 0), PTGNULL, ORDER (ResetIsDeclared (Variable.Key, 1), PTGDeclVariable (StringTable (Ident)))); END; This macro is attached to a product file.
The pattern Decl.ptg[19]== DeclVariable: $ string " = 0" Declaration: "int " $ ";\n" This macro is attached to a product file. The second pattern constitutes a complete declaration where the declarator list is inserted.
The declarator list is collected in the ProgDecl.lido[20]== SYMBOL Program COMPUTE SYNT.DeclPtg = PTGDeclaration ( CONSTITUENTS Variable.DeclPtg WITH (PTGNode, PTGCommaSeq, IDENTICAL, PTGNull)); END; This macro is attached to a product file.
The Comma.ptg[21]== CommaSeq: $ {", "} $ This macro is attached to a product file.
|