Project Oscar |
Previous: Ecriture des grammaires attribuées
Pour la production de code intermédiaire, nous avons besoin de décrire :
Les trois descriptions précédentes se trouvent respectivement, dans les fichiers simproc-adt.asx, ag_simproc-term.olga (avec son fichier de déclaration dec_simproc-term.olga) et simproc-ppat.ppat.
Nous donnons la description de ces fichiers ci-dessous.
grammar simproc-adt is from simproc-types import all {Table de symboles} ; root is Program ; Program = Execute ; Execute -> Procid Block ; Block = Concat ; Concat -> Decl-source-modifs Stmt-source-modifs ; Decl-source-modifs = Decl-concat ; Decl-concat -> Decl-source-modif* ; Decl-source-modif = Procdecl Intdecl Arraydecl ; Stmt-source-modifs = Stmt-concat ; Stmt-concat -> Stmt-source-modif* ; Stmt-source-modif = Assignint Assignvar Condit Proccall ; Assignint -> Var Int ; Assignvar -> Refvar Int ; Condit -> Int Int Stmt-source-modifs Stmt-source-modifs ; Proccall -> Procid Int Var Procid ; Procdecl -> Procid Varid Refid Procid Block ; Intdecl -> Varid Procid ; Arraydecl -> Arrayid Int Procid ; Call = Currentcall ; Currentcall -> ; {Identificateurs} {===============} Varid = VarId ; VarId -> ; Refid = RefId ; RefId -> ; Arrayid = ArrayId ; ArrayId -> ; Procid = ProcId ; ProcId -> ; {Variables} {=========} Var = Designates Refersto Element ; Designates -> Varid Call ; Refersto -> Refvar ; Element -> Arrayid Call Int ; Refvar = Refdesignates ; Refdesignates -> Refid Call ; {Entiers} {=======} Int = Plus Difference Times Quotient Valueof Const ; Plus -> Int Int ; Difference -> Int Int ; Times -> Int Int ; Quotient -> Int Int ; Valueof -> Var ; Const -> ; {Attributs attachés à l'arbre de sortie} {======================================} $Value-att (Int) : token ; $Id (Varid, Refid, Arrayid, Procid, Var) : token ; $block-table(Block) : symbol-table ; end grammar ;
attribute grammar simproc-term (simproc-out in PROGRAM) : ($Program: Program) is from simproc-types import all ; const Prog := "Prog" ; attribute {Pour la construction de l'arbre en sorti} {========================================} synthesized $Block-model (BLOCK) : Block ; synthesized $Decl-models (DECLS) : Decl-source-modifs ; synthesized $Stmt-models (STMTS) : Stmt-source-modifs ; synthesized $Decl-model (DECL) : Decl-source-modif ; synthesized $Stmt-model (STMT) : Stmt-source-modif ; synthesized $Address (VAR) : Var ; synthesized $Value (EXPR) : Int ; inherited $procid (BLOCK) : token { name of enclosing proc } ; global $symbtab-term (BLOCK) : symbol-table ; {Les regles sémantiques} {======================} {Programme et blocs} {==================} where program -> BLOCK use $Program := Execute (ProcId () with $Id := token (Prog) end with, $Block-model (BLOCK)) ; $procid (BLOCK) := token (Prog) ; $symbtab-term (BLOCK) := $symtab (BLOCK) ; end where ; where null-PROGRAM -> use $Program := null-Program () ; end where ; where block -> DECLS STMTS use $Block-model := Concat ($Decl-models (DECLS), $Stmt-models (STMTS)) with $block-table := $symbtab-term (block) end with ; end where ; where null-BLOCK -> use $Block-model := null-Block () with $block-table := empty-table end with ; end where ; {Déclarations} {============} where decls -> DECL* use $Decl-models := map left Decl-concat-post value Decl-concat () other $Decl-model (DECL) end map ; end where ; where null-DECLS -> use $Decl-models := null-Decl-source-modifs () ; end where ; where null-STMTS -> use $Stmt-models := null-Stmt-source-modifs () ; end where ; where int-decl -> ID use $Decl-model := Intdecl (VarId () with $Id := $id (ID) end with, ProcId () with $Id := $procid [BLOCK] end with) ; end where ; where array-decl -> ID NUMBER use $Decl-model := Arraydecl (ArrayId () with $Id := $id (ID) end with, $Value (NUMBER), ProcId () with $Id := $procid [BLOCK] end with) ; end where ; where proc-decl -> ID1 ID2 ID3 BLOCK use $symbtab-term (BLOCK) := $symtab (BLOCK) ; $Decl-model := Procdecl (ProcId () with $Id := $id (ID1) end with, VarId () with $Id := $id (ID2) end with, RefId () with $Id := $id (ID3) end with, ProcId () with $Id := $procid [BLOCK] end with, $Block-model (BLOCK)) ; $procid (BLOCK) := $id (ID1) ; end where ; where null-DECL -> use $Decl-model := null-Decl-source-modif () ; end where ; {Instructions} {============} where stmt-list -> STMT+ use $Stmt-models := map left Stmt-concat-post value Stmt-concat () other $Stmt-model (STMT) end map ; end where ; where assign -> VAR EXPR use $Stmt-model := case $Address (VAR) is Refersto (Refdesignates (X,Y)) : Assignint ($Address (VAR), $Value (EXPR)) ; other : Assignint ($Address (VAR), $Value (EXPR)) ; end case ; end where ; where ifthenelse -> EXPR1 EXPR2 STMTS1 STMTS2 use $Stmt-model := Condit ($Value (EXPR1), $Value (EXPR2), $Stmt-models (STMTS1), $Stmt-models (STMTS2)) ; end where ; where call -> ID EXPR VAR use $Stmt-model := Proccall (ProcId () with $Id := $id (ID) end with, $Value (EXPR), $Address (VAR), ProcId () with $Id := $procid [BLOCK] end with) ; end where ; where null-STMT -> use $Stmt-model := null-Stmt-source-modif () ; end where ; {Expressions et operateurs} {=========================} where bin-expr -> OP EXPR1 EXPR2 use $Value := case $op (OP) is addition : Plus ($Value (EXPR1), $Value (EXPR2)) with $Value-att := token (string (0)) end with ; subtraction : Difference ($Value (EXPR1), $Value (EXPR2)) with $Value-att := token (string (0)) end with ; multiplication : Times ($Value (EXPR1), $Value (EXPR2)) with $Value-att := token (string (0)) end with ; division : Quotient ($Value (EXPR1), $Value (EXPR2)) with $Value-att := token (string (0)) end with ; other : null-Int () with $Value-att := token (string (0)) end with ; end case ; end where ; where used-var -> VAR use $Value := Valueof ($Address (VAR)) with $Value-att := token (string (0)) end with ; end where ; where null-EXPR -> use $Value := Const () with $Value-att := token (string (0)) end with ; end where ; {Variables} {=========} where null-VAR -> use $Address := null-Var () with $Id := error-token end with ; end where ; where simple-var -> ID use $Address := let id : token := $id (ID) in case lookup (id, $symbtab-term [BLOCK]) is refid : Refersto (Refdesignates (RefId () with $Id := id end with, Currentcall ())) with $Id := id end with ; other : Designates (VarId () with $Id := id end with, Currentcall ()) with $Id := id end with ; end case ; end where ; where indexed-var -> ID EXPR use $Address := Element (ArrayId () with $Id := $id (ID) end with, Currentcall (), $Value (EXPR)) with $Id := $id (ID) end with ; end where ; {Nombres} {=======} where number -> use $Value := Const () with $Value-att := $value end with ; end where ; where null-NUMBER -> use $Value := null-Int () with $Value-att := token (string (0)) end with ; end where ; end grammar ;
Le module de déclaration correspondant à la grammaire précedente est donné ci-dessous.
declaration module simproc-term is from simproc-types import all ; import grammar simproc-in; import grammar simproc-adt; function simproc-term (r:PROGRAM) : Program; end module;
Enfin, la dernière spécification concerne la décompilation de l'arbre attribué crée par la grammaire précédente. Elle est listée ci-après.
ppat simproc-ppat ( simproc-adt ) ; from simproc-types import all ; separator <h1> = <h 1> ; <h0> = <h 0> ; <v00> = <v 0 , 0> ; <v01> = <v 0 , 1> ; <v04> = <v 0 , 4> ; <v40> = <v 4 , 0> ; <v20> = <v 2 , 0> ; <hov100> = <hov 1 , 0 , 0> ; {- -------------------------------------------------------------------- -} {- Programme -} {- --------------------------------------------------------------------- -} where null-Program -> pprint end where ; where Execute -> Procid Block pprint [v00 "Execute" Procid Block] end where ; {- --------------------------------------------------------------------- -} {- Bloc -} {- --------------------------------------------------------------------- -} where null-Block -> pprint end where ; where Concat -> Decl-source-modifs Stmt-source-modifs pprint [v40 "Decl" Decl-source-modifs "Stmt" Stmt-source-modifs] end where ; {- --------------------------------------------------------------------- -} {- Decl-source-modifs -} {- --------------------------------------------------------------------- -} where null-Decl-source-modifs -> pprint end where ; where Decl-concat -> Decl-source-modif * pprint pplist left global v00 subbox Decl-source-modif end pplist end where ; {- --------------------------------------------------------------------- -} {- Decl-source-modif -} {- --------------------------------------------------------------------- -} where null-Decl-source-modif -> pprint end where ; {- --------------------------------------------------------------------- -} {- Stmt-source-modifs -} {- --------------------------------------------------------------------- -} where null-Stmt-source-modifs -> pprint end where ; where Stmt-concat -> Stmt-source-modif * pprint pplist left global v00 subbox Stmt-source-modif end pplist end where ; {- --------------------------------------------------------------------- -} {- Stmt-source-modif -} {- --------------------------------------------------------------------- -} where null-Stmt-source-modif -> pprint end where ; where Assignint -> Var Int pprint [h1 "Assignint" Var Int] end where ; where Assignvar -> Refvar Int pprint [h1 "Assignvar" Refvar Int] end where ; where Condit -> Int1 Int2 Stmt-source-modifs1 Stmt-source-modifs2 pprint [v00 [h1 "Condit" Int1 Int2] [h1 "Then" Stmt-source-modifs1] [h1 "Else" Stmt-source-modifs2] ] end where ; where Proccall -> Procid1 Int Var Procid2 pprint [h1 "Call" Procid1 Int Var Procid2] end where ; where Procdecl -> Procid1 Varid Refid Procid2 Block pprint [v00 [h1 "Procdecl" Procid1 Varid Refid Procid2] Block "EndProddecl" ] end where ; where Intdecl -> Varid Procid pprint [h1 "Intdecl" Varid Procid] end where ; where Arraydecl -> Arrayid Int Procid pprint [h1 "Arraydecl" Arrayid Int Procid] end where ; {- --------------------------------------------------------------------- -} {- Call -} {- --------------------------------------------------------------------- -} where null-Call -> pprint end where ; where Currentcall -> pprint end where ; {- --------------------------------------------------------------------- -} {- Varid -} {- --------------------------------------------------------------------- -} where null-Varid -> pprint end where ; where VarId -> pprint $Id end where ; {- --------------------------------------------------------------------- -} {- Refid -} {- --------------------------------------------------------------------- -} where null-Refid -> pprint end where ; where RefId -> pprint $Id end where ; {- --------------------------------------------------------------------- -} {- Arrayid -} {- --------------------------------------------------------------------- -} where null-Arrayid -> pprint end where ; where ArrayId -> pprint $Id end where ; {- --------------------------------------------------------------------- -} {- Procid -} {- --------------------------------------------------------------------- -} where null-Procid -> pprint end where ; where ProcId -> pprint $Id end where ; {- --------------------------------------------------------------------- -} {- Var -} {- --------------------------------------------------------------------- -} where null-Var -> pprint end where ; where Designates -> Varid Call pprint [h1 "Designates" Varid Call] end where ; where Refersto -> Refvar pprint [h1 "Refersto" Refvar] end where ; where Element -> Arrayid Call Int pprint [h1 "Element" Arrayid Call Int] end where ; {- --------------------------------------------------------------------- -} {- Refvar -} {- --------------------------------------------------------------------- -} where null-Refvar -> pprint end where ; where Refdesignates -> Refid Call pprint [h1 "Refdesignates" Refid Call] end where ; {- --------------------------------------------------------------------- -} {- Int -} {- --------------------------------------------------------------------- -} where null-Int -> pprint end where ; where Plus -> Int1 Int2 pprint [h1 "Plus" Int1 Int2] end where ; where Difference -> Int1 Int2 pprint [h1 "Difference" Int1 Int2] end where ; where Times -> Int1 Int2 pprint [h1 "Times" Int1 Int2] end where ; where Quotient -> Int1 Int2 pprint [h1 "Quotient" Int1 Int2] end where ; where Valueof -> Var pprint Var end where ; where Const -> pprint $Value-att end where ; end ppat ;
Comme nous l'avons fait à la fin des descriptions de sémantique statique, nous pouvons soumettre nos spécifications au système SYNTAX/FNC-2.