G n rateurs de compilateurs
Sponsored Links
This presentation is the property of its rightful owner.
1 / 29

Générateurs de compilateurs PowerPoint PPT Presentation


  • 65 Views
  • Uploaded on
  • Presentation posted in: General

Générateurs de compilateurs. Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI) http://zegour.esi.dz / email: [email protected] Générateurs de compilateurs Introduction Yacc Lex Coco/R. générateur scanner. scanner. Spécification du scanner Ex. grammaire régulière).

Download Presentation

Générateurs de compilateurs

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Générateurs de compilateurs

Pr ZEGOUR DJAMEL EDDINE

Ecole Supérieure d’Informatique (ESI)

http://zegour.esi.dz/

email: [email protected]


Générateurs de compilateurs

Introduction

Yacc

Lex

Coco/R


générateur

scanner

scanner

Spécification du scanner

Ex. grammaire régulière)

générateur

de l’analyseur

Analyseur

Spécification sémantique

(Ex. grammaire d’attribut)

Générateur

De compilateurs

Exemples

Yaccgénérateur d’analyseur syntaxique et sémantique pour C et Java

Lexgénérateur de scanner pour C, Java et C#

Coco/Rgénérateur de scanner et d’analyseur pour Java, C#, Modula-2, Oberon, ...

...

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 , ...)

compilateur

& éditeur de liens

compilateur

généré

  • Classes utilisateur

  • Table des symboles

  • Générateur de code

  • Programme principal

  • ...


Générateurs de compilateurs

Introduction

Yacc

Lex

Coco/R


Utilisation

Yacc

javac

sample.y

parser.java

parser.class

Versions actuelles

Bisonversion GNU de Yacc

http://www.gnu.org/software/bison/bison.html

ByaccBerkeley Yacc

http://byaccj.sourceforge.net/

Yacc - Yet another compiler 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

Nous décrivons ici la version de Java


class parser {

...

public void yyparse() {

... parser ...

}

}

Traduit vers

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)


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

$iattribut du i-ème symbole du coté droit

($1 = attr. du premier symbole, $2 = attr. du second symbole, ...)

Yacc — Productions et actions sémantiques

Productions

Grammar= {Production}.

Production= NT ":" Alternative {"|" Alternative} ";"

Alternative= {NT | T} [SemAction].

SemAction= "{" ... arbitrary Java statements ... "}".

NT= ident.

T= ident | charConst.

Exemple

expr:term{ $$ = $1; }

|expr '+' term{ $$.ival = $1.ival + $3.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 — 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

Accès dans une action sémantique

yylval = new parserval(n);

{ ... $1.ival ... }


Yacc — Variables et Méthodes Java

Sont déclarées après le second %%

%{ ... imports ... %}

... Unités ...

%%

... Productions ...

%%

... DéclarationsJava ...

  • 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

Pour afficher les messages d’erreur

void yyerror(String msg) {...}

Scanner (retourne les codes des unités

et remplit yylval)

int yylex() {...}

public static void main(String[] arg) {

... initializations for yylex ...

yyparse();

}

Programme principal


Exemple: Compilateur pour les expressions arithmétiques

Conventions de codage des unités

/* 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{ $$ = $1; }

| expr '+' term{ $$.ival = $1.ival + $3.ival; } ;

term: factor{ $$ = $1; }

| term '*' factor{ $$.ival = $1.ival * $3.ival; } ;

factor: number{ $$ = $1; }

| '(' expr ')'{ $$ = $2; } ;

%%

int yylex() {...}

void yyerror(string msg) {...}

public static void main(String[] arg) {...}

  • 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é.


On peut aussi l’exprimer comme suit en Yacc:

%tokennumber

%left'+'

%left'*'

%%

input: expr{ System.out.println($1.ival); } ;

expr: number{ $$ = $1; }

| expr '+' expr{ $$.ival = $1.ival + $3.ival; }

| expr '*' expr{ $$.ival = $1.ival * $3.ival; }

| '(' expr ')'{ $$ = $2; }

%%

...

  • %left: l’opérateur est associatif gauchea+b+c == (a+b)+c

  • Les opérateurs sont déclarés en ordre

  • ascendant de priorité: '*' a une précédence sur '+'

  • 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 — Précédence des opérateurs

La grammaire suivante spécifie explicitement la précédence des opérateurs

  • '*' a une précédence sur '+'

  • Les opérateurs sont associatifs à gauche: a*b*c == (a*b)*c

expr:term | expr '+' term ;

term:factor | term '*' factor ;

factor:number | '(' expr ')' ;


Exemple

Statement = ...

| error ';' ;

Saute tout jusqu’au prochain ';'

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 : errora)

  • Il réduit errora à A et exécute l’action sémantique correspondante


Générateurs de compilateurs

Introduction

Yacc

Lex

Coco/R


Utilisation

Nous decrivons ici la version C

Lex

sample.l

sample.yy.c

include

Yacc

C-Compiler

sample.y

sample.tab.c

sample.o

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/

CsLexversion C# , dérivé de JLex

http://www.cybercom.net/~zbrad/DotNet/Lex

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


Exemple de description Lex

%{ ... e.g. include directives for token numbers exported by the parser ... %}

/* macros */

delim[ \t\n]/* 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 = storeId(yytext, yyleng); return ID; }

{number}{ yylval = convert(yytext, yyleng); return number; }

<{ return yytext[0]; }

>{ return yytext[0]; }

.{}/* . denotes any character */

%% /* semantic routines */

int storeId(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;/* attribute if the token has a numeric value */

char* yytext;/* token text (attribute of ident, string, ...) */

int yyleng;/* lengh of the token text */

int yylineno;/* line number of the token */

L’analyseur déclare (et exporte) les codes des unités

%token IF

%token THEN

...


Expressions régulières dans Lex

Éléments des expressions régulières

abcla chaîne "abc"; tout caractère sauf ()[]{}*+?|^$.\ dénote lui-même

.Tout caractère sauf \n (fin de ligne)

x*0 ou plusieurs répétitions de x

x+1 ou plusieurs répétitions de x

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-z0-9$])

{...}Utilise d’une macro

^ligne début

$ligne fin

\uddddcaractère en Unicode


Générateurs de compilateurs

Introduction

Yacc

Lex

Coco/R


Utilisation

main

grammaire

d’attribut

Coco/R

parser

csc

scanner

Classes utilisateurs

(Ex. Table des symboles)

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/


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.WriteLine(x); .) .

Expr<out int x>(. int y; .)

=Term<out x>

{ '+' Term<out y>(. x = x + y; .)

}.

Term<out int x>(. int y; .)

=Factor<out x>

{ '*' Factor<out y>(. x = x * y; .)

}.

Factor<out int x>

=number(. x = Convert.ToInt32(t.val); .)

|'(' Expr<out x> ')'.

END Calc.


Les symboles non terminaux

  • Les NTS peuvent avoir des attributs d’entrée

Attr. formels:

Attr réels.:

A<int x, char c> = ... .

... A<y, 'a'> ...

  • Les NTS peuvent avoir des attributs de sortie

B<outint x, outint y> = ... .

... B<out z, out n> ...

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 (. x = Convert.ToInt32(t.val); .)

class Token {

int kind;// token code

string val;// token value

int pos; // token position in the source text (starting at 0)

int line;// token line (starting at 1)

int col;// token column (starting at 0)

}


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 myList;

static void AddToList (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 — 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

déclaration

Term<out int x>(. int y; .)

=Factor<out x>

{ '*' Factor<out y>(. x = x * y; .)

}.

action sémantique


Coco/R – les méthodes d’analyse

Chaque production est traduite en une méthode de l’analyseur

Expr<out int x>(. int y; .)

=Term<out x>

{ '+' Term<out 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;

}

}


Séparateurs faibles

Les séparateurs au début d’une itération peuvent être marqués comme Weak (faibles)

FormalPars

= "(" 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) U Suivant({...}) U{eof}

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

|IfSatement

|...

).

if la.kind dans Suivant(SYNC)

une erreur est reportée et des unités sont sautées

jusqu’à la.kind dans Suivant(SYNC) U {eof}

Les faux messages d'erreur sont supprimés si moins de 3 unités

ont été reconnues depuis la dernière erreur.


Coco/R — Tests de grammaire

Test LL(1)

Coco/R affiche les avertissements suivants

A=a [B] C d

|B a.

B= a b.

C= a [d].

LL1 warning in A: a is start & successor of deletable structure

LL1 warning in A: a is start of several alternatives

LL1 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 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

PrintOption= "$print".(. option[print] = true; .)

DbgOption= "$debug". (. option[debug] = true; .)

...

Quand la chaine

$print

apparaît dans le texte d’entrée l’action sémantique

option[print] = true;

est exécutée


Dans les productions

Il décrit tout unité qui ne peut être produite par les autres alternatives

PlaceHolder

= ident

|ANY.

Tout unité qui n’est pas ident ou eof

Tout unité qui n’est pas ".)" ou eof

SemAction = "(." { ANY } ".)".

Coco/R — le symbole ‘ANY’

Dans la déclaration des ensembles de caractères

Il décrit des ensembles de caractères complémentaires

CHARACTERS

letter = 'A' .. 'Z' + 'a' .. 'z'.

noLetter = ANY - letter.

...

Tous les caractères qui ne sont pas des lettres


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 eofSym = 0;

-->declarations

...

static Token NextToken () {

while (ignore[ch]) NextCh();

-->scan1

t = new Token();

t.pos = pos; t.col = pos - lineStart + 1; t.line = line;

int state = start[ch];

StringBuilder buf = new StringBuilder(16);

-->scan2

...

}

...

}

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 sourceFileName) {...}

public static void Init (Stream s) {...}

public static TokenScan () {...}

public static TokenPeek () {...}

public static void ResetPeek () {...}

}

Parser

public class Parser {

public static Tokent;

public static Tokenla;

public static void Parse () {...}

public static voidSemErr (string msg) {...}

}

Error message class

public class Errors {

public static int count = 0;

public static string errMsgFormat = "-- line {0} col {1}: {2}";

public static void SynErr (int line, int col, int n);

public static void SemErr (int line, int col, int n);

public static void Error (int line, int col, string msg);

public static void Exception (string msg);

}


  • Login