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