next up previous Project Oscar

Next: Appel des grammaires attribuées Up: Exemple d'utilisation du système

Previous: Ecriture des grammaires attribuées

Ecriture des grammaires attribuées pour la production de code cible

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.



Web page maintained by Didier Parigot
Tue Aug 18 11:42:13 MET DST 1998