Gnrateurs de compilateurs Pr ZEGOUR DJAMEL EDDINE Ecole
- Slides: 30
Générateurs de compilateurs Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI) www. zegour. uuuq. com email: d_zegour@esi. dz
Générateurs de compilateurs Introduction Yacc Lex Coco/R
Fonctionnement des générateurs de compilateurs Ils génèrent les parties d’un compilateur à partir d’une spécification concise (Parties générées : scanner, analyseur syntaxico-sémantique, générateur de code , . . . ) générateur scanner Spécification du scanner Ex. grammaire régulière) Spécification sémantique (Ex. grammaire d’attribut) générateur de l’analyseur Générateur De compilateurs Exemples Yacc Lex Coco/R. . . scanner Analyseur compilateur & éditeur de liens Classes utilisateur • Table des symboles • Générateur de code • Programme principal • . . . générateur d’analyseur syntaxique et sémantique pour C et Java générateur de scanner pour C, Java et C# générateur de scanner et d’analyseur pour Java, C#, Modula-2, Oberon, . . . compilateur généré
Générateurs de compilateurs Introduction Yacc Lex Coco/R
Yacc - Yet another compiler Histoire 1975 développé aux laboratoires Bell ( ensemble avec C et Unix) • Génère des analyseurs LALR(1) • À l’origine sous Unix, Aujourd'hui aussi sous Windows, Linux • A l’origine pour C, Aujourd'hui pour Java Utilisation sample. y Nous décrivons ici la version de Java Yacc parser. javac Versions actuelles Bison version GNU de Yacc http: //www. gnu. org/software/bison. html Byacc Berkeley Yacc http: //byaccj. sourceforge. net/ parser. class
Langage d’entrée pour Yacc Format général %{package Java et les lignes ‘import’ %} Déclarations Yacc (unités, règles de précédence des opérateurs, . . . ) %% productions %% Déclarations Java (champs, méthodes) Traduit vers class parser {. . . public void yyparse() {. . . parser. . . } }
Yacc — Productions et actions sémantiques Productions Grammar Production Alternative Sem. Action NT T = {Production}. = NT ": " Alternative {"|" Alternative} "; " = {NT | T} [Sem. Action]. = "{". . . arbitrary Java statements. . . "}". = ident | char. Const. Exemple expr: term { $$ = $1; } | expr '+' term { $$. ival = $1. ival + $3. ival; } ; Actions Sémantiques • Peuvent contenir des instructions Java • Peuvent apparaître seulement à la fin d’une alternative • Les attributs sont dénotés par des noms spéciaux: $$ attribut du coté gauche NTS $i attribut du i-ème symbole du coté droit ($1 = attr. du premier symbole, $2 = attr. du second symbole, . . . )
Yacc — Attributs Pour les symboles terminaux • Sont délivrés par le scanner (scanner développé manuellement ou généré avec Lex) • Chaque unité lexicale a un attribut de type parserval class parserval { int ival; // token value if the token should have an int attribute double dval; // token value if the token should have a double attribute String sval; // token value, e. g. for ident and string Object obj; // token value for more complex tokens parserval(int val) {. . . } // constructors parserval(double val) {. . . } parserval(String val) {. . . } parserval(Obj val) {. . . } } • Le scanner retourne les attributs dans la variable globale yylval Scanner yylval = new parserval(n); Accès dans une action sémantique {. . . $1. ival. . . } Pour les symboles non terminaux • Chaque NTS a un attribut $$ de type parserval ( valeurs plus complexes rangées dans $$. obj) • Chaque affectation à $$ empile l’attribut du NTS dans une pile d’attributs. Les accès à $1, $2 se font en dépilant les attributs de la pile
Yacc — Variables et Méthodes Java Sont déclarées après le second %% %{. . . imports. . . %}. . . Unités. . . %%. . . Productions. . . %%. . . Déclarations Java. . . • Deviennent des champs et des méthodes pour l’analyseur • Peuvent être utilisées dans les actions sémantiques Au moins les méthodes suivantes doivent être implémentées dans les déclarations Java void yyerror(String msg) {. . . } Pour afficher les messages d’erreur int yylex() {. . . } Scanner (retourne les codes unités et remplit yylval) public static void main(String[] arg) {. . . initializations for yylex. . . yyparse(); } Programme principal
Exemple: Compilateur pour les expressions /* declaration of all tokens which are not strings */ %token number %% /* productions: first NTS is the start symbol */ input: expr { System. out. println($1. ival); } ; expr: term | expr '+' term { $$ = $1; } { $$. ival = $1. ival + $3. ival; } ; term: factor | term '*' factor { $$ = $1; } { $$. ival = $1. ival * $3. ival; } ; factor: number | '(' expr ')' { $$ = $1; } { $$ = $2; } ; %% int yylex() {. . . } void yyerror(string msg) {. . . } public static void main(String[] arg) {. . . } arithmétiques Conventions de codage des unités • eof == 0 • Code des unités ‘caractère’ : leurs valeurs Ascii (Par exemple '+' == 43) • YYERRCODE == 256 • Autres unités sont numérotées consécutivement commençant par 257 (Par exemple. nombre == 257); elles peuvent être accédées dans les productions et dans yylex() utilisant leur nom déclaré.
Yacc — Précédence des opérateurs La grammaire suivante spécifie explicitement la précédence des opérateurs expr: term | expr '+' term ; term: factor | term '*' factor ; factor: number | '(' expr ')' ; • '*' a une précédence sur '+' • Les opérateurs sont associatifs à gauche: a*b*c == (a*b)*c On peut aussi l’exprimer comme suit en Yacc: %token number %left '+' %left '*' • %left : l’opérateur est associatif gauche a+b+c == (a+b)+c input: expr • Les opérateurs sont déclarés en ordre ascendant de priorité: '*' a une précédence sur '+' { System. out. println($1. ival); } ; expr: number | expr '+' expr | expr '*' expr | '(' expr ')' { $$ = $1; } { $$. ival = $1. ival + $3. ival; } { $$. ival = $1. ival * $3. ival; } { $$ = $2; } %% %%. . . • Cette grammaire ne spécifie aucune précédence d’opérateurs • La précédence est spécifiée par %left ou %right
Yacc — Traitement des erreurs Les alternatives ‘error’ Pour certains NTS (EX: Instructions, Expression, . . . ) l’utilisateur doit spécifier Les alternatives ‘error’ A: . . . | error a {. . . } ; a. . . Séquence quelconque de symboles T et NT Signification: S’il existe une erreur dans A l’analyseur effectue les actions suivantes: • Il dépile des états de la pile jusqu’à l’obtention d’un état dans lequel une action ‘décaler’ avec l’unité error est valide • ‘Décaler’ error • Il saute les unités d’entrée jusqu’à ce qu’il détecte une séquence d’unités qui peut être réduite à a ( le sommet de pile contient alors : error a) • Il réduit error a à A et exécute l’action sémantique correspondante Exemple Statement =. . . | error '; ' ; Saute tout jusqu’au prochain '; '
Générateurs de compilateurs Introduction Yacc Lex Coco/R
Lex — Générateur de scanner Histoire 1975 développé aux laboratoires Bell • génère un scanner en forme de DFA • A l’origine un outil de Unix, aujourd'hui aussi pour Windows • A l’origine pour C, Aujourd’hui aussi pour Java • Coopère généralement avec Yacc Utilisation Nous decrivons ici la version C sample. l Lex sample. yy. c sample. y Yacc sample. tab. c include C-Compiler Versions actuelles flex version GNU de Lex (pour C) http: //www. gnu. org/software/flex/ JLex version Java avec légère différence dans la syntaxe d’entrée; incompatible avec Bison ou Byacc http: //www. cs. princeton. edu/~appel/modern/java/JLex/ version C# , dérivé de JLex http: //www. cybercom. net/~zbrad/Dot. Net/Lex Cs. Lex sample. o
Exemple de description Lex %{. . . e. g. include directives for token numbers exported by the parser. . . %} /* macros */ delim [ tn] /* blank, tab, eol */ ws {delim}+ /* {. . . }. . . use of a macro */ letter [A-Za-z] digit [0 -9] id {letter} ({letter} | {digit})* number {digit}+ %% /* token declarations described as regular expressions */ {ws} {} /* no action */ if { return IF; } /* constants like IF are imported from the parser */ then { return THEN; } else { return ELSE; } {id} { yylval = store. Id(yytext, yyleng); return ID; } {number} { yylval = convert(yytext, yyleng); return number; } < { return yytext[0]; } > { return yytext[0]; }. {} /*. denotes any character */ %% /* semantic routines */ int store. Id(char* text, int len) {. . . } int convert(char* text, int len) {. . . }
Scanner généré La spécification du scanner est convertie en une fonction int yylex() {. . . } qui est incluse dans l’analyseur yylex() retourne aussi les attributs d’unités comme variables globales int yylval; char* yytext; int yyleng; int yylineno; /* attribute if the token has a numeric value */ /* token text (attribute of ident, string, . . . ) */ /* lengh of the token text */ /* line number of the token */ L’analyseur déclare (et exporte) les codes unités %token IF %token THEN. . .
Expressions régulières dans Lex Éléments des expressions régulières abc. x* x+ x? (. . . |. . . ) [. . . ] {. . . } ^ $ udddd la chaîne "abc"; tout caractère sauf ()[]{}*+? |^$. dénote lui-même Tout caractère sauf n (fin de ligne) 0 ou plusieurs répétitions de x 1 ou plusieurs répétitions de x 0 ou 1 occurrence de x ( occurrence optionnelle) pour grouper des alternatives ensemble de tous les caractères entre les crochets (Ex. [A-Za-z 0 -9$]) Utilise d’une macro ligne début ligne fin caractère en Unicode
Générateurs de compilateurs Introduction Yacc Lex Coco/R
Coco/R – Compilateur de compilateur / Descente Récursive Histoire 1980 développé à l’université de Linz (Rechenberg, Mössenböck) • génère un scanner et un analyseur à partir d’une grammaire d’attribut - scanner comme un DFA - Analyseur sous forme de ‘descente récursive’ • Il existe des versions pour C#, Java, C/C++, Delphi, Modula-2, Oberon, Python, . . . • Publié sous GPL: http: //www. ssw. uni-linz. ac. at/Research/Projects/Coco/ Utilisation main grammaire d’attribut parser Coco/R scanner Classes utilisateurs (Ex. Table des symboles csc
Exemple: Compilateur pour les Expressions arithmétiques COMPILER Calc /* grammar name = start symbol */ CHARACTERS /* character sets used in token declarations */ digit = '0'. . '9'. tab = 't'. cr = 'r'. lf = 'n'. TOKENS /* declaration of all tokens which are not literals */ number = digit {digit}. COMMENTS /* declaration of comments */ FROM "//" TO cr lf FROM "/*" TO "*/" NESTED IGNORE tab cr lf /* these characters are ignored as white space */ PRODUCTIONS Calc (. int x; . ) = "CALC" Expr<out x> (. System. Console. Write. Line(x); . ). Expr<out int x> = Term<out x> { '+' Term<out y> }. (. int y; . ) Term<out int x> = Factor<out x> { '*' Factor<out y> }. (. int y; . ) Factor<out int x> = number | '(' Expr<out x> ')'. END Calc. (. x = x + y; . ) (. x = x * y; . ) (. x = Convert. To. Int 32(t. val); . )
Coco/R — les attributs Les symboles terminaux • Les symboles terminaux n’ont pas d’attribut explicite • Leurs valeurs peuvent être accédées dans les actions sémantiques utilisant les variables suivantes Token t; l’unité la plus récente reconnue Token la; la prochaine unité (lookahead) (non encore reconnue) Exemple Factor<out int x> = number class Token { int kind; string val; int pos; int line; int col; } (. x = Convert. To. Int 32(t. val); . ) // token code // token value // token position in the source text (starting at 0) // token line (starting at 1) // token column (starting at 0) Les symboles non terminaux • Les NTS peuvent avoir des attributs d’entrée Attr. formels: A<int x, char c> =. . Attr réels. : . . . A<y, 'a'>. . . • Les NTS peuvent avoir des attributs de sortie B<out int x, out int y> =. . . . B<out z, out n>. . .
Coco/R — Traitement sémantique Actions sémantiques • code Java entre (. et. ) • Peuvent apparaître n’importe où dans les productions • Dans le coté gauche d’une production elles sont considérée comme des déclarations Term<out int x> = Factor<out x> { '*' Factor<out y> }. (. int y; . ) déclaration (. x = x * y; . ) action sémantique Déclarations sémantiques • Apparaissent au début de la spécification du compilateur • Sont utilisées pour déclarer les champs et les méthodes de l’analyseur • Les ‘import’ peuvent aussi être spécifiés COMPILER Sample using System. Collections; static IList my. List; static void Add. To. List (int x) {. . . } CHARACTERS. . . Bien sûr, les actions sémantiques peuvent aussi accéder aux champs et méthodes de classes autre que ceux de l'analyseur.
Coco/R – les méthodes d’analyse Chaque production est traduite en une méthode de l’analyseur Expr<out int x> = Term<out x> { '+' Term<out y> }. (. int y; . ) (. x += y; . ) devient static void Expr (out int x) { int y; Term(out x); while (la. kind == plus) { Scan(); Term(out y); x += y; } }
Coco/R – Traitement des erreurs syntaxiques L’analyseur utilise la technique des ‘ancres spéciaux’ Point de synchronisation Doivent être marqués par SYNC Statement = SYNC ( Assignment | If. Satement |. . . ). if la. kind dans Suivant(SYNC) une erreur est reportée et des unités sont sautées jusqu’à la. kind dans Suivant(SYNC) Inter {eof} Les faux messages d'erreur sont supprimés si moins de 3 unités ont été reconnues depuis la dernière erreur. Séparateurs faibles Les séparateurs au début d’une itération peuvent être marqués comme Weak (faibles) Formal. Pars = "(" Param { WEAK ', ' Param } ')'. Si le séparateur manque ou est mal écrit, la boucle n'est pas terminée prématurément, mais l'analyseur synchronise avec Premier(Param) Inter Suivant({. . . }) Inter {eof}
Coco/R — Tests de grammaire Test LL(1) A = a [B] C d | B a. B = a b. C = a [d]. Coco/R affiche les avertissements suivants LL 1 warning in A: a is start & successor of deletable structure LL 1 warning in A: a is start of several alternatives LL 1 warning in C: d is start & successor of deletable structure Test de complétude Existe-il une production pour chaque NTS? Test de non-redondance Est-ce que la grammaire contient des productions non atteintes? Test de Dérivabilité Est-ce que chaque NTS peut être dérivé en une chaîne de symboles terminaux? Test de Non-circularité Y a t-il des NTS qui peuvent être dérivé (directement ou indirectement)en eux-mêmes?
Coco/R — Pragmas (Directives de compilation) Pragmas sont des symboles terminaux • Qui peuvent apparaître n’importe où dans l’entrée • Qui ne font pas partie de la syntaxe • Qui doivent être traités sémantiquement Ex. options du compilateur COMPILER X CHARACTERS. . . TOKENS. . . PRAGMAS Print. Option = "$print". Dbg. Option = "$debug". . (. option[print] = true; . ) (. option[debug] = true; . ) Quand la string $print apparaît dans le texte d’entrée l’action sémantique option[print] = true; est exécutée
Coco/R — le symbole ‘ANY’ Dans la déclaration des ensembles de caractères Il décrit des ensemble de caractères complémentaires CHARACTERS letter = 'A'. . 'Z' + 'a'. . 'z'. no. Letter = ANY - letter. . Tous les caractères qui ne sont pas des lettres Dans les productions Il décrit tout unité qui ne peut être produite par les autres alternatives Place. Holder = ident | ANY. Tout unité qui n’est pas ident ou eof Sem. Action = "(. " { ANY } ". )". Tout unité qui n’est pas ". )" ou eof
Coco/R — Résolution des conflits LL(1) Résolution de conflit par un by a multi-symbol lookahead Statement = IF (Is. Assignment()) Designator "=" Expr "; " | Designator "(" Actual. Params ")" "; " |. . static boolean Is. Assignment () { Token x = la; while (x. kind != _assign && x. kind != _lpar) x = Scanner. Peek(); return x. kind == _assign; } Scanner. Peek(). . . Lit les unités sans les enlever de l’entrée Les noms d’unités (_assign, _lpar, . . . ) sont générés à partir des sections TOKENS Résolution de conflit par une vérification sémantique Factor = IF (Is. Cast()) '(' ident ')' Factor /* type cast */ | '(' Expr ')' /* nested expression */ |. . static boolean Is. Cast () { Token x = Scanner. Peek(); if (x. kind == _ident) { Symbol s = Tab. Find(x. val); return s. kind == Symbol. Kinds. Type; } else return false; }
Coco/R — les frames Le scanner et l’analyseur sont générés à partir de frames (fichier texte ordinaire) Ex. Scanner. frame public class Scanner { const char EOL = 'n'; const int eof. Sym = 0; -->declarations. . . static Token Next. Token () { while (ignore[ch]) Next. Ch(); -->scan 1 t = new Token(); t. pos = pos; t. col = pos - line. Start + 1; t. line = line; int state = start[ch]; String. Builder buf = new String. Builder(16); -->scan 2. . . } Coco/R insère le code à ces positions En modifiant les frames le scanner et l’analyseur peuvent être adaptés aux besoins de l’utilisateur (à un certain degré)
Coco/R — Interfaces Scanner public class Scanner { public static void Init (string source. File. Name) {. . . } public static void Init (Stream s) {. . . } public static Token Scan () {. . . } public static Token Peek () {. . . } public static void Reset. Peek () {. . . } } Parser public class Parser { public static Token t; public static Token la; public static void Parse () {. . . } public static void Sem. Err (string msg) {. . . } } Error message class public class Errors { public static int public static string public static void } count = 0; err. Msg. Format = "-- line {0} col {1}: {2}"; Syn. Err (int line, int col, int n); Sem. Err (int line, int col, int n); Error (int line, int col, string msg); Exception (string msg);
- Zegour djamel eddine
- Docteur kati
- Zegour
- Zegour esi
- Zegour
- Zegour esi
- Arbres avl
- Zegour
- Sécurité incendie école maternelle
- Ecole doctorale erasme
- Ecole
- Ecole inclusive
- Ecole de commerce neuveville
- Silence silence un souffle descend
- Creatisse
- Ecole moser calendrier
- Pierre fasly
- Esc la neuveville vacances
- Ecole packaging reims
- Ecole superieure de biotechnologie constantine
- école virtuelle
- Ecole maternelle poulletier
- Radiation ecole
- Ecole quarterway
- Ecole du sabbat
- L'ecole de prague
- Périscolaire ingwiller
- L'école d'athènes analyse du tableau
- Pipe ecole
- Ecole de commerce delémont
- Saint sacrement 2022