Pràctiques Mètodes i Eines de Compilació

35
Pràctiques Mètodes i Eines de Compilació Marc Massot i Bayés [email protected] AM11-S2 Mateu Villaret Auselle [email protected] AM11-S2

description

Pràctiques Mètodes i Eines de Compilació. Marc Massot i Bayés [email protected] AM11-S2 Mateu Villaret Auselle [email protected] AM11-S2. Planificació. Una sola pràctica a realitzar amb el PCCTS. Grups de 2 persones. Entrega de la pràctica abans de cada exàmen de cada Convocatòria. - PowerPoint PPT Presentation

Transcript of Pràctiques Mètodes i Eines de Compilació

Page 1: Pràctiques Mètodes i Eines de Compilació

PràctiquesMètodes i Eines de Compilació

Marc Massot i Bayé[email protected]

AM11-S2

Mateu Villaret [email protected]

AM11-S2

Page 2: Pràctiques Mètodes i Eines de Compilació

Planificació

• Una sola pràctica a realitzar amb el PCCTS. • Grups de 2 persones.• Entrega de la pràctica abans de cada exàmen

de cada Convocatòria.• La nota de la pràctica serà un 30% de la nota

final.• A l’exàmen hi haurà 2 punts amb preguntes

sobre la pràctica.

Page 3: Pràctiques Mètodes i Eines de Compilació

Breu descripció de la Pràctica

• Realitzar un compilador de sentències SQL parametritzades a codi Visual Basic que permeti executar les sentències donades, sobre la base de dades definida, en un entorn de finestres.

Page 4: Pràctiques Mètodes i Eines de Compilació

Etapes d’un procés de Compilació

• Anàlisi lèxica

• Anàlisi sintàctica

• Anàlisi semàntica

• Generació codi intermig

• Optimització de codi

• Generació de codi

Page 5: Pràctiques Mètodes i Eines de Compilació

PCCTS Perdue Compiler Construction Tool Set

• Conjunt d’eines que faciliten la construcció de compiladors i traductors

• Conté dues eines bàsiques:– DLG (DFA-Based Lexical Generator).– ANTLR (Another Tool for Language Recognition)

• Genera codi C++.

Page 6: Pràctiques Mètodes i Eines de Compilació

PCCTS(II)

____.cppantlr

dlg

____.g

____.cpp

____.dlg

Page 7: Pràctiques Mètodes i Eines de Compilació

PCCTS (III)

• Genera un parser descendent. Gramàtiques lliures de contexte LL.

• Procés de compilació dirigit per la sintaxis.

Anàlisi Sintàctica

Anàlisi Lèxica Anàlisi Semàntica Generació de Codi

Page 8: Pràctiques Mètodes i Eines de Compilació

Entorn de treball amb el PCCTS• Crearem un directori de treball on hi posarem el fitxer

<grammar>.g que ens descriurà la classe amb la regla a reconeixer <class>

• Hem de poder compilar i linkar els fitxers en C++ generats pel PCCTS.

• Ho tractarem com a projecte Visual C++, cosa que ens permetrà a l’estil Makefile:– Engegar les comandes d’execució del ANTLR i del DLG.– Compilar i muntar els fitxers generats.

Page 9: Pràctiques Mètodes i Eines de Compilació

Fitxer <grammar>.g<<#include "PBlackBox.h"#include "DLGLexer.h"

typedef ANTLRCommonToken ANTLRToken;

main() { ParserBlackBox<DLGLexer, PrimerParser, ANTLRToken> p(stdin); p.parser()->programa();}>>

// Anàlisi Sintàcticaclass PrimerParser {programa : (~"@")*"@" <<printf("\nFinal de procés.\n");>>;}

// Anàlisi Lèxica ...... ......

Page 10: Pràctiques Mètodes i Eines de Compilació

Lèxic (i)

• Podem utilitzar expressions regulars directament a les regles sintàctiques.

• o podem definir tokens amb l’etiquetatge:– #token Ident “[a-zA-Z][a-zA-Z0-9_]*”– El nom del token ha de començar amb majúscules.– L’expressió regular va entre cometes dobles “”.– L’ordre de definició és important, en cas

d’ambigüetat escull el primer.

Page 11: Pràctiques Mètodes i Eines de Compilació

Lèxic (ii)

Expressions regulars que podem reconèixer:

Expressióregular

Interpretació

"e1|e2" reconeix e1 o bé e2

"(e1)" reconeix e1

"{e1}" reconeix e1 o be res (seria com (e1|)

"[c1c2...cn]" reconeix un (només un) dels caràcters de la llista seria com: (c1|c2|...|cn)

"[c1-cn]" reconeix un dels caràcters que tinguin el codi ASCII entre c1 i cn

"~[c1c2...cn]" reconeix un caràcter dels que no està a la llista

"~[]" reconeix un caràcter qualsevol, és com dir: no cap caracter (o sigui,algun)

"e1*" reconeix zero o més ocurrencies de l'expressió e1

"e1+" reconeix un o més ocurrencies de l'expressió e1

"\c1" reconeix el caràcter c1 encara que tingui un cert significat en lesexpressions regulars: per ex. (\+)

Page 12: Pràctiques Mètodes i Eines de Compilació

Lèxic (iii)

També es poden reconeixer una sèrie de caràcters especials:

"@" reconeix el fi de fitxer

"\t" tabulador

"\n" línea nova (Newline)

"\r" enter

"\b" backspace

"\c" ESC

"\0nnn" reconeix el caràcter amb valor octal: nnn

"\0xnn" reconeix el caràcter amb valor hexadecimal: nn

"\mnn" reconeix el caràcter amb valor decimal mnn (1=m=9)

"\ " reconeixer l'espai.

Page 13: Pràctiques Mètodes i Eines de Compilació

Lèxic (iv)

• Per agrupar tokens, podem definir classes de tokens amb:– #tokclass nomclasse { T1 … Tn }– podem usar nomclasse per a referirnos a qualsevol

dels T1 … Tn.

• Podem associar accions al reconeixement de tokens per tal que es realitzin un cop reconeguts aquests:– #token nomtok expreg << acció_desitjada >>

Page 14: Pràctiques Mètodes i Eines de Compilació

Lèxic (v)

Algunes de les funcions/accions que ens poden ser útils amb el DLG:

replchar(DLGchar c) Substitueix el text del l'últim element lèxic per c. Es pot borrar el text de l'últimelement enviant el caràcter '\0'.

replstr(DLGchar *s) Substitueix el text del l'últim element lèxic per s.

int line() La linia actual que s'està processant.

newline() Informem al DLG que s'ha trobat un caràcter de canvi de línia.

more() Indiquem al DLG que busqui un nou token però que els proper caràcterss'afegeixen al text del token actual.

Page 15: Pràctiques Mètodes i Eines de Compilació

Lèxic (vi)

skip() Indiquem al DLG que continui processant un nou token però que no guardi eltext del token actual.

advance() Fem que el DLG consumeixi un nou caràcter.

int ch L'últim caràcter processat.

DLGChar *lextext() El text que s'han llegit des de que l'últim token que s'ha retornat.

DLGchar *begexpr() Començament de l'ultim token trobat.

Page 16: Pràctiques Mètodes i Eines de Compilació

Lèxic (vii)

DlGchar *endexpr() Punter a l'últim caràcter de l'últim token trobat.

trackColumns() Cal cridar aquesta funció si es vol comptabilitzar les columnes. El número decolumna es posa a zero quan es troba un caràcter de final de línia. També s'actualitzael número de columna quan es troben caràcter que ocupen més d'un espai (p.e.TAB).

int begcol() El número de columna començant per 1 del primer caràcter de l'últim token detectat.

int endcol() El número de columna començant per 1 de l'últim caràcter de l'últim token detectat.

Page 17: Pràctiques Mètodes i Eines de Compilació

Lèxic (viii)• Per a definir accions, funcions, variables, etc., que

volem usar en el codi ___.cpp generat pel DLG que tindrà l’scaner fem:– #lexaction << codi en C++ que desitgem >>

• Podem definir diverses classes lèxiques amb les seves regles cadascuna:– Per definir l’inici d’una classe farem:

• #lexclass contexte.

– La classe lèxica inicial per defecte és: START.

– Per canviar de classe lèxica farem:• mode (nova_classe).

Page 18: Pràctiques Mètodes i Eines de Compilació

Sintàctic 1• L’anàlisi sintàctica consistirà en la definició de

regles sintàctiques:– Una regla descriu una porció del llenguatge d’entrada.– Consisteix en un nom de regla que comença amb

minúscules i una llista d’alternatives.– Te utilitats de pas de valors entre regles i d’utilitats de

tractaments d’errors (opcionals).

• Notem que cada regla és un “mètode” de la classe del parser, per tant pot tenir variables locals, paràmetres, etc.

Page 19: Pràctiques Mètodes i Eines de Compilació

Sintàctic 2• Esquema de regla:

r1 [a1,…an]>[r1,…rn]: prod1|…|prodn ;– r1 és el nom de la regla, comença amb minúscula.– Els ai són possibles arguments d’entrada per a la

regla i els ri possibles valors de retorn de la regla.– Els prodi són produccions possibles que

defineixen la regla, estan formades per:• referències a regles

• referències a tokens

• subregles

• accions

• predicats

Page 20: Pràctiques Mètodes i Eines de Compilació

Sintàctic 3

• Per a referenciar una regla només cal posar el seu nom i els arguments (e/s) si en té:– referència[paràm entrada]>[paràm sortida]

• Podem referenciar el token, posar una expressió regular o bé referenciar classes de tokens, exemples:– Identificador– “altrament”– Operadors

Page 21: Pràctiques Mètodes i Eines de Compilació

Sintàctic 4

• Les subregles són regles sense etiquetes ni paràmetres:– Simple: (…) ex: (Id|Const)– Zero_o_mes: (…)* ex: Id (“,” Id)*– Una_o_mes: (…)+ ex: (decvars)+– Opcional: {...} ex: {“altrament” sentencia}

Page 22: Pràctiques Mètodes i Eines de Compilació

Sintàctic 5

• Les accions són codi C++ entre <<...>>:– Inicialitzacions: es posarà just després del “:” i

s’executarà abans de reconèixer res.– Accions de fracàs: es posarà després del “;” i

s’executarà si el gestor d’errors no és actiu al trobar un error en el reconeixement de la regla.

– Intermitges: les posarem al mig de la regla i s’executaran segons l’ordre de reconeixement dels elements de la regla.

Page 23: Pràctiques Mètodes i Eines de Compilació

Sintàctic 6• Els predicats poden ser de dos tipus semàntics

i sintàctics. Els sintàctics són especificacions del contexte on certa producció farà “matching” amb èxit i es definirà dins:– ( … ) ?

• Exemple:– a: (llista “=“ ) ? llista “=“ llista

|llista

Page 24: Pràctiques Mètodes i Eines de Compilació

Sintàctic 7• Etiquetatge: Les referències dins d’una

producció poden ser etiquetades amb un identificador que es sol fer servir per accedir al token, s’etiqueta així:– etiqueta : element

• Podem accedir a l’element etiquetat (token) amb: $etiqueta, exemple:– r1: t:ID <<printf(“%s\n”, $t->getText());>>

;

Page 25: Pràctiques Mètodes i Eines de Compilació

Sintàctic 8• El PCCTS proporciona una utilitat per al

tractament d’errors (notificació) i la resincronització a base d’excepcions.

• Quan en el reconeixement d’una regla es produeix un error sintàctic el parser llença una excepció que és capturada pel manegador d’excepcions que atengui aquella excepció, més proper.

• Una vegada atesa l’excepció el parser segueix, retornan de la regla generadora.

Page 26: Pràctiques Mètodes i Eines de Compilació

Sintàctic 9

• Els manegadors d’exepcions es poden posar a:– Després de qualsevol alternativa: aquests manegadors només

s’aplicaran sobre al reconexer els components de la corresponent alternativa.

– Després del “;” de definició de la regla: s’aplicarà a qualsevol excepció de qualsevol alternativa de la regla.

– Després de la llista de regles: és un manegador global i actuarà quan no actuin manegadors locals.

Page 27: Pràctiques Mètodes i Eines de Compilació

Sintàctic 10

• La manera de definir-los és la següent:– exception {[etiqueta]}

(catch signal: <<codi associat>>)*{default: <<codi associat>>}

• Els possibles signals són:– NoViableAlt– NoSemViableAlt– MismatchedToken

Page 28: Pràctiques Mètodes i Eines de Compilació

Sintàctic 11

• Si definim manegador d’excepcions associats a etiquetes, ho farem al final de la regla (recordem que les etiquetes són úniques).– …a: A t:expr B | …..

;exception[t]catch:catch:...

Page 29: Pràctiques Mètodes i Eines de Compilació

Sintàctic 12

• L’ordre d’execució de les excepcions és el determinat per la proximitat de la definició del manegador:– etiqueta– alternativa– regla– global

Page 30: Pràctiques Mètodes i Eines de Compilació

Sintàctic 13

• Per a resincronitzar es poden fer servir les següents accions:– consumeUntil(X_set)– consumeUntilToken(T)

Page 31: Pràctiques Mètodes i Eines de Compilació

Semàntic 1

• Per a fer tractament semàntic usarem el pas de paràmetres entre regles ja explicat i la una taula de símbols per tal de poder fer comprovacions com:

– Unicitat d’identificadors.– Ús de cada identificador correcte: variables,

constants, accions i funcions.– Operadors utilitzats amb operands del tipus

correcte.

Page 32: Pràctiques Mètodes i Eines de Compilació

Semàntic 2

• Altres comprovacions semàntiques:– Coincidència del tipatge al prototipus de les

funcions/accions i a l’implementació.– Parametrització de les funcions correcta:

• Entrada sortida correcta.

• Paràmetres del tipus corresponent.

– Correcte ús de les funcions i les variables com a expressions del tipus correcte.

– Taules indexades correctament.

Page 33: Pràctiques Mètodes i Eines de Compilació

Semàntic 3

• La taula de símbols ens servirà per a guardar la informació semàntica de tots els identificadors del programa a compilar.

• Utilitzarem una TS que proporciona el PCCTS al directori:– /usr/local/pccts/support/sym

Page 34: Pràctiques Mètodes i Eines de Compilació

Semàntic 4

• Aquesta taula de símbols te dos fitxers, caldrà que modifiquem el template.h en la definició del símbol tal com ens interessi.

• Caldrà afegir la compilació i linkatge en el projecte i posar l’include adequat en el fitxer ___.g.

Page 35: Pràctiques Mètodes i Eines de Compilació

#header << #include <iostream.h> >><<#include “PblackBox.h”#include “DLGLexer.h”

main() { ParserBlackBox<DLGLexer, Calculadora, ANTLRCommonToken> p(stdin); p.parser()->calcul();}

class Calculadora { calcul: (~”@”)*”@”;}

#token “[\n\r]” << skip(); newline(); >>#token “[\ \t]” << skip(); >>#token ID “[a-zA-Z][a-zA-Z0-9_]”

<< cout << “Trobat ID(“ << line() << “): ” << lextext() << endl;>>

#token ENTER “(0|([1-9][0-9]*))”<< cout<< “Trobat ENTER(“ << line() << “): ” << lextext()<< endl;>>

#token REAL “(0|([1-9][0-9]*))\.[0-9]+”<< cout << “Trobat REAL(“ << line() << “): ” << lextext() <<

endl;>>

#token “~[@]”<< skip(); cout << “Error Lèxic(“ << line() << “): ” << lextext() <<

endl;>>