Analyse lexicale Pr ZEGOUR DJAMEL EDDINE

Slides:



Advertisements
Présentations similaires
Cours n° 1 Introduction à la programmation
Advertisements

Traitement sémantique et grammaire dattributs Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure dInformatique (ESI)
Le langage Z Pr ZEGOUR DJAMEL EDDINE
Vue générale Pr ZEGOUR DJAMEL EDDINE
Machines de Turing Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure dInformatique (ESI)
Sémantique des déclarations pour le langage Z minimal
Chap 1 Grammaires et dérivations.
Introduction : Compilation et Traduction
IFT313 Introduction aux langages formels
IFT313 – Introduction aux langages formels Eric Beaudry Département dinformatique Université de Sherbrooke Laboratoire 4 – JFlex Été 2010.
IFT313 Introduction aux langages formels
Introduction : Compilation et Traduction
44 Contrôle du déroulement du programme. 4-2 Objectifs A la fin de ce cours, vous serez capables de : Utiliser les constructions de prise de décision.
Analyse lexicale Généralités Expressions rationnelles Automates finis
IFT451 Introduction aux langages formels Froduald Kabanza Département dinformatique Université de Sherbrooke planiart.usherbrooke.ca/kabanza/cours/ift313.
IFT313 Introduction aux langages formels
Introduction au paradigme objet Concepts importants surcharge (overload) redéfinition (override) Définition d’une classe Définition des attributs.
© 2007 P. Van Roy. All rights reserved. FSAB1402: Informatique 2 Le Langage Java et les Exceptions Peter Van Roy Département dIngénierie Informatique,
IFT313 Introduction aux langages formels
Faculté I&C, Claude Petitpierre, André Maurer 1 JavaCC Java compilers compiler (version générant du Javascript)
Examen de compilation 4ème année - A
Structures de données IFT Abder Alikacem La classe string Département dinformatique et de génie logiciel Édition Septembre 2009 Département dinformatique.
Xpath XML Path language par Yves Bekkers
IFT313 Introduction aux langages formels
IFT313 Introduction aux langages formels Froduald Kabanza Département dinformatique Université de Sherbrooke Analyseurs récursifs LL (1)
Contrôle de types Les types en programmation Expressions de types Un contrôleur de types Equivalence de types Conversions de types Généricité.
LIFI-Java 2004 Séance du Jeudi 9 sept. Cours 1. La notion de langage Décrire une tâche à effectuer –programme Écrire à un haut niveau –facile pour lutilisateur.
Chapitre 9 Les sous-programmes.
Chapitre 3 Syntaxe et sémantique.
Analyse lexicale et syntaxique
Partie II Sémantique.
Séance d’introduction
Analyse syntaxique Pr ZEGOUR DJAMEL EDDINE
Table des symboles Pr ZEGOUR DJAMEL EDDINE
Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure dInformatique (ESI) Plate-forme.NET.
Instructions de contrôle
Faculté I&C, Claude Petitpierre, André Maurer JavaCC Java compilers compiler (version générant du Javascript)
Rappel Modèle analyse-synthèse de la compilation
Animateur : Med HAIJOUBI
Programmation procédurale Transformations
Paradigmes des Langages de Programmation
Structures complexes Pr ZEGOUR DJAMEL EDDINE
Expressions logiques Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
LES PILES ET FILES.
O-notation 1. Introduction 2. O-notation 3. Opérations 3.1 Somme 3.2 Produit 4. Règles générales 5. Exemple 6.Analyse des algorithmes récursifs 6.1 Dilatation.
Procédures et fonctions Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
Listes linéaires chaînées Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
Sémantique des expressions arithmétiques pour le langage Z minimal Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
Master 1 SIGLIS Java Lecteur Stéphane Tallard Les erreurs communes en Java.
Tables de compilation pour le langage Z minimal Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
© 2005 P. Van Roy. All rights reserved. FSAB1402: Informatique 2 Le Langage Java Peter Van Roy Département d’Ingénierie Informatique, UCL
D.E ZEGOUR Ecole Supérieure d’Informatique. Problèmes de décision Concepts de base Expressions régulières Notation particulière pour exprimer certaines.
Le langage Z minimal Pr ZEGOUR DJAMEL EDDINE
Structures de données avancées : Fichiers uni-dimensionnels Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
Structures de données avancées : Arbres ‘Left Leaning Red-Black’
L’analyse lexicale Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
Sémantique des instructions pour le langage Z minimal Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
Structures simples et tableaux Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
Interprétation/Génération de code pour le langage Z minimal Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
Expressions sur les chaînes de caractères Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
1 Programmation en C++ Marianne Morris. 2 Intro générale à la programmation On a déjà étudié le langage assembleur Langage de bas niveau Meilleur que.
Recherche par automates finis
Master IRAD - SPIN / PROMELA
Chap 1 Grammaires et dérivations.
Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI) C O M P I L Z.
Langage de programmation
PRO-1027 Programmation Scientifique en C
IFT359 – Programmation fonctionnelle Thème #8 Création de nouvelles formes syntaxiques 1.
Transcription de la présentation:

Analyse lexicale Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI) www.zegour.uuuq.com email: d_zegour@esi.dz

Analyse lexicale Taches d‘un scanner Grammaires Régulières et Automates finis Implémentation des scanners

Taches d’un scanner 1. Délivre les symboles terminaux (unités lexicales) scanner IF, LPAR, IDENT, EQ, NUMBER, RPAR, ..., EOF i f ( x = = 3 ) Source Unités lexicales 2. Saute les caractères non significatifs blancs Caractères de tabulation Caractères de fin de lignes (CR, LF) Commentaires Les unités lexicales ont une structure syntaxique ident = letter { letter | digit }. number = digit { digit }. if = "i" "f". eql = "=" "=". ...

Pourquoi la phase lexicale est séparée de la phase syntaxique? Entrainerait une analyse syntaxique plus compliquée (Ex. distinction difficile entre les mots clés et les identificateurs) Statement = ident "=" Expr ";" | "if" "(" Expr ")" ... . On doit écrire ceci comme suit Statement = "i" ( "f" "(" Expr ")" ... | letter {letter | digit} "=" Expr ";" ) Le scanner doit éliminer les caractères non significatifs Ces caractères peuvent apparaître partout => conduiraient vers des grammaires très complexes) Statement = "if" {Blank} "(" {Blank} Expr {Blank} ")" {Blank} ... . Blank = " " | "\r" | "\n" | "\t" | Comment. Les unités lexicales peuvent être decrites à l‘aide de grammaires régulières (Plus simple et plus efficace que les grammaires à contexte libre)

Analyse lexicale Taches d‘un scanner Grammaires Régulières et Automates finis Implémentation des scanners

Grammaires régulières Définition Une grammaire est dite régulière si elle peut être décrite par des productions de la forme: A = a. A = b B. a, b des TS A, B des NTS Exemple Grammaire pour les identificateurs Ident = letter | letter Rest. Rest = letter | digit | letter Rest | digit Rest. Ex., dérivation de xy3 Ident => letter Rest => letter letter Rest => letter letter digit Autre définition Une grammaire est dite régulière si elle peut être décrite par une simple non récursive production EBNF. Exemple Grammaire pour les identificateurs Ident = letter { letter | digit }.

Exemples Peut-on transformer la grammaire suivante en une grammaire régulière? Après substitution de F dans T T = id { "*" id }. E = T { "+" T }. T = F { "*" F }. F = id. Après substitution de T dans E E = id { "*" id } { "+" id { "*" id } }. La grammaire est régulière Peut-on transformer la grammaire suivante en une grammaire régulière? E = F { "*" F }. F = id | "(" E ")". Après substitution de F dans E E = ( id | "(" E ")" ) { "*" ( id | "(" E ")" ) }. Substituer E dans E ne mène à rien. Récursion centrale ne peut être éliminée. La grammaire est non régulière.

Limitations des grammaires régulières Les grammaires régulières ne traitent pas les structures emboîtées Raison : ne peut éliminer la récursion centrale! La récursion centrale est importante dans les langages de programmation. Expressions emboîtées Instructions emboîtées Classes emboîtées Expr => ... "(" Expr ")" ... Statement => "do" Statement "while" "(" Expr ")" Class => "class" "{" ... Class ... "}" Solution : utilisation des grammaires à contexte libre. Les structures lexicales sont généralement régulières nom letter { letter | digit } nombres digit { digit } Exception: commentaires emboîtés /* ..... /* ... */ ..... */ Le scanner doit les traiter comme cas spécial chaînes "\"" { pas de quote } "\"" Mot-clés letter { letter } opérateurs ">" "="

Expressions régulières Autre notation pour les grammaires régulières Définition 1. e (la chaîne vide) est une expression régulière 2. Un symbole terminal est une expression régulière 3. Si a et b sont des expressions régulières, les expressions suivantes sont régulières: a b (a | b) (a)? e | a (a)* e | a | aa | aaa | ... (a)+ a | aa | aaa | ... Exemples "w" "h" "i" "l" "e" while letter ( letter | digit )* names digit+ numbers

Automate Fini Déterministique (DFA) Peut être utilisé pour analyser les langages réguliers Exemple Table de transition letter digit s0 s1 d error "fini", car d Peut être défini explicitement letter État final letter 1 État initial est 0 par convention digit Définition Un automate fini déterministique est un 5 tuple (S, I, d, s0, F) S Ensemble des états I Ensemble des symboles d‘entrée d: S x I  S Fonction de transition des états s0 État initial F Ensemble des états finaux Le langage reconnu par une DFA est l‘ensemble de toutes les séquences de symboles pouvant être générées de l‘état initial vers l‘un des états finaux. Un DFA reconnaît une phrase (sentence) S‘il est dans un état final Et il n‘y a plus de symboles d‘entrée Ou il n‘ y a pas de transition possible avec le prochain symbole d‘entrée

Le Scanner comme un DFA Le scanner peut être vu comme un grand DFA " " letter Exemple Entrée: max >= 30 letter 1 ident digit s0 s1 m a x Pas de transition avec " " dans s1 ident reconnu digit 2 digit number > = s0 s5 Saute les blancs au début Ne s‘arrête pas en s4 Pas de transition avec " " dans s5 geq reconnu ( 3 lpar > = 4 5 s0 s2 3 0 Saute les blancs au début Pas de transition avec " " dans s2 number reconnu gtr geq ... Après chaque unité lexicale reconnue le scanner recommence à l‘état initial s0

Transformation: grammaire régulière vers DFA Une grammaire régulière peut être transformée en un DFA comme suit A = b C.  b A C A = d.  d A stop Exemple Grammaire A = a B | b C | c. B = b B | c. C = a C | c. Automate b c A B a C b stop c a c

Automate Fini Non Déterministique (NDFA) Exemple intNum intNum = digit { digit }. hexNum = digit { hex } "H". digit = "0" | "1" | ... | "9". hex = digit | "A" | ... | "F". digit Non déterministique car Il y a 2 possibles transitions avec digit dans s0 1 digit digit H 2 3 hexNum hex Chaque NDFA peut être transformé en un DFA équivalent 1 digit 2 A,B,C,D,E,F hex H 3 intNum hexNum

Implémentation d‘un DFA (Variante 1) Implémentation de d comme une matrice int[,] delta = new int[maxStates, maxSymbols]; int lastState, state = 0; // DFA starts in state 0 do { int sym = next symbol; lastState = state; state = delta[state, sym]; } while (state != undefined); assert(lastState in F); // F is set of final states return recognizedToken[lastState]; Exemple pour d 2 a 1 c b A = a { b } c. A d a b c 0 1 - - 1 - 1 2 2 - - - F int[,] delta = { {1, -1, -1}, {-1, 1, 2}, {-1, -1, -1} }; Cette implémentation pourrait être très inefficace pour un véritable scanner

Implémentation d‘un DFA (Variante 2) c 1 2 A b Coder les états dans le code source int state = 0; loop: for (;;) { char ch = read(); switch (state) { case 0: if (ch == 'a') { state = 1; break; } else break loop; case 1: if (ch == 'b') { state = 1; break; } else if (ch == 'c') { state = 2; break; } case 2: return A; } return errorToken; en Java c‘est plus fatiguant: char ch = read(); s0: if (ch == 'a') { ch = read(); goto s1; } else goto err; s1: if (ch == 'b') { ch = read(); goto s1; } else if (ch == 'c') { ch = read(); goto s2; } s2: return A; err: return errorToken;

Analyse lexicale Taches d‘un scanner Grammaires Régulières et Automates finis Implémentation des scanners

Interface du Scanner Initialisation du scanner class Scanner { static void Init (TextReader r) {...} static Token Next () {...} } Scanner.Init(new StreamReader("myProg.zs")); Initialisation du scanner Token t; for (;;) { t = Scanner.Next(); ... } Lecture des unités lexicales

Unités lexicales Exemple de codage pour un langage particulier class Token { public const int NONE = 0, IDENT = 1, …. int kind; // token code int line; // token line (for error messages) int col; // token column (for error messages) int val; // token value (for number and charCon) string str; // token string (for numbers and identifiers) } PLUS = 4, /* + */ MINUS = 5, /* - */ TIMES = 6, /* * */ SLASH = 7, /* / */ REM = 8, /* % */ EQ = 9, /* == */ GE = 10, /* >= */ GT = 11, /* > */ LE = 12, /* <= */ LT = 13, /* < */ NE = 14, /* != */ AND = 15, /* && */ OR = 16, /* || */ Exemple de codage pour un langage particulier const int NONE = 0, IDENT = 1, NUMBER = 2, CHARCONST = 3, ASSIGN = 17, /* = */ PPLUS = 18, /* ++ */ MMINUS = 19, /* -- */ SEMICOLON = 20, /* ; */ COMMA = 21, /* , */ PERIOD = 22, /* . */ LPAR = 23, /* ( */ RPAR = 24, /* ) */ LBRACK = 25, /* [ */ RBRACK = 26, /* ] */ LBRACE = 27, /* { */ RBRACE = 28, /* } */ BREAK = 29, CLASS = 30, CONST = 31, ELSE = 32, IF = 33, NEW = 34, READ = 35, RETURN = 36, VOID = 37, WHILE = 38, WRITE = 39, EOF = 40; Erreur Classes des unités Opérateurs et caractères spéciaux Mot-clés Fin de fichier

Implémentation des Scanner Variables statiques dans le scanner static TextReader input; // input stream static char ch; // next input character (still unprocessed) static int line, col; // line and column number of the character ch const int EOF = '\u0080'; // character that is returned at the end of the file Init() public static void Init (TextReader r) { input = r; line = 1; col = 0; NextCh(); // reads the first character into ch and increments col to 1 } NextCh() static void NextCh() { try { ch = (char) input.Read(); col++; if (ch == '\n') { line++; col = 0; } else if (ch == '\uffff') ch = EOF; } catch (IOException e) { ch = EOF; } } ch = prochain caractère d‘entrée retourne EOF si fin de fichier incrémente line et col

Method Next() nom, mot-clés nombres unité simple unités composée public static Token Next () { while (ch <= ' ') NextCh(); // skip blanks, tabs, eols Token t = new Token(); t.line = line, t.col = col; switch (ch) { case 'a': ... case 'z': case 'A': ... case 'Z': ReadName(t); break; case '0': case '1': ... case '9': ReadNumber(t); break; case ';': NextCh(); t.kind = Token.SEMICOLON; break; case '.': NextCh(); t.kind = Token.PERIOD; break; case EOF: t.kind = Token.EOF; break; // no NextCh() any more ... case '=': NextCh(); if (ch == '=') { NextCh(); t.kind = Token.EQ; } else t.kind = Token.ASSIGN; break; case '&': NextCh(); if (ch == '&') { NextCh(); t.kind = Token.AND; } else t.kind = NONE; case '/': NextCh(); if (ch == '/') { do NextCh(); while (ch != '\n' && ch != EOF); t = Next(); // call scanner recursively } else t.kind = Token.SLASH; default: NextCh(); t.kind = Token.NONE; break; } return t; } // ch holds the next character that is still unprocessed nom, mot-clés nombres unité simple unités composée commentaire caractère invalide

Autres méthodes static void ReadName (Token t) Au début ch contient la première lettre du nom Lit les prochaines lettres, digits et '_' et les range dans t.str Chercher le nom dans la table des mots clés ( hash-code ou arbre de recherche binaire ) si trouvé: t.kind = code du mot clé; sinon: t.kind = Token.IDENT; À la fin, ch contient le premier caractère après le nom static void ReadNumber (Token t) Au début ch contient le premier chiffre du nombre Lit les prochains digits, les range dans t.str; puis convertit la chaîne en un nombre et range la valeur dans t.val. Si débordement: Erreur t.kind = Token.NUMBER; A la fin ch contient le premier caractère après le nombre

Considérations d‘efficacité Taille d‘un programme modeste Aux environs de 1000 instructions  environ 6000 unités  environ 60000 caractères La phase lexicale consomme un temps important prend 20-30% du temps total de compilation Faire attention à la programmation Utiliser les variables globales : Ex.: ch est global et non un paramètre de NextCh() Pour les grands fichiers d‘entrée, c‘est judicieux d‘utiliser des lectures bufférisées Stream file = new FileStream("MyProg.zs"); Stream buf = new BufferedStream(file); TextReader r = new StreamReader(buf); Scanner.Init(r);