230 likes | 379 Views
Professeur : Justus H. Piater. Structure des langages de programmation. Implémentation d ’ un langage de calcul de devises. Dessilly Adrien Gobert Thibaud Lauwers Alexandre Roland Sébastien. Comment gérer nos comptes avec différentes devises monétaires?
E N D
Professeur : Justus H. Piater Structure des langages de programmation Implémentation d’un langage de calcul de devises Dessilly Adrien Gobert Thibaud Lauwers Alexandre Roland Sébastien
Comment gérer nos comptes avec différentes devises monétaires? • Écrire un programme de gestion (par exemple : COBOL, C, …). Inconvénients : • faire les calculs de conversions explicitement; Exemple COBOL • gérer les cas d’erreurs sur les devises. Exemple C 77 dollar PIC 9(2)v99. 77totalEuro PIC 9(4)v99. 77 argent PIC 9(4)v99. MOVE 0.75 TO dollar. COMPUTEtotalEuro= argent * dollar. 3 + 20 * 0.75 est calculable, mais est-ce bien correct? 1 + 2 € = ? 2$ * 3€ = ? MonArgent+=30*deviseYen+50 * deviseDollar ; MonArgent+=3+20* deviseDollar ; Préambule
la manipulation des devises monétaires; • la gestion implicite des opérations mathématiques entre les devises; • la gestion des boucles et conditions à cet effet; • l’affichage des devises de façon simplifiée. Il faut donc créer un langage permettant : Présentation du langage • principes
Devise (currency) Valeur constante d’une devise en fonction d’une devise de référence. • Portefeuille (value) Stocker des sommes d’argent. • Float (float) Valeur numérique sans unité pour multiplier / diviser des sommes d’argent. Manipulation de trois types de données : currency euro; currency dollar =0.75; valuemonArgent=10 euro +25 dollar; floatmultiplicateur =2.5; monArgent= multiplicateur *10 euro; Présentation du langage • concepts
currencyEUR ; currency GBP =1.2692; currency AUD =0.5840; valuetotalLondres; valuetotalSydney; valuetemp; floatnbrWeeks; nbrWeeks= 4; totalLondres=25 EUR +nbrWeeks * 300 AUD +50 GBP +250 GBP; totalLondres=totalLondres + 150 EUR; totalSydney=25 EUR +nbrWeeks * 50 AUD +40 GBP +100 AUD; totalSydney=totalSydney+1090 EUR ; print(totalLondres, EUR) ; print(totalSydney, EUR) ; temp=totalLondres; totalLondres=0 EUR ; while (temp>0 EUR){ totalLondres=totalLondres+1 EUR; temp=temp - 1 EUR; } if(totalLondres<totalSydney) {print(totalSydney+4 EUR -totalLondres, GBP); } else{print(totalLondres-totalSydney, GBP); } nbrWeeks * 300 AUD valeur en AUD à convertir en GBP. Exemple de code
Keyword currency|value|float|if|else| while|print • Identifier [a-zA-Z_][a-zA-Z_0-9]* • Litteral[0-9]+ (.[0-9]+)? • Separator{ | }( | ) | ; | , | = • Rel_op< |<= | > | >= | == | != • Add_op+ | - • Mul_op* | / Structure lexicale semblable à Jay : Structure lexicale
Program → Declarations Block Declarations → ReferenceCurrency Currency*Initialization* ReferenceCurrency →currency Identifier ; Currency → currencyIdentifier = litteral ; Initialization → TypeIdentifier; Type → float| value Block → Instruction* Instruction → Assignment | Loop | Cond | Print Assignment → Identifier=Expression; Expression → Term{add_op Term}* Term → Factor{mul_opFactor}* Factor → litteral | Identifier | litteral Identifier | (Expression ) BoolExpression →Expressionrel_opExpression Loop → while( BoolExpression){Block} Print → print(Expression,Identifier ); Cond → if (BoolExpression) {Block} | if (BoolExpression) { Block}else{Block} Exemple : total = 3 euros; 3 litteral Euros identifier Grammaire
Program = Declarations ; Block Declarations = ReferenceCurrency ; Currency* ; Initialization* ReferenceCurrency = string Currency = string ; float Initialization = Type Identifier ; Type = float | value | currency Block = Instruction* Instruction = Assignment | Loop | Cond | Print Assignment = string ; Expression Loop = BoolExpression ; Block Cond = BoolExpression ; Block ; Block Print = Expression ; string Expression = FactorFloat | FactorValue | FactorCurrency | Binary FactorFloat = float; FactorValue = string; FactorCurrency = float ; string Binary = operator ; Expression ; Expression Operator = Addop | Mulop BoolExpression = Relop ; Expression ; Expression Addop = * | / Mulop = + | - Relop = < | <= | > | >= | == |!= Syntaxe abstraite Expression → Term{add_op Term}* Term → Factor{mul_opFactor}*
Typage du langage • Langage fortement typé • Typage statique Que faut-il vérifier? • Les déclarations: les identifiants sont-ils uniques? • La validité des instructions dans le corps du programme ReferenceCurrency →currency Identifier ; Currency → currencyIdentifier = litteral ; Initialization → TypeIdentifier; Instruction → Assignment | Loop | Cond | Print Contrôle de types • Vérifications?
Que faut-il vérifier dans les instructions? • Les affectations • L’affichage des portefeuilles • Les boucles et conditions TypeOf(Identifier) = TypeOf(Expression) Assignment → Identifier=Expression; TypeOf(Identifier) != currency TypeOf(Identifier) = currency Print → print(Expression,Identifier ); TypeOf(Expression) = value TypeOf(Expression) != currency BoolExpression →Expressionrel_opExpression Contrôle de types TypeOf(Expression1) = TypeOf(Expression2) • Validité des instructions
Implémentation: classe StatickTypeCheck • 1) Construction d’une « map des types » • Parcours de la partie « déclarations » de l’arbre de syntaxe abstraite • Construction de la map • En même temps: vérification de l’unicité des identifiants. • 2) La validité des instructions dans le corps du programme • Parcours de la partie « corps » de l’arbre de syntaxe abstraite • Vérification « en cascade » de la validité des instructions • Si une instruction invalide est rencontrée, le contrôle se termine et une exception est déclenchée currencyEUR ; currency GBP =1.2692; valuetotalLondres; float nbrWeeks; EUR currency GBP currency totalLondres value …........……. nbrWeeks float …………... Contrôle de types • Implémentation
Exemple: type d’une expression? 25 EUR + nbrWeeks * 300 GBP + totalLondres ; EUR currency GBP currency totalLondres value …........……. nbrWeeks float …………... MAP + value + value totalLondres value value * 25 EUR value float currency value nbrWeeks 300 GBP float float currency Contrôle de types • Exemple
Expression = FactorValue (Exemple : AUD) M : Expression x ∑ → float M(Expression e, State σ) = σ(e.name).value • Expression = FactorFloat (Exemple : 12) M : Expression → float M(Expression e) = e.value • Expression = FactorCurrency (Exemple : 12 AUD) M : Expression x ∑ → float M(Expression e, State σ) = e.value * σ(e.nameCurrency).value • Program = Declarations ; Block M : Program → ∑ M(Program p) = M(p.block, M(p.declarations,{ })) • Declarations = ReferenceCurrency ; Currency* ; Initialization* M : Declarations x ∑ → ∑ M(Declarations d, State σ) = M(d.values,M(d.currencies,M(d.refCurrency, σ))) • ReferenceCurrency = string M : ReferenceCurrency x ∑ → ∑ M(ReferenceCurrency r, State σ) = σ Ū {<r.name,Value(Type.Currency,1)>} • Currency = string ; float M : Currency x ∑ → ∑ M(Currency c, State σ) = σ Ū {<c.name,Value(Type.currency,c.value)>} • Initialization = Type ; float M : Initialization x ∑ → ∑ M(Initialization i, State σ) = σ Ū {<i.name,Value(i.type,0)>} Sémantique et interprétation • Sémantique dénotationnelle
currencyEUR ; currency GBP =1.26; currency AUD =0.587; valuetotalLondres; valuetotalSydney; valuetemp; floatnbrWeeks; nbrWeeks= 4; totalLondres=25 EUR +nbrWeeks * 300 AUD +50 GBP +250 GBP; totalLondres=totalLondres + 150 EUR; totalSydney=25 EUR +nbrWeeks * 50 AUD +40 GBP +100 AUD; totalSydney=totalSydney+1090 EUR ; print(totalLondres, EUR) ; print(totalSydney, EUR) ; temp=totalLondres; totalLondres=0 EUR ; while (temp>0 EUR){ totalLondres=totalLondres+1 EUR; temp=temp - 1 EUR; } if(totalLondres<totalSydney) {print(totalSydney+4 EUR -totalLondres, AUD); } else{print(totalLondres-totalSydney, AUD); } Sémantique et interprétation • Exemple et résultats
Génération du code intermédiaire Parcours de l'arbre abstrait, ajout de MInstructions au BB & graphe de flots de contrôle • Allocation de registres Calcul durée de vie des registres virtuels, algo SDA • Génération du code assembleur Calcul offset mémoire, traduction du CI CASMβ Particularités : * inversion opérandes * libinout.uasm * stockage value en default currency (pas calculé en assembleur) Génération du code • Introduction
Génération de code • Architecture générale
// pour importer des colis des USA, taxe fixe (en USD) // dépendant de l'age par objet + frais de réception (en BEF) Génération de code • Exemple (code intermédiaire)
Allocation des ressources [VR=0] B=0, E=1, RSR=0 [VR=1] B=2, E=3, RSR=0 [VR=2] B=4, E=5, RSR=0 [VR=3] B=6, E=7, RSR=0 [VR=4] B=11, E=12, RSR=2 [VR=5] B=9, E=11, RSR=0 [VR=6] B=10, E=11, RSR=1 [VR=7] B=16, E=17, RSR=2 [VR=8] B=14, E=16, RSR=0 [VR=9] B=15, E=16, RSR=1 [VR=10] B=21, E=22, RSR=2 [VR=11] B=19, E=21, RSR=0 [VR=12] B=20, E=21, RSR=1 [VR=13] B=28, E=29, RSR=1 [VR=14] B=24, E=28, RSR=0 [VR=15] B=27, E=28, RSR=3 [VR=16] B=25, E=27, RSR=1 [VR=17] B=26, E=27, RSR=2 [VR=18] B=32, E=33, RSR=0 [VR=19] B=30, E=32, RSR=2 [VR=20] B=31, E=32, RSR=3 [VR=21] B=35, E=37, RSR=1 [VR=22] B=36, E=37, RSR=3 [VR=23] B=37, E=38, RSR=2 Génération de code • Exemple (allocation)
618 (age 26) • 311 (age 15) Génération de code • Exemple (code ASM β)
Structure contenant double registre virtuel doubleVR* generate(constFactorFloat* …) • Codage selon mantisse – exposant FloatUtils • Allocation de ressources non affectée • Utilisation de la librairie externe • Adapter certaines traductions Exemple : pas de comparaison >= Génération de code • Critique : float
Selon une partie du code présenté au début : currencyEUR ; currency GBP =1.2692; currency AUD =0.5840; valuetotalLondres; value totalSydney; value temp; float nbrWeeks; nbrWeeks = 4; totalLondres =25 EUR + nbrWeeks * 300 AUD +50 GBP +250 GBP; totalLondres = totalLondres + 150 EUR; Amélioration du code • Exemple concret
Amélioration du code • Ancienne méthode : exemple Fibonacci
Merci pour votre attention… ? Des questions?