1 PtiLoo Compléments de Cours pour réaliser les Extensions version 20/08/ :51 Ajout à faire pour version 20/08/ :51 n "animation" pour passe1(AST) et passe 2(resolve-name) avec: double déclaration (err passe 1) non déclaration ou erreur de type (err passe 2) n comparaison entre: instruction et exp (AST only) bloc (AST + portée) declaration (AST + TS) méthode, classe (AST + TS + portée)
Transparent 2 ratio.loo (1) extern int printf (string,...); class rational { int num, denom; rational (int n, int d) { num = n; denom = d; } void print (string s) { printf ("%s = %d / %d\n", s, num, denom); } rational add (rational o) { rational r; r = new rational (num * o.denom + o.num * denom, denom * o.denom); return r; }
Transparent 3 ratio.loo (2) class safe_rat extends rational { bool ok; safe_rat (int n, int d) { super (n, d); if (d == 0) { n = 0; ok = false; } else ok = true; } rational add (rational o) { rational r; if (ok) r = super.add (o); else r = new safe_rat (0, 0); return r; } safe_rat safe_add (safe_rat o) { safe_rat r; if (ok && o.ok) r = new safe_rat (num * o.denom + o.num * denom, denom * o.denom); else r = new safe_rat (0, 0); return r; }
Transparent 4 ratio.loo (3) main () { rational r1, r2, r3, r4, r5; r1 = new rational (1, 2); r2 = new rational (1, 4); r3 = new rational (1, 8); r4 = r3.add (r2.add (r1.add (new rational (1, 16)))); r5 = r3.add (r2).add (r1).add (new rational (1, 16)); r1.print ("r1"); r2.print ("r2"); r3.print ("r3"); r4.print ("r4"); r5.print ("r5"); safe_rat s1, s2, s3, s4, s5; s1 = new safe_rat (1, 0); s2 = new safe_rat (3, 4); s3 = new safe_rat (1, s4 = s2.safe_add (s3); s5 = s1.safe_add (s3); s1.print ("s1"); s2.print ("s2"); s3.print ("s3"); s4.print ("s4"); s5.print ("s5"); r5 = s2.add (r1); r5.print ("r5"); r5 = s2.safe_add (s1); r5.print ("r5"); r5 = s2.add (s1); r5.print ("r5"); r2 = s2; r3 = r2.add (s3); r3.print ("r3"); r1 = s1; r4 = r1.add (s4); r4.print ("r4"); // division par 0 printf ("%s %s\n", r5.type_name (), s5.type_name ()); }
Transparent 5 ptiloo.cc try { symbol_table.init(); yyparse (); if (!errors) { cerr << "analyse lexico-syntaxique et declarations OK\n"; for (ClassList::const_iterator p = classes.begin(); p != classes.end(); ++p) (*p)->analyse () ; main_function->analyse (); if (! errors) cerr << "analyse semantique OK\n"; // production du code C cout \n"; if (!externals.empty()) { cout << "\n/*********** definition des fonctions externes ************/\n\n"; for (ExternalList::const_iterator p = externals.begin (); p != externals.end(); ++p) (*p)->produce_declaration(); } for (ClassList::const_iterator p = classes.begin (); p != classes.end(); ++p) (*p)->produce_definition (); cout << "\n/*********************************************************/\n\n"; main_function->produce_definition (); cerr << "production de code OK\n"; } else { res = 1; cerr << "erreurs a la compilation, code non produit\n"; }
6 PtiLoo PROLOGUE version 20/08/ :51
Transparent 7 ptiloo.cc ("shunté" pour le Prologue) try { // **** symbol_table.init(); yyparse (); if (!errors) { cerr << "analyse lexico-syntaxique et declarations OK\n"; *** Shunt PFZ for (ClassList::const_iterator p = classes.begin(); p != classes.end(); ++p) (*p)->analyse () ; main_function->analyse (); if (! errors) cerr << "analyse semantique OK\n"; // production du code C cout \n"; if (!externals.empty()) { cout << "\n/*********** definition des fonctions externes ************/\n\n"; for (ExternalList::const_iterator p = externals.begin (); p != externals.end(); ++p) (*p)->produce_declaration(); } for (ClassList::const_iterator p = classes.begin (); p != classes.end(); ++p) (*p)->produce_definition (); cout << "\n/*********************************************************/\n\n"; main_function->produce_definition (); cerr << "production de code OK\n"; } / **** Shunt PFZ ***/ else { res = 1; cerr << "erreurs a la compilation, code non produit\n"; }
Transparent 8.loo vers SA en XML + CSS + DTD Essais/*.loo Essais/*.xml Essais/mainLoo.css Essais/looSA.dtd. ratio.xml ratio.loo mainLoo.css looSA.dtd
9 PtiLoo Extensions version 20/08/ :51
26/11/2007 Nom: Prénom: Groupe: PtiLoo - Ext # yacc(I) lex entity.h expr.h stat.h yacc(II) _ana.cc _pro.cc run- time.h
Transparent 11 E#0 : simple.loo => simple.c main () { int x; int y; x = 1; // pas d'initialisation int x = 1 pour l'instant y = 2; int z; int t; z = 3; t = 4; printf ("%d %d %d %d\n", x, y, z, t); if (t - z == y - x) { // int t interdit car double le t global int q; int r; q = t - y; r = z - x; printf ("%d %d\n", q, r); } int q; int r; // autorise car ne doublent pas les q et r précédents q = t + x; r = y + z; printf ("%d %d\n", q, r); } int main () { int x = 0; int y = 0; int z = 0; int t = 0; int q = 0; int r = 0; x = 1; y = 2; z = 3; t = 4; printf ("%d %d %d %d\n", x, y, z, t); if (t - z == y - x) { int q = 0; int r = 0; q = t - y; r = z - x; printf ("%d %d\n", q, r); } q = t + x; r = y + z; printf ("%d %d\n", q, r); }
12 PtiLoo Extension #1 Operateur "++" et "--" Opérateur "!" & Fonction externe _FACT
Transparent 13 E#0=>E#1 : oper.loo => oper.c typedef struct _A* A; /************ définition de la classe A ************/ struct _A { _META* _type; }; A _A_A (A); _METH _A__VTBL[] = { (_METH) &_Object_type_name }; _META _A__META = { "A", &_Object__META, _A__VTBL }; /****méthodes de A ******/ A _A_A (A this) { _Object_Object ( (Object) this ); this->_type = &_A__META; { } return this; } int main () { int i = 0; int j = 0; string s = 0; A a = 0; j = i++; j = --i; } class A {}; main () { int i, j; string s; A a; j = i++; j = --i; // erreurs : // printf++; // --A; // a++; // --s; }
Transparent 14 Extensions PtiLoo: opérateurs ++ et -- Ext#1-Sol 1 Opérateurs ++ et -- sur entiers yacc(I) + %token MM PP expression + … lex + "++" return PP; "- -" return MM; entity.h expr.h + class IncDec : public Expression { … } stat.h yacc(II) expression + { $$ = new IncDec( … ) ; } _ana.cc + IncDec::analyse ( ) { … type entier ?… } _pro.cc + IncDec::generate ( ) const { … } run-time.h
Transparent 15 Extensions PtiLoo: opérateurs ++ et -- Ext#1-Sol 2 Opérateurs ++ et -- sur entiers yacc(I) + %token MM PP expression + … lex + "++" return PP; "- -" return MM; entity.h expr.h stat.h yacc(II) expression + { $$ = new Assignment( … ) ; } _ana.cc _pro.cc run-time.h ?? … type entier ??…
Transparent 16 Extensions PtiLoo: opérateur ! et fonction Xterne Ext#1Sol 1 factorielle ! sur exp. entières yacc(I) expression + … '!' { } lex entity.h expr.hclass Factorielle : public Expression { … } stat.h yacc(II) expression + { $$ = new Factorielle ( … ) ; } _ana.cc Factorielle ::analyse () { …type entier ?…} _pro.cc Factorielle ::generate ( ) { …_FACT() } run-time.h + … _FACT
Transparent 17 Extensions PtiLoo: opérateur ! et fonction Xterne Ext#1Sol 2 factorielle ! sur exp. entières yacc(I) expression + … '!' { } lex entity.h expr.h stat.h yacc(II) expression + {…$$= new CallDesignator (… "_FACT"…) ; } + … declare_external ( … "_FACT" … ) _ana.cc _pro.cc run-time.h + … _FACT
18 PtiLoo Extension #2 Initialisation des Variables Initialisation des Attributs de Classe
Transparent 19 E#0 : Un Souci évité grâce à la Règle Java ! main () { int x; int y; x = 1; // pas d'initialisation int x = 1 pour l'instant y = 2; int z; int t; z = 3; // t = 4; printf ("%d %d %d %d\n", x, y, z, t); if (t - z == y - x) { t = 4; int t ; // heureusement interdit int q; int r; q = t - y; r = z - x; printf ("%d %d\n", q, r); } int q; int r; // autorise car ne doublent pas les q et r précédents q = t + x; r = y + z; printf ("%d %d\n", q, r); } int main () { int x = 0; int y = 0; int z = 0; int t = 0; int q = 0; int r = 0; x = 1; y = 2; z = 3; printf ("%d %d %d %d\n", x, y, z, t); if (t - z == y - x) { int t = 0; int q = 0; int r = 0; t = 4; // erreur de t q = t - y; r = z - x; printf ("%d %d\n", q, r); } q = t + x; r = y + z; printf ("%d %d\n", q, r); }
Transparent 20 E#2(variables: sol1) : init.loo => init.c int main () { int i = 1; i = 2; { int j = i; i = j + 1; printf ("%d %d\n", i, j); { A a = _A_A (_NEW (A), 100); printf ("%d %d %d\n", _OCHECK (a, A)->_A_x, _OCHECK (a, A)->_A_j, _OCHECK (a, A)->_A_k ); { B b = _B_B (_NEW (B), 200, 300); printf ("%d %d %d %d %d\n", _OCHECK (b, B)->_A_x, _OCHECK (b, B)->_A_j, _OCHECK (b, B)->_A_k, _OCHECK (b, B)->_B_m, _OCHECK (b, B)->_B_n ); } main () { int i = 1; i = 2; int j = i; i = j + 1; printf ("%d %d\n", i, j); A a = new A (100); printf ("%d %d %d\n", a.x, a.j, a.k); B b = new B (200, 300); printf ("%d %d %d %d %d\n", b.x, b.j, b.k, b.m, b.n); }
Transparent 21 E#2(variables: sol2) : init.loo => init.c int main () { int i = 0; int j = 0; A a ; B b ; i = 1; i = 2; j = i; i = j + 1; printf ("%d %d\n", i, j); a = _A_A (_NEW (A), 100); printf ("%d %d %d\n", _OCHECK (a, A)->_A_x, _OCHECK (a, A)->_A_j, _OCHECK (a, A)->_A_k ); b = _B_B (_NEW (B), 200, 300); printf ("%d %d %d %d %d\n", _OCHECK (b, B)->_A_x, _OCHECK (b, B)->_A_j, _OCHECK (b, B)->_A_k, _OCHECK (b, B)->_B_m, _OCHECK (b, B)->_B_n ); } main () { int i = 1; i = 2; int j = i; i = j + 1; printf ("%d %d\n", i, j); A a = new A (100); printf ("%d %d %d\n", a.x, a.j, a.k); B b = new B (200, 300); printf ("%d %d %d %d %d\n", b.x, b.j, b.k, b.m, b.n); }
Transparent 22 Extensions PtiLoo: initialisation des déclarations Ext#2 initialisation des déclarations: attributs, variables, paramètres(=0) yacc(I)declvars : declattr : + initExpression yacc(II)declvars + { $$ = declare_variable ( init ) declattr + { $$ = declare_attribute ( init ) entity.hclass Variable, LocalVariable, Attribute, ClassType + Expression* vinit stat.hclass BlockStat { … add (LocalVariable …) … } entity.ccclass ClassType + Expression* vinit entity.hclass Variable, + ::analyse(…) ent_anavoid Variable::analyse (…) {… if variable_init type conforme?...} void ClassType::analyse (…) {… Attribute -> analyse...} stat_ana stat_pro void BlockStat::analyse (…) {…LocalVariableList -> analyse...} void BlockStat::generate (…) {…...} entity_ pro void LocalVariable::produce_definition ( ) const { …valeur init …} void Attribute::produce_definition ( ) const { …valeur init …} void ClassType::produce_attribute_initialization(…) {…..}
Transparent 23 E#0 => E#2 variables : ptiloo.yacc static LocalVariable* declare_variable (const char* no, const Type& ty) { LocalVariable* va = new LocalVariable (no, ty, yylineno); current_block->add (*va); symbol_table.declare (no, va, yylineno); return va; } %type % declvars : type IDENT { declare_variable ($2, *$1); $$ = $1; } | declvars ',' IDENT{ declare_variable ($3, *$1); $$ = $1; }
Transparent 24 E#0 => E#2 (Variables) : entity.h class Variable : public Entity { // classe abstraite des variables public : Variable (const string& cn, const Type& ty, int li) : Entity (cn, li), vtype (ty){ } const Type& type () const { return vtype; } void analyse (); protected : const Type& vtype; }; class LocalVariable : public Variable { public : LocalVariable (const string& cn, const Type& ty, int li) : Variable (cn, ty, li) { } void produce_definition () const; }; typedef autolist LocalVariableList;
Transparent 25 E#0 => E#2(Variables) : stat.h class BlockStat : public Statement { // l'instruction {... } public : …. void add (LocalVariable& v) { locals.push_back (&v); } void add (Statement& s) { body.push_back (&s); } …. void analyse (const Type&, bool); int compute_temporaries (); void generate (const Type&) const; // declare_locals + generate_body void declare_locals () const; void produce_body (const Type&) const; protected : BlockStat* embedding; int line; BlockScope scope; LocalVariableList locals; StatementList body; };
Transparent 26 E#0 => E#2 (Variables) : stat_pro.cc void BlockStat :: declare_locals () const { bool first = true; for (LocalVariableList::const_iterator p=locals.begin(); p=locals.end();++p) {if (first) first=false; (*p)-> produce_definition(); } void BlockStat :: produce_body (const Type& res) const { bool first = true; for (StatementList::const_iterator p=body.begin(); p=body.end();++p) (*p)-> generate(res); } void BlockStat :: generate (const Type& res) const { declare_locals() ; produce_body(res); }
Transparent 27 E#0 => E#2 (Variables) : stat_ana.cc void BlockStat :: analyse (const Type& res, bool in_constr) const { symbol_table.enter_scope(const-cast (scope)); for (StatementList::const_iterator p=body.begin(); p=body.end();++p) (*p)-> analyse(res, in_constr); symbol_table.leave_scope(); }
Transparent 28 E#0 => E#2(Variables): entity_ana.cc, entity_pro.cc stat_pro.cc void Variable::analyse (bool in_constr) { …. } void LocalVariable::produce_definition () const { cout << vtype.c_name << ' ' << c_name << " = 0 "; ……. cout <<";" ; } void BlockStat::generate () const { for ( ) {// traiter la StatementList du bloc (body) if (necessaire) cout << '{' ; // ouvrir un extra bloc ……. } ……. for ( ) {// fermer tous les extras blocs ouverts cout << '}' ; }
Transparent 29 E#2(attributs):.loo =>.c typedef struct _A* A ; s truct _A { _META* _type; int _A_ax; string _A_as; }; A _A_A (A this, int aa) { _Object_Object ((Object) this); this->_type = &_A__META; this->_A_ax = 50; this->_A_as = "Hello"; this->_A_ax = aa; printf ("\n\t%s\n", this->_A_as); return this; } typedef struct _B* B; struct _B { _META* _type; int _A_ax; string _A_as; int _B_bx; }; class A { int ax = 50; string as = "Hello" ; A (int aa) { ax = aa; printf ("\n\t%s\n", as); } } class B extends A { int bx; B (int bb) { super (bb); bx = bb; } }
Transparent 30 E#0 => E#2:attributs: Suivez la piste … fichieroù? classe?fction, méthode, constructeur.yaccdeclattr:declare_attribute + Expression* init.yaccdeclare _attribute current_class-> add_attribute + Expression* init entity.hClassTypeadd_attribute + Expression* init analyse produce_attribute_initialization entity.ccClassType:: add_attribute Attribute() + Expression* init entity.hAttributeproduce_initialization + Expression* init entity_ana.ccClassType:: Attribute:: analyse entity_pro.ccClassType::produce_attribute_initialization entity_pro.ccAttribute::produce_initialization
Transparent 31 E#0 => E#2 (Attributs): entity.h & entity.cc class ClassType : public Type { friend class Constructor; public : void add_attribute (const char*, const Type&, int); class Attribute : public Variable { public : Attribute (const string& cn, const Type& ty, const ClassType& cl, int li) : Variable (cn, ty, li), klass (cl) { } ~Attribute () { } const ClassType& attribute_class () const { return klass; } void produce_definition () const; protected : const ClassType& klass; }; ClassType::add_attribute (const char*, const Type&, int) { new Attribute() ; … };
Transparent 32 E#0 => E#2 (Attributs) : entity_ana.cc void ClassType::analyse () { // construire un constructeur implicite pour faciliter la production de code if (is_defined()) { current_class = this; for (autolist ::iterator it = pattrs.begin(); it != pattrs.end(); ++it) (*it)->analyse(true); symbol_table.enter_scope (*scope); // analyser les methodes et le constructeur constr->analyse (); for (autolist ::iterator it = pmeths.begin(); it != pmeths.end(); ++it) (*it)->analyse(); symbol_table.leave_scope (); current_class = 0; } else name_error ("classe non définie", c_name, line); }
Transparent 33 E#0 => E#2(Attributs) : entity_pro.cc void ClassType::produce_attribute_initialization () const { …….. } void Attribute::produce_initialization () const { cout " << c_name << c_name << " = "; …….. cout <<";" ; }
34 PtiLoo Extension #3 Instruction "for"
Transparent 35 E#3 : for.loo => for.c int main () { int x = 0; int y = 0; int i = 0; x = 0; { int k = 0; while (k < 10) { x = x + k; k = k + 1; } { int k = 0; while (k < 10) { { x = x + k; y = y + x; } k = k + 1; } { int p = 1; int q = 10; while (p < q) { { x = x + p; y = y - q; } p = p + 1; q = q - 1; } main() { int x; int y; int i; x = 0; for (int k = 0; k < 10; k = k + 1) x = x + k; for (int k = 0; k < 10; k = k + 1) { x = x + k; y = y + x; } for (int p = 1, q = 10; p < q; p = p + 1, q = q - 1) { x = x + p; y = y - q;} }
Transparent 36 Extensions PtiLoo: boucle "for" Ext#3 boucle "for" yacc(I) %token KFOR instruction + instruction_for lex "for" return KFOR ; entity.h expr.h stat.h class ForStat : public Statement {…} yacc(II) %type ? instruction_for + { ….*new ForStat (….)…} _ana.cc void ForStat ::analyse (…) const {…} _pro.cc void ForStat ::generate () const {…} run-time
Transparent 37 Extensions PtiLoo: boucle "for" Ext#3 boucle "for" yacc(I) %token KFOR instruction + instruction_for lex "for" return KFOR ; entity.h expr.h stat.h yacc(II) instruction_for + { …. BlockStat* b = new BlockStat (current_block, yylineno); … current_block->add (*new WhileStat (….)); … } _ana.cc _pro.cc run-time
38 PtiLoo Extension #4 Instruction "break" et Etiquettes
Transparent 39 E#4 : break.loo => break.c { while (i < 100) { if (i == 50) break; j = j + 1; k = i * j; if (k < 1000) { while (k > 0) if (k == 10) goto _L1; else if (k == 11) goto _L2; else k = k - 1; _L2 : ; } else k = 0; i = i + 1; } _L1 : ; } AA : while (i < 100) { if (i == 50) break; j = j + 1; k = i * j; if (k < 1000) BB : while (k > 0) if (k == 10) break AA; else if (k == 11) break BB; else k = k - 1; else k = 0; i = i + 1; }
Transparent 40 Extensions PtiLoo: "break" et étiquettes Ext#4 "break" et étiquettes yacc(I) %token KBREAK instruction + instruction_break instruction_while & _for + etiqu_option lex "break" return KBREAK ; entity.h expr.h stat.h class BreakStat: public Statement {…} WhileStat() & ForStat() + etiqu_option yacc(II) instruction_break + { …. new BreakStat() …} instruction_while & _for + y créer les étiquettes en pile stat_ana à déplacer dans le.yacc instruction_break + tester la validité des étiquettes et des "break" ? stat_pro WhileStat() & ForStat()::generate() + le code des étiquettes BreakStat()::generate() transformer les "break Et" en "goto Et" ! run-time