|
![]() |
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.
|