350 likes | 484 Views
Pràctiques Mètodes i Eines de Compilació. Marc Massot i Bayés marc@ima.udg.es AM11-S2 Mateu Villaret Auselle villaret@ima.udg.es 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.
E N D
PràctiquesMètodes i Eines de Compilació Marc Massot i Bayés marc@ima.udg.es AM11-S2 Mateu Villaret Auselle villaret@ima.udg.es 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. • 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.
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.
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
PCCTSPerdue 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++.
PCCTS (III) • Genera un parser descendent. Gramàtiques lliures de contexte LL. • Procés de compilació dirigit per la sintaxis.
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.
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.
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 >>
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).
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.
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
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
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}
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.
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
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());>> ;
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.
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.
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
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:...
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
Sintàctic 13 • Per a resincronitzar es poden fer servir les següents accions: • consumeUntil(X_set) • consumeUntilToken(T)
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.
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.
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
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.