Compilation Analyse Syntaxique

Download Report

Transcript Compilation Analyse Syntaxique

Langages et Documents
Traitements des textes « sources »
Langages de Programmation
Documents Structurés
Paul Franchi
SI - 4
2014-15
1
Quelques dates

1957-68

1968
1969
1972
1974
1975
1979-83
1980
1981
1982
1984
1985
1983-86
1987
1989
1990
1991
1993
1995
19951996
2004
2008
2010
2010























Fortran, Cobol, Lisp, Algol, APL, PL/I,
Basic
Pascal, Simula, Algol 68
Multics  Unix
B  C, Prolog, Lex, Yacc
DOS, TeX
Scheme
Green (DoD) => Ada
Smalltalk, Modula 2
MS-DOS
PostScript, LaTeX
Lisa => Mac & Souris
Windows
C++
Perl, SQL
ANSI C, Modula 3
Mosaic + HTML
Unix  Linux, Python
PDF
Java, Windows
AltaVista, MSN, Yahoo, etc.
SGML  XML, JavaScript
iTunes, iPod
Google = 100 Gigas$
iPod x 275 Millions
Apple = 225 Giga$ > Microsoft
Transparent 3
Langages de Programmation
Analyse lexicale
Traitements « source to source »
Documents Structurés
Modèles SGML, DTD, DOM
Langages HTML, XML, CSS
Transformations XSLT
Navigateurs
Editeurs & Outils
Transparent 4
Compilation
Analyses Lexicale, Syntaxique, et
Sémantique
Chapitres 1 & 2
Paul Franchi
SI deuxième année
2014-15
5
Sommaire
1. Introduction à la compilation
2. Analyse lexicale
3. Rappels sur les langages formels
4. Analyse syntaxique non déterministe
5. Analyse syntaxique descendante
6. Analyse syntaxique ascendante
7. Traduction dirigée par la syntaxe
8. Générateurs LR()
9. Sémantique statique des L.P.
10. Traitements «source to source»
Transparent 6
Chapitre 1
Introduction à la Compilation
Historique
 Schéma conceptuel
 Phases et passes
 Structures et langages
intermédiaires
 Méta-compilation

7
Conception: modèle Analyse et
Synthèse

Traduire un programme source
dans un langage cible
 analyse le programme conformément à la
définition du langage source
 produit d’éventuels messages d’erreurs
 synthétise un code équivalent au
programme source dans le langage cible

Schéma fonctionnel
Source
Compilateur
Partie
Avant
Cible
Partie
Arrière
Messages d’erreurs
Transparent 8
Phases & Passes


Une phase est une étape conceptuelle du
processus de compilation
Une passe regroupe des traitements
nécessitant un parcours complet du source
(ou de la représentation associée)
Source
A. lexicale
A. syntaxique
S
y
m
b
o
l
e
s
A. sémantique
G. code intermédiaire
Optimiseur de code
E
r
r
e
u
r
s
G. de code
Cible
Transparent 9
Phase lexicale : fonctionnalités

Traiter le texte source à l’entrée
 découpe le texte en unités lexicales
conformément à la définition lexicale du
langage compilé
 élimine (éventuellement) certaines unités
inutiles

Schéma fonctionnel
Erreurs.
Lexèmes
Source
Anal. Lex
Arbres
Anal. Synt.
requête
Table
Symbôles.
Identificateurs
Source
instrumenté.
Transparent 10
Phase lexicale : pourquoi la séparer
de la phase syntaxique ?

Avantages:
 Conception modulaire de l’architecture
logicielle
 Indépendance phases/passes
 Performances des analyseurs
 en temps
 en mémoire
 Evolutivité du compilateur vis à vis du
langage source

Autres applications hors
compilation:
 Traitement de texte et des documents
 Codage des données
 sécurité
 compression
 Recherche de motifs
 KMP
 Programmation spécialisée
Transparent 11
Phase syntaxique

Fonctions
 Déterminer l’appartenance à un langage
 Produire un arbre (de dérivation) et
d’éventuels messages d’erreurs

Analyse descendante récursive
 multipasse de gauche à droite
 construction de l’arbre avec ou sans
backtracking
 complexité : O(|règles||source|)

Analyse (déterministe) descendante
 une seule passe de gauche à droite
 construction de l’arbre en descendant à
partir de la racine
 meilleure complexité : O(|source|)

Analyse (déterministe) ascendante
 une seule passe de gauche à droite
 construction de l’arbre en montant à partir
des feuilles
 meilleure complexité : O(|source|)
Transparent 12
Phase sémantique statique

Actions sémantiques synchronisées
par A.S.
 compilation en une seule passe
 Attributs synthétisés seulement

Actions sémantiques dirigées par la
syntaxe
 compilation multipasse
 Attributs synthétisés et hérités

Sémantique statique
 portée, visibilité, typage
 décompilation
 transformations au niveau du source
Transparent 13
Compilation et Théories

Référence de langages
 Définition formelle non ambiguë
 Systèmes générateurs
Expressions régulières
Grammaires

Reconnaissance des programmes
 Déterminisme
 Performance (complexité)
 Classes de langages
Automates finis
Automates à pile
Langages hors contexte

Sémantique
 Spécifications exécutables & Générateurs
 Optimisation
Langages à contexte
Graphes
Systèmes logiques
Transparent 14
Métacompilation
« compiler-compiler »
Grammaire
lexicale
de L
Lexical
Grammaire
syntaxique
de L
Parser
Définitions
& actions
sémantiques
L -> 
Trans
lator
G
E
N
E
R
A
T
O
R
C
O
M
P
I
L
A
T
E
U
R
L -> 
Transparent 15
Archicture des compilateurs:
Evolution et autres applications

Documents
 XML, DOM, XSLT

Communication par une API
intermédiaire
Source
Compilateur
Edition
Cible
Décompilation
Partie Avant
Cible
Transformations
Compilateur
Cible
Partie Arrière
Cible
Transparent 16
Chapitre 2
Analyse lexicale
2.1 les bases théoriques de
l’implémentation
 2.2 lex: un méta_générateur
lexical
 2.3 lex: des exemples de base

17
Analyse lexicale :
le découpage d’un source Java
class Pile {
// lexicalement correct
public int hauteur () {
if vide() return 0;
return 1+ this.depile().hauteur()
}
}
#11:
Pile
<class> < id,11> <{>
<public> <int> < id,13> <(> <)> <{>
< if> < id,1> <(> <)> <return> <ce,0> <:>
<return> <ce,1> <op,+> <this> <.>
< id,2> <(> <)> <.> < id,13> <(> <)> <}> <}>
Transparent 19
Section 2.1
les bases théoriques de
l’implémentation
Expressions régulières
Grammaires régulières
Langages rationnels
Automates finis
Déterminisme
20
Analyse lexicale :
les outils de l ’implémentation

Les outils théoriques:
 Langages réguliers:
 Expressions régulières
 lexèmes (« tokens »)
 Grammaires régulières
 symboles terminaux
 Automates finis:
 déterministes
 non déterministes
 transducteurs

Les outils logiciels
 Les générateurs lexicaux :
 lex, flex, javalex, …
 grep, egrep, fgrep, ...
 sed, awk, ...
 Langages de programmation
 Grafcet, Esterel
 Perl, Python, Java, JavaScript, Php.
 Langages de Documents
 XPath, XSL, DTD, XSD
Transparent 21
Langages Rationnels (Réguliers)

Grammaires régulières (linéaires)

Expressions étendues(lex)

Expressions régulières

Automates finis indéterministes

Automates finis déterministes
Transparent 22
Implémentation des Générateurs
d'Analyse Lexicale

Source
 format général
/*exp
ek

exemple
actions */
a
abb
a*b+
ak;
;
;
;
AFND


0
a
1
2
a
3
b
4
5
b
6

b
7
8
b

AFD
0137
a
b
247
58
b
68
a
b
7
b
b
8
b
Transparent 23
Section 2.2
lex: un méta-générateur lexical
24
lex : un générateur lexical

lex est un méta-compilateur pour
grammaires lexicales
Table
Transitions
AF(N)D
[ section de définitions ]
%%
[ section des règles:
ExpReg Actions ]
[ %%
code de l ’utilisateur ]

Analyseur
(N)D
Sorties
 analyseur lexical en C: lex.yy.c
 une fonction de découpage: yylex()

Utilisation sous unix
source.lex
lex
lex.yy.c
cc
a.out
Transparent 25
Définition des Expressions régulières

Alphabets:
 codes ISO, ASCII, etc

Expressions régulières
 forme de Kleene via des méta-opérateurs
(concaténation, le  est omis )
| (alternative)
(répétition)
()
 exemple: les identificateurs C
 Id = (a|b|..|z|A|..|Z|_) (a|b|..|z|A|..|Z|_|0|..|9)

Expressions régulières étendues
 méta-opérateurs
 [] - + ? 
 "" \
^
 exemples




les entiers: [0-9]+
les identificateurs C: [a-zA-Z_] [a-zA-Z0-9_]
les chaînes de caractères sans " : \" [^"] \"
les commentaires lignes Java: "/ /"
Transparent 26
Les caractères de lex

Les caractères terminaux
 tous les caractères, sauf les spéciaux
 l ’espace est significatif
 les spéciaux doivent être protégés par " " ou \

Les caractères spéciaux (méta-)
e?
e*
e+
ef
e|f
e{n,m}
(e)
{D}
e/f
^e
e$
<E>e
.
\c
"abc"
[abc]
[^abc]
[a-c]
Forme de Kleene
0 ou 1 fois l’exp e
0 ou n fois l’exp e
1 ou n fois l’exp e
l'exp e f
l'exp e ou l'exp f
l'exp e répétée entre n et m fois
l'exp e
l'exp obtenue par substitution de D
Contexte sensitivité
l'exp e si suivie de l'exp f
exp e en début de ligne
exp e en fin de ligne
L'exp e si dans l'état E
Caractères
tout caractère sauf \n
le caractère c , même spécial
la chaine de caractères abc
le caractère a ou b ou c
un des caractères sauf a, b, c
le caractère a ou b ou c
Transparent 27
Méta-langage et syntaxe de Lex
/* Section Définitions (optionnelle)*/
Définitions lex /* optionnelles */
/* à substituer dans les règles Lex */
%{ /* obligatoirement en début de ligne */
Définitions en langage C ou C++
/* seront insérées telles quelles
dans le code généré par Lex*/
%} /* obligatoirement en début de ligne */
Définitions lex /* optionnelles */
/* à substituer dans les règles Lex */
/* Section Règles ci-dessous:
attention: commentaires ligne possibles seulement
après les actions */
%%
expressions lex
{instructions C} /* … */
%%
/* Section Code utilisateur (optionnelle)*/
Code C de l ’utilisateur & main()
/*à insérer dans le code généré par lex*/
/* retour chariot obligatoire à la fin du flot d'entrée*/
Transparent 28
Exécution (simplifiée) d'un analyseur Lex
public Flot scan() { // this est un flot d'entrée
Flot FSortie: new Flot();
CC=CD= debut();
while( !EOF() && ulex(CD,CC).rec() ) {CC++;}
if ( !EOF() || ulex(CD,CC-1).rec() )
if (CD==CC) { FSortie.app(CC); CD=++CC;}
else {exec(ulex(CD,CC-1).regle()); CD=CC;}
return FSortie;
}
Lexème le + long possible
CCCCCCCCCCCCCCCCCCCCC
CD
CC
E1 -> A1
Transparent 29
Format (non convivial!) de Lex

Espaces ou tabulations
 ni en début de ligne, ni dans les expressions
 obligatoire entre expressions et actions

commentaires
 dans les blocs {}
 seulement en fin de ligne dans les Règles

Substitution des { }
 attention aux priorités après substitution

Passage à la ligne impossible
 sauf | pour "factoriser" des règles

Erreurs classiques
 exp;
 [public|private]
 ["class"]
 [^"class"]
 ALPHA
ID
({L}|{C} )
{L} ( {ALPHA} ) *
Transparent 30
Lex: variables, fonctions et macros

Analyseur lexical
 yylex() – la fonction d’analyse
 yywrap() – après l'analyse du texte en
entrée

Le « token » en cours
 char *yytext
 int yyleng

Etats ou contexte gauche
 %START %s %x
 BEGIN
Transparent 31
Lex: modifier le fonctionnement

Modifier le découpage
 yymore() – concatène les tokens successifs
 yyless(int n) – retour arrière de yyleng - n
 REJECT – ressaye les autres
reconnaissances possibles par les autres
règles

Entrées/Sorties de caratères
 input() – lit le prochain caractère
 output(char c) – écrit c
 unput(char c) – met c dans le flot d’entrée
 ECHO – écrit le token courant
Transparent 32
Lex & flex: compléments (1)

Sur les Etats
 INITIAL ou 0
 <*>
– tous les états, y compris 0
 <A,B,C> – «start conditions» multiples
 <A> {
 Exp1 R1 ;
 Expn Rn ;
}
– règles multiples
 YY_START – l’état courant YYSTATE

Avec une (la) pile des états
 %option stack – accès à la pile des états
 yy_push_state(s), _pop_ => BEGIN
 yy_top_state() # de YY_START

<<EOF>>
 <<EOF>> – règle spéciale sur fin de fichier
 yyterminate() – fin d’analyse
 yyin=fopen(*fliste, «r») – chang. de fichier
Transparent 33
Exécution d'un analyseur Lex
Lexème le + long possible
CCCCCCCCCCCCCCCCCCCCC
CD
REJECT
yyless()
yymore()
yyterminate()
CC
E1 -> A1
état
valide
BEGIN
yy_pop_
yy_top_
yy_push_
YY_USER_
"désarmées"
état
invalide
Transparent 34
Lex & flex: compléments (2)

échappements caractères
 \176
 \x7E

// le caractère ~ en Octal
// le caractère ~ en Hexa
options de "pattern matching"
 i et -i – sensibilité à la casse
 x et -x – ignore les blancs et commentaires
 s et -s – . avec ou sans \n

classes caractères
 [:digit:] – comme 0-9
 [:alnum:] – comme 0-9a-zA-Z
 [[:digit:][:alpha:]] – comme [0-9a-zA-Z]
 [[:^digit:]] – comme [^0-9]
Transparent 35
Lex & flex: compléments (3)

La ligne courante
 %option yylineno – gestion de la ligne
courante

Sur les règles de l’analyseur
 yy_act – le numéro de la règle activée
 YY_NUM_RULES – le nombre total de
règles

Routines Utilisateur
 YY_USER_INIT – à faire avant l’analyse
 YY_USER_ACTION -- à faire à chaque
règle

Fichiers
 *yyin – FILE en entrée
 *yyout – FILE en sortie
 yyrestart (FILE *new_file) – FILE
Transparent 36
Section 2.3
Lex: des exemples de base
Identificateurs, mots clés,
commentaires, chaînes de
caractères,
des L.P.
38
lex : les identificateurs Ada

Expression étendue:
[a-zA-Z](_?[a-zA-Z0-9])*

Source lex
/* définitions lex*/
LET
[a-zA-Z]
CHIF
[0-9]
ALPNUM ({LET}|{CHIF})
%% /* règle sans action*/
{LET}(_?{ALPNUM})*
;
%%
Transparent 39
lex : les identificateurs Java

Expression étendue:
[a-zA-Z_$ ] [a-zA-Z0-9_$] *

Source lex
/* définitions */
LET
[a-zA-Z_$]
CHIF
[0-9]
ALPNUM
({LET}|{CHIF})
%% /* règle sans action*/
{LET}({ALPNUM}) *
;
%%
Transparent 40
lex : les chaînes de caractères
en Ada

Expression ambigüe:
 ".  "
 => accepte tous les caractères sur une
ligne, y compris donc plusieurs " avant le "
le plus à droite
 => ambiguïté:
 " chaine1 " ++ " chaine2 " ++ " chaine3 "

Expression correcte
%% /* règle sans action*/
\" ( [^ " \n ] | \" \" ) \" ;
%%
Transparent 41
lex : les chaînes de caractères
en C et Java

Expression ambigüe:
 ".  "
 => accepte tous les caractères sur une
ligne, y compris donc plusieurs " avant le " le
plus à droite
 => ambiguïté:
 " chaine1 " ++ " chaine2 " ++ " chaine3 "

Expression correcte
%% /* règle sans action*/
%%
Transparent 42
lex :
mots clés, entiers, identificateurs C

Source lex
CHIF
[0-9]
ENTSIG
("-"|"+")?{CHIF} +
IDENT
[a-zA-Z_][a-zA-Z_0-9]
MC1
auto | extern | static | typedef | register
MC2
short | int | long | char | float | double
MC3
if | else | do | while | for | case | switch
MC4
default | return | break | continue | goto
MC
{MC1} | {MC2} | {MC3} | {MC4}
%%
{ENTSIG}
{printf("%d\n", atoi(yytext)) ;}
{IDENT}
{printf("%s\n", yytext) ;}
{MC}
{printf( "mclé: %s\n", yytext) ;}
[ \t\n]+
; /* caractères ignorés */
.
{fprintf(stderr, "car. invalide:
%s\n", yytext) ;}
%%
Transparent 44
lex : les commentaires en C
forme /* */
Expression ambiguë:

 " / " .  "/ "
 => accepte tous les caractères dans le
commentaire, y compris donc plusieurs / avant
le / le plus à droite
 => ambiguïté:
 /com1/ ++ /com2/ ++ /com3/

Expression Régulière Lex

Source lex (avec un état exclusif)
%x COM
%%
?
?
Transparent 45
lex : les commentaires en C
forme /* */

Expression ambiguë:
 " / " .  "/ "
 => accepte tous les caractères dans le
commentaire, y compris donc plusieurs /
avant le / le plus à droite
 => ambiguïté:
 /com1/ ++ /com2/ ++ /com3/

Expression correcte

Source lex(avec un état inclusif)
%s COM
%%
?
?
?
Transparent 47
Unités lexicales imbriquées en lex

Reconnaissance imbriquées ou non ?
 Mots réservés et identificateurs
 Mots réservés dans/hors les commentaires
 Mots réservés dans/hors les chaînes
 Chaînes dans/hors les commentaires
 etc.

Reconnus ou pas ?
MC
if | else | do | while | for | case | switch
%s COM /* ou %x ? */
%%
{MC}
{printf( "mclé: %s\n", yytext) ;}
?
%%
Transparent 49
lex : supprimer les espaces sauf dans
les chaînes (1)

Avec un état exclusif
%x CHA
%%
?
?
Attention:
 les règles 2, 3 et 4 ne sont activables que dans
l'état <CHA>
 dans l'état <CHA>, le lexeme \" est reconnu
par la règle 4 et non pas 1
 les règles 1, 5 et 6 ne sont pas activées dans
l'état <CHA>
 hors de l'état <CHA>, " " est reconnu par la
règle 5 et non pas 6
Transparent 51
lex : supprimer les espaces sauf dans
les chaînes (2)

Avec un état inclusif
%s CHA
%%
?
Attention:
 la règle 1 n'est activable que dans l'état <0>
 les règles 2, 3 et 4 ne sont activables que dans
l'état <CHA>
 dans l'état <CHA>, le lexeme \" est reconnu
par la règle 4 et non pas 1
 les règles 5 et 6 sont activables dans tous les
états
 un lexeme " " est reconnu par la règle 2 dans
l'état <CHA> et par la régle 5 sinon
Transparent 53
lex : compter les éléments d’un texte

Source lex
%{
static int nbCar = 0, nbMot = 0, nbLig = 0;
%}
MOT
EOL
%%
{MOT}
{EOL}
.
[^ \t\n]+
\n
{nbMot++; nbCar +=yyleng;}
{nbLig++; nbCar ++;}
nbCar ++;
%%
main() {
yylex();
printf(« %d %d %d\n », nbLig, nbMot, nbCar);
}
Transparent 55
Section 2.4
Traitement lexical des Textes
par Expressions régulières
awk, grep, find, emacs, etc.
Java
Python
Perl
JavaScript
56
Expressions grep -E -P
e?
e*
e+
ef
e|f
e{n}
e{n,m}
e{n,}
(e)
^e
e$
\<e
e\>
.
\c
"abc"
[abc]
[^abc]
[a-c]
\i
0 ou 1 fois l’exp e
0 ou n fois l’exp e
1 ou n fois l’exp e
l'exp e f
l'exp e ou l'exp f
l'exp e répétée n fois
l'exp e répétée entre n et m fois
l'exp e répétée n fois ou plus
l'exp e ou le groupe e
exp e en début de ligne,
exp e en fin de ligne.
exp e en début de mot
exp e en fin de mot
tout caractère sauf \n
le caractère c , même spécial
la chaine abc
le caractère a ou b ou c
un des caractères sauf a, b, c
le caractère a ou b ou c
répéter le ième groupe( ) reconnu
Transparent 57
Java
Le Paquetage Java.util.regex

Expressions régulières
String expreg

java.util.regex.Pattern
Pattern p = Pattern.compile(expreg)

java.util.regex.Matcher
Matcher m = p.matcher( )
m.find()
m.group()
Transparent 58
Python
Le Module re

expreg = re.compile(' … ')

m = expreg .match(… )

if m

m.group( …)
Transparent 59
Expressions Perl (1)
e?
e*
e+
ef
e|f
e{n}
e{n,m}
e{n,}
(e)
^e
e$
\Ae
e\Z
.
\c
"abc"
[abc]
[^abc]
\d \D
\w \W
[a-c]
\i $i
0 ou 1 fois l’exp e
0 ou n fois l’exp e
1 ou n fois l’exp e
l'exp e f
l'exp e ou l'exp f
l'exp e répétée n fois
l'exp e répétée entre n et m fois
l'exp e répétée n fois ou plus
l'exp e ou le groupe e
exp e en début de ligne,
exp e en fin de ligne.
exp e en début de mot
exp e en fin de mot
tout caractère sauf \n
le caractère c , même spécial
la chaine de caractères abc
le caractère a ou b ou c
un des caractères sauf a, b, c
caractère chiffre ou non
caractère alphanum ou non
le caractère a ou b ou c
le ième groupe( ) reconnu
Transparent 60
Expressions Perl (2)

Les Opérateurs sur Exp. Reg.
 pattern matching (m)
/[0-9]/
m$[0-9]$
 substitution(s)
s+new+old+
s/0/1/
 character translation (tr ou y)
tr/A-Z/a-z/
 pattern binding (~)
$nom =~/Paul/
$nom !~/Paul/
$liste =~ s/Paul/Pierre/g
$liste =~ tr/A-Z/a-z/
Transparent 61
JavaScript 1.5 et + (ECMAScript)
Les expressions (Ecmascript v3, Perl 5 )

la classe RegExp
var motif=/finADroite$/i;
var motif=new RegExp("finADroite$", i);

méthodes
match()
substr()
replace()
split()

Modes
i
g
(ignorer la casse)
(global, donc toutes les occurrences)

Répétition non avide (not "greedy")
??
+?
*?

Groupe seulement (non numéroté)
(? :
Transparent 62
Un modèle d'architecture
partie avant  partie arrière
63