La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les...

171

Transcript of La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les...

Page 1: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica
Page 2: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica
Page 3: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

Creative Commons License Deed Reconeixement-No comercial-Sense obres derivades 3.0 Espanya

Vostè és lliure de: Copiar, distribuir i comunicar públicament l’obra.

Sota els següents condicionants:

Reconeixement. S’ha de referenciar aquesta obra a Mª Antonia Mozota - Enginyeria La Salle (Semipresencial) No comercial. No es pot utilitzar aquesta obra per a finalitats comercials. Sense obres derivades. No es pot alterar, transformar o generar una obra derivada a partir d’aquesta.

• Quan reutilitzeu o distribuïu l'obra, heu de deixar ben clar els termes de la llicència de l'obra. • Alguna d'aquestes condicions pot no aplicar-se si obteniu el permís del titular dels drets d'autor. • No hi ha res en aquesta llicència que menyscabi o restringeixi els drets morals de l'autor.

Els drets derivats d'usos legítims o altres limitacions reconegudes per llei no queden afectats per l'anterior

Això és un resum fàcilment llegible del text legal (la llicència completa) disponible en els idiomes següents:

Català Castellà Basc Gallec

Page 4: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

Crèdits

Autor: Mª Antonia Mozota

Editor: Lluís Vicent

Coordinació lingüística: Sara Laso

Revisió lingüística: Christian Lara

Maquetació: Víctor Miras

Disseny de portada: Víctor Miras

Aquesta edició ha comptat amb el suport de l’Agència de Gestió d’Ajuts Universitaris i de Recerca (AGAUR) de la Generalitat de

Catalunya en la Convocatòria d’ajuts a l’edició i la difusió de llibres de text o manuals universitaris i llibres cientificotècnics, en suport

paper o en suport electrònic, escrits en llengua catalana (DILL 2009)

ISBN: 978-84-937712-1-8

Page 5: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

1

Índex

SESSIÓ 1: Una introducció ........................................................................................... 5 

1 Llenguatges de programació ................................................................................... 5 

1.1 Història ........................................................................................................................ 5 1.1.1 Història ........................................................................................................................................ 5 

1.2 Classificació .................................................................................................................. 6 1.2.1 Classificació ................................................................................................................................. 6 

1.3 Programació. Disseny. Implementació ......................................................................... 7 1.3.1 Programació, disseny i implementació ....................................................................................... 7 

SESSIÓ 2: Sintaxi i Semàntica ...................................................................................... 9 

1.4 Definició formal dels llenguatges imperatius ................................................................ 9 1.4.1 Sintaxi i Semàntica ...................................................................................................................... 9 1.4.2 Treball (opcional) ...................................................................................................................... 10 

SESSIÓ 3: El procés de la compilació ......................................................................... 13 

2 El procés de la compilació ...................................................................................... 13 

2.1 Compiladors ............................................................................................................... 13 2.1.1 Compiladors .............................................................................................................................. 13 

2.2 Parts d'un compilador ................................................................................................ 14 2.2.1 Parts d'un compilador ............................................................................................................... 14 

2.3 Tipus de compiladors ................................................................................................. 18 2.3.1 Tipus de compilador ................................................................................................................. 18 

SESSIÓ 4: Eines ......................................................................................................... 21 

2.4 Eines per la construcció de compiladors ..................................................................... 21 2.4.1 Eines per la construcció de compiladors .................................................................................. 21 

SESSIÓ 5: Aspectes regulars i funcions ...................................................................... 23 

3 L'anàlisi lexicogràfica ............................................................................................ 24 

3.1 Llenguatges de programació i els seus aspectes regulars ............................................ 24 3.1.1 Llenguatges de programació i els seus aspectes regulars ........................................................ 24 

3.2 Esquema i funcionalitats ............................................................................................ 26 3.2.1 Esquema d'un analitzador lexicogràfic ..................................................................................... 26 3.2.2 Funcions d'un analitzador lexicogràfic ...................................................................................... 27 3.2.3 Treball (opcional ) ..................................................................................................................... 28 

SESSIÓ 6: Tokens i lexemes ....................................................................................... 29 

3.3 Tokens  i lexemes ....................................................................................................... 29 3.3.1 Tokens i lexemes ....................................................................................................................... 29 

SESSIÓ 7: Implementació, errors i la seva recuperació .............................................. 35 

3.4 Implementació d'un analitzador lexicogràfic .............................................................. 35 3.4.1 Implementació d'un analitzador lexicogràfic ............................................................................ 35 3.4.2 Treballs (recomanats) ............................................................................................................... 36 

Page 6: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

2

3.5 Errors i recuperació .................................................................................................... 36 3.5.1 Errors i la seva recuperació ....................................................................................................... 36 

SESSIÓ 8: Aplicacions ................................................................................................ 39 

3.6 Aplicacions ................................................................................................................. 39 3.6.1 Aplicacions ................................................................................................................................ 39 3.6.2 Treball (opcional) ...................................................................................................................... 40 

SESSIÓ 9: Sintaxi i tipus de parsers ........................................................................... 41 

4 L'anàlisi sintàctica ................................................................................................. 42 

4.1 Sintaxi ........................................................................................................................ 42 4.1.1 Sintaxi ....................................................................................................................................... 42 

4.2 Tipus de parsers ......................................................................................................... 45 4.2.1 Tipus de "parser" ...................................................................................................................... 45 

SESSIÓ 10: Eliminació de recursivitat a esquerra i factorització ................................ 47 

4.3 L'anàlisi descendent (LL) ............................................................................................. 47 4.3.1 El procés general ....................................................................................................................... 47 4.3.2 Consideracions per a una anàlisi top‐down eficient i predictiva .............................................. 49 

SESSIÓ 11: Analitzadors descendents recursius ......................................................... 54 4.3.3 Anàlisi descendent recursiva .................................................................................................... 54 4.3.4 Condicions suficients LL(1) ........................................................................................................ 55 

SESSIÓ 12: Analitzadors descendents tabulars .......................................................... 60 4.3.5 Anàlisi descendent tabular ....................................................................................................... 60 4.3.6 Ambigüitat en LL ....................................................................................................................... 64 

SESSIÓ 13: Recuperació d'errors ............................................................................... 67 4.3.7 Recuperació d'errors en parsers descendents .......................................................................... 67 

SESSIÓ 14: Problemes (parsers descendents) ............................................................ 69 4.3.8 Problemes ................................................................................................................................. 69 

SESSIÓ 15: Una introducció als parsers ascendents ................................................... 71 

4.4 L'anàlisi ascendent (LR) .............................................................................................. 71 4.4.1 El procés general ....................................................................................................................... 71 

SESSIÓ 16: Parsers simples SLR ................................................................................. 79 

SESSIÓ 17: Parsers canònics LR ................................................................................. 87 4.4.3 Analitzadors  ascendents canònics LR (LR) ............................................................................... 87 

SESSIÓ 18: Parsers LALR ............................................................................................ 95 4.4.4 Analitzadors  ascendents lookahead LALR (LALR) ..................................................................... 95 4.4.5 Comparació entre parsers ascendents ..................................................................................... 97 

SESSIÓ 19: Ambigüitat en LR ..................................................................................... 99 4.4.6 Ambigüitat en LR....................................................................................................................... 99 

SESSIÓ 20: Recuperació d'errors ............................................................................. 103 4.4.7 Recuperació d'errors en parsers ascendents .......................................................................... 103 

SESSIÓ 21: Problemes (parsers ascendents SLR) ...................................................... 107 4.4.8 Problemes (parsers SLR) ......................................................................................................... 107 

Page 7: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

3

SESSIÓ 22: Problemes (parsers ascendents SLR) ...................................................... 109 4.4.9 Problemes (parsers LR) ........................................................................................................... 109 

SESSIÓ 23: Problemes ............................................................................................. 111 4.4.10 Problemes ............................................................................................................................. 111 

SESSIÓ 24: Generadors de parsers .......................................................................... 115 

4.5 Eines ........................................................................................................................ 115 4.5.1 Eines ........................................................................................................................................ 115 

SESSIÓ 25: Definicions ............................................................................................ 117 

5 Traducció dirigida per sintaxi ............................................................................... 117 

5.1 Gramàtiques d'atributs ............................................................................................ 117 5.1.1 Gramàtiques d'atributs ........................................................................................................... 117 

SESSIÓ 26: Problemes ............................................................................................. 121 5.1.2 Problemes ............................................................................................................................... 121 

SESSIÓ 27: Problemes ............................................................................................. 123 

5.2 Esquemes de traducció ............................................................................................ 123 5.2.1 Esquemes de traducció ........................................................................................................... 123 

SESSIÓ 28: Problemes ............................................................................................. 125 5.2.2 Problemes ............................................................................................................................... 125 

Problemes i Solucions ............................................................................................. 127 

Enunciats dels problemes .............................................................................................. 127 CAPÍTOL 1 LLENGUATGES DE PROGRAMACIÓ ................................................................................. 127 CAPÍTOL 2 EL PROCÈS DE LA COMPILACIÓ ...................................................................................... 127 CAPÍTOL 3 ANÀLISI LEXICOGRÀFICA ................................................................................................ 127 CAPÍTOL 4 ANÀLISI SINTÀCTICA ....................................................................................................... 128 CAPITOL 5 GRAMÀTIQUES D'ATRIBUTS ........................................................................................... 141 

Algunes Solucions .......................................................................................................... 146 

Bibliografia ............................................................................................................ 163 

Glossari .................................................................................................................. 165 

Page 8: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

4

Page 9: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

5

SESSIÓ 1: Una introducció

FITXA DE LA SESSIÓ Nom: Una introducció Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no

OBJECTIUS Mostrar els diferents llenguatges de programació mitjançant una llista exhaustiva i les seves possibles classificacions. Donar les diferents visions per estudiar els llenguatges de programació i així introduir la necessitat d'estudiar la teoria de la compilació.

CONTINGUTS

1 Llenguatges de programació

1.1 Història

1.1.1 Història Els llenguatges de programació han anat evolucionant de manera contínua des dels anys 50 quan van aparèixer els primers llenguatges de programació d'alt nivell.

Què és un llenguatge de programació?

Es pot considerar un llenguatge de programació aquell conjunt de sentències definides sobre un vocabulari determinat que permeten escriure algorismes i estructures de dades. En el context de la teoria de la compilació només ens interessen els llenguatges de programació que s'implementen en un ordinador.

Una petita història

La història dels llenguatges de programació d'alt nivell es remunta als anys 50. Els primers llenguatges servien per desenvolupar aplicacions numèriques. El llenguatge més representatiu de l'època que actualment s'utilitza encara, tot i que en versions més modernes, és el FORTRAN.

Page 10: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

6

El llenguatge ALGOL, als anys 60, va definir un estil diferent de llenguatge de programació. ALGOL no va tenir massa èxit però va ser el primer pas cap els llenguatges, ALGOL68, ALGOLW i Pascal. COBOL, també sorgit als 60, s'utilitzava en aplicacions de negocis. L'àrea de la intel·ligència artificial va aportar llenguatges tan coneguts com el LISP. Alguns articles comenten que s'han desenvolupat més de 200 llenguatges de programació entre els anys 50 i 80 dels quals els més significatius són: FORTRAN(‘50), ALGOL(‘60), LISP(‘60), COBOL(‘60), APL(‘60), PL/I (‘60), SIMULA(‘60), PROLOG (‘70), C (‘70), PASCAL (‘70), dBaseII ('80), Smalltalk('80), ADA ('80), C++('80), Eiffel('80), Oberon('80), etc. L'any 1995 Kinnersley va publicar una llista de 2200 llenguatges que inclouen variants, dialectes i diferents implementacions. També hi ha llenguatges teòrics que mai no han estat implementats. L'any 2004 O'Reilly, aprofitant la commemoració dels 50 anys del primer llenguatge de programació d'alt nivell (FORTRAN), va publicar un diagrama que representa la història dels llenguatges ( http://oreilly.com/news/graphics/prog_lang_poster.pdf )

1.2 Classificació

1.2.1 Classificació Els diferents llenguatges de programació es poden classificar segons diversos criteris. Alguns criteris que permeten classificar-los són: els paradigmes de programació i les àrees d'aplicació.

Paradigmes de programació

Un paradigma de programació és un model de computació en el qual està basat un llenguatge de programació. Actualment, podem considerar-ne cinc models bàsics: l’imperatiu, l'aplicatiu, el basat en regles, l'orientat a objectes i l'orientat a events. El model de llenguatge imperatiu, anomenat també de procediments, és el que utilitzarem al llarg d'aquest curs per estudiar la teoria de la compilació.

Àrees d'aplicació

El llenguatge més apropiat per desenvolupar una aplicació depèn directament del domini de l'aplicació. Els llenguatges que eren apropiats en el passat han evolucionat i han sortit noves àrees d'aplicació. Entre d'altres podem mencionar: de propòsit general, científic, de sistemes, intel·ligència artificial, processament de dades, etc.

Page 11: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

7

1.3 Programació. Disseny. Implementació

1.3.1 Programació, disseny i implementació Els llenguatges de programació poden ser estudiats des de les següents perspectives: programació, disseny i implementació. En cada cas veiem el llenguatge d'una manera diferent però les tres ens ajuden a:

Aprendre més fàcilment nous llenguatges de programació. Utilitzar millor els llenguatges ja coneguts. Avaluar i escollir un llenguatge per a una determinada aplicació. Facilitar el disseny d'un nou llenguatge. Desenvolupar algorismes més eficaços.

Programació

Quan volem programar en un llenguatge, és a dir, quan volem utilitzar un llenguatge de programació, hem de conèixer la seva sintaxi i la seva semàntica. La sintaxi permet d'escriure programes vàlids estructuralment i la semàntica permet d'escriure programes correctes semànticament. En la pròxima sessió veurem com s'especifiquen la sintaxi i la semàntica. Un programador ha de saber “llegir” la sintaxi formal i la semàntica d'un llenguatge de programació.

Disseny

Definir un nou llenguatge vol dir especificar la seva sintaxi i la seva semàntica. El dissenyador ha de saber “escriure” formalment la sintaxi i la semàntica del llenguatge. A més a més ha de conèixer molt bé els elements que conformen aquest llenguatge i com s'implementen, és a dir, com es compilen.

Implementació

Implementar un llenguatge vol dir desenvolupar un compilador pel llenguatge. Un implementador ha de saber “llegir” la sintaxi formal i la semàntica d'un llenguatge de programació i conèixer molt bé els elements que conformen un llenguatge. Al llarg del curs aprendrem les tècniques necessàries per fer implementadors.

RESUM Hi ha més de 200 llenguatges de programació però només uns 15 són els més utilitzats. Podem classificar els llenguatges des de diversos punts de vista.

Page 12: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

8

La programació, el disseny i la implementació dels llenguatges de programació ens permet de conèixer millor els llenguatges que fem servir més sovint i ens dóna criteris per escollir-ne un.

Page 13: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

9

SESSIÓ 2: Sintaxi i Semàntica

FITXA DE LA SESSIÓ Nom: Sintaxi i Semàntica Tipus: teòrica Format: no presencial Durada: 2 hora Treball a lliurar: no

OBJECTIUS Donar una visió global dels diferents formalismes per definir la sintaxi i la semàntica dels llenguatges de programació.

CONTINGUTS En aquesta sessió fem una introducció a la sintaxi i a la semàntica dels llenguatges de programació i com es descriuen.

1.4 Definició formal dels llenguatges imperatius

1.4.1 Sintaxi i Semàntica La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica especifica el seu significat.

Formalismes per expressar la sintaxi

A diferència de la semàntica, la sintaxi dels llenguatges de programació s'expressa, en la majoria dels casos, formalment. Els formalismes per definir la sintaxi són: les gramàtiques i els diagrames sintàctics o de Conway. Entre les gramàtiques podem destacar:

- la notació BNF (Backus-Naur Form) - la notació BNFE (Backus-Naur Form Extended)

Una gramàtica descriu l'estructura jeràrquica d'un llenguatge. És el formalisme més utilitzat per descriure la sintaxi i és la base de moltes de les eines de construcció de compiladors. Els diagrames de Conway són formalismes gràfics de fàcil comprensió. La sintaxi d'una llista d'identificadors es pot definir de les maneres següents:

Page 14: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

10

1) Mitjançant una gramàtica amb notació BNF: LI --> id, LI LI --> id 2) Mitjançant una gramàtica amb notació BNFE: LI --> {id}+ 3) Mitjançant un diagrama de Conway:

Formalismes per expressar la semàntica

Un programador necessita conèixer la semàntica del llenguatge per poder programar algorismes correctes. L'implementador necessita conèixer la semàntica per poder implementar correctament el llenguatge. Normalment, en els manuals dels llenguatges de programació, la semàntica està descrita de manera informal. El manual està orientat a la sintaxi, i per a cada construcció sintàctica, explica, amb llenguatge natural, la seva semàntica. S'han desenvolupat diversos mètodes o formalismes per expressar formalment la semàntica però això no és tan fàcil com la sintaxi. Entre els formalismes, podem citar la semàntica operacional, la semàntica axiomàtica, la semàntica denotacional i les gramàtiques d'atributs. Aquest últim formalisme és el que utilitzarem en el curs.

1.4.2 Treball (opcional)

Definició formal d'un llenguatge de programació

Busqueu la definició d'un llenguatge de programació imperatiu. Estudieu com està definida la seva sintaxi i la seva semàntica.

Page 15: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

11

RESUM La sintaxi dels llenguatges sempre es defineix formalment mitjançant gramàtiques o diagrames sintàctics. La semàntica dels llenguatges s'expressa habitualment en els manuals amb llenguatge natural. Hi ha diversos formalismes per definir la semàntica. En la pràctica el més utilitzat és la gramàtica d'atributs.

Page 16: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

12

Page 17: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

13

SESSIÓ 3: El procés de la compilació

FITXA DE LA SESSIÓ Nom: El procés de la compilació Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no

OBJECTIUS Donar una visió global del que és un compilador.

CONTINGUTS En aquesta sessió veurem la definició de compilador i estudiarem les seves parts principals. En sessions posteriors estudiarem cada una de les fases en detall.

2 El procés de la compilació

2.1 Compiladors

2.1.1 Compiladors Un compilador pot ser considerat una mena de traductor que tradueix un programa font, escrit en un llenguatge de programació, en un programa objecte.

Esquema general

Un compilador és un traductor que tradueix un programa font escrit en un llenguatge d'alt nivell a un programa objecte.

El programa objecte generat pel compilador s'ha de poder executar sobre un ordinador. Normalment compilem per a un ordinador específic. El compilador també reporta els errors produïts durant el procés de la compilació.

Page 18: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

14

Processament d'un llenguatge

El compilador genera, en la majoria del casos, codi en llenguatge assemblador. L'assemblador és un programa que tradueix de codi assemblador a codi relocalitzable de màquina. El carregador/"linkador" s'encarregarà de generar codi absolut.

En aquesta assignatura estudiarem només la teoria per la construcció de compiladors.

2.2 Parts d'un compilador

2.2.1 Parts d'un compilador Un compilador té dues fases diferenciades, la fase de l'anàlisi del programa font i la fase de síntesi del programa objecte. La fase d'anàlisi analitza l'entrada tot verificant que sigui correcta sintàcticament i semànticament. La fase de síntesi genera el programa objecte.

Page 19: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

15

L'anàlisi del programa font

Bàsicament identifica l'estructura del programa font i verifica la semàntica. Sintaxi i semàntica són dos aspectes claus que estudiarem en detall en les pròximes sessions. L'anàlisi comporta: l'anàlisi lexicogràfica, l'anàlisi sintàctica i l'anàlisi semàntica. L'anàlisi lexicogràfica (scanner) és una anàlisi lineal del programa font vist com una seqüència de caràcters. Agrupa aquests caràcters en unitats lexicals anomenades tokens. L'anàlisi sintàctica (parser) és una anàlisi de l'estructura del programa vist com una seqüència de tokens. Verifica que l'estructura compleixi les regles sintàctiques del llenguatge. L'anàlisi semàntica verifica que les declaracions de constants, variables i funcions i les seves utilitzacions siguin coherents respecte a la semàntica definida pel llenguatge. També construeix la taula de símbols, utilitzada tant en aquesta fase com en la fase de síntesi. Cadascuna d'aquestes fases genera els corresponents errors trobats.

La síntesi del programa objecte

Crea un programa objecte. La síntesi comporta: l'assignació de memòria i la generació de codi. Si es vol fer optimització de codi, s'ha de generar codi intermedi. L'assignació de memòria determina com seran representades les variables del programa en memòria i com es gestionarà la memòria. La generació de codi intermedi tradueix el programa font en un programa escrit en un llenguatge intermedi. L'optimització de codi optimitza el codi intermedi generat en la fase anterior. La generació de codi determina i implementa les seqüències de codi objecte per efectuar, en temps d'execució, les seqüències d'accions definides en el programa font optimitzat.

Page 20: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

16

Esquema

Les fases d'un compilador poden ser vistes en forma d'esquema. En la següent figura podeu observar que hi figuren com fases la taula de símbols i les rutines de recuperació d'errors. N'estudiarem aquestes últimes en cada una de les fases. Estudiarem la taula de símbols en la fase semàntica.

Page 21: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

17

Un exemple

Per donar una idea global de les tasques de cada fase es mostra el següent exemple: Sigui el següent fragment de codi: x = y + z * 60. Les variables x, y i z són reals.

Page 22: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

18

2.3 Tipus de compiladors

2.3.1 Tipus de compilador Els compiladors poden ser de diverses passades (multi) o d'una sola passada. El número de passades és el número de vegades que es llegeix el programa font o algun codi intermedi.

Compilació multi-passada

L'esquema donat en l'apartat anterior representa un compilador organitzat en diverses passades o fases. Cada fase es completa abans de començar la següent. Cada fase genera un codi intermedi de manera que cadascuna depura el programa i crea una estructura més adient per a la pròxima fase. Aquesta mena de compiladors solen generar codi més eficient, són més costosos d'implementar, es mantenen més fàcilment, són desenvolupats per equips i són més lents. La compilació multi-passada ens permet d'organitzar els compiladors amb front ends i back ends.

Compilació d'una passada

La idea d'un compilador d'una sola passada és fer les fases en paral·lel tot llegint una sola vegada el programa font. La tècnica que s'utilitza per a implementar aquesta mena de compilador és la traducció dirigida per sintaxi. Aquesta mena de compiladors solen generar un codi menys eficient, són més fàcils d'implementar, són desenvolupats per un sol equip i són més ràpids.

Criteris per escollir el tipus de compilador

Els dos criteris bàsics a seguir per escollir un compilador multi-passada o d'una sola passada són: el llenguatge de programació a compilar i l'aspecte pràctic. El llenguatge de programació que hem de compilar pot tenir unes característiques que impedeixen implementar un compilador d'una sola passada. Per exemple, el llenguatge permet declarar variables després d'utilitzar-lo. L'aspecte pràctic es refereix al nombre de persones (equips) que volem involucrar a la velocitat del compilador i a l'optimització del codi objecte.

Page 23: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

19

RESUM Un compilador és un traductor de codi font a codi objecte. Un compilador té dues parts lògiques: l'anàlisi del programa font i la síntesi del programa objecte. L'anàlisi comporta: l'anàlisi lexicogràfica, l'anàlisi sintàctica i l'anàlisi semàntica. La síntesi comporta: l'assignació de memòria i la generació de codi i eventualment l'optimització de codi. Un compilador pot ser implementat d'una passada o de múltiples passades.

Page 24: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

20

Page 25: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

21

SESSIÓ 4: Eines

FITXA DE LA SESSIÓ Nom: Eines Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no

OBJECTIUS Donar les nocions globals de les diferents eines que existeixen en el mercat per a la construcció de compiladors.

CONTINGUTS En aquesta sessió presentem un conjunt d'eines que faciliten la construcció de compiladors.

2.4 Eines per la construcció de compiladors

2.4.1 Eines per la construcció de compiladors Els primers compiladors van aparèixer als anys 50 i es consideraven programes molt difícils d'implementar. Amb el temps van millorar els llenguatges mateixos de programació i es van desenvolupar eines i ambients de programació que faciliten l'escriptura de compiladors. Aquestes eines segueixen evolucionant i avui dia en podem trobar una gran varietat. A continuació en donarem algunes i en comentarem les més rellevants.

Classificació

Tant les eines disponibles de lliure distribució com les comercials poden ser classificades en els següents grups principals: - Construcció d'analitzadors lexicogràfics (generadors de scanner). - Construcció d'analitzadors sintàctics (generadors de parser). - Per l'optimització de codi. - Generadors de back ends. Algunes d'aquestes eines estan integrades en ambients molt complets de construcció de compiladors. En canvi, d'altres són molt específiques per desenvolupar una única feina. Podeu trobar un catàleg exhaustiu d'eines en http://catalog.compilertools.net/

Page 26: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

22

LEX i YACC

De totes les eines, el LEX i el YACC són les més conegudes ja que van ser de les primeres. El LEX permet definir patrons mitjançant expressions regulars i fer accions en cada cas. S'utilitza principalment per generar un analitzador lexicogràfic. A la pràctica, l'eina genera un autòmat d'estats finit per reconèixer les expressions regulars definides. El YACC és un generador d'analitzadors sintàctics ascendents i s'ha utilitzat per a la construcció de molts dels compiladors comercials. La primera versió data dels anys 70. http://dinosaur.compilertools.net/

PCCTS

PCCTS és una eina que permet construir de manera automàtica a partir d'una gramàtica, un analitzador sintàctic descendent recursiu. De forma molt similar al LEX, es pot definir un conjunt d'expressions regulars i genera automàticament l'analitzador lexicogràfic. http://www.antlr2.org/pccts133.html

JavaCC

JavaCC és una de les eines més actuals ja que és un generador de compiladors escrits en JAVA. L'entorn permet, com les eines anteriors, l'especificació d'expressions regulars per l'analitzador lexicogràfic i l'especificació d'una gramàtica per l'analitzador sintàctic descendent recursiu que construeix. https://javacc.dev.java.net/

RESUM Hi ha moltes eines per desenvolupar compiladors. Les més conegudes són el LEX i el YACC. Una de les més actuals i que utilitzarem a la pràctica és JavaCC.

Page 27: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

23

SESSIÓ 5: Aspectes regulars i funcions

FITXA DE LA SESSIÓ Nom: Aspectes regulars i funcions Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Aho1985]

PRECEDENTS Fins ara hem estudiat una introducció al procés de la compilació. D'ara endavant començarem a estudiar en detall cadascuna de les fases del procés de la compilació. En el següent esquema mostrem en color vermell el que falta per estudiar i en color vermell i quadre doble el que farem en aquest capítol. Les fases ja estudiades apareixeran en color blau.

OBJECTIUS Introduir la fase d'anàlisi lexicogràfica d'un compilador. Determinar, donat un llenguatge de programació, quins són els seus aspectes regulars.

CONTINGUTS En aquesta sessió estudiarem els aspectes regulars d'un llenguatge de programació i definirem les funcions d'un analitzador lexicogràfic.

Page 28: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

24

3 L'anàlisi lexicogràfica

3.1 Llenguatges de programació i els seus aspectes regulars

3.1.1 Llenguatges de programació i els seus aspectes regulars

L'analitzador lexicogràfic és la primera fase d'un compilador. És la fase que llegeix l'entrada (el programa) caràcter per caràcter reconeixent els elements bàsics del llenguatge. Aquests elements bàsics són totes les construccions regulars del llenguatge de programació. Abans de veure les funcionalitats que ha de tenir un analitzador lexicogràfic, revisarem el concepte d'expressió regular i després veurem quines parts d'un llenguatge de programació poden considerar-se regulars.

Revisió del concepte d'expressió regular

Una expressió regular és una expressió construïda a partir d'expressions simples i d'un conjunt d'operadors. Les expressions simples són elements d'un vocabulari i el conjunt d'operacions és: la unió (+), la concatenació (·) i la clausura (*). Cada expressió regular defineix un llenguatge. Cada expressió regular es pot considerar com un patró. Tot llenguatge regular pot ser definit mitjançant una gramàtica regular. En les eines generadores, l'especificació per a la construcció de l'analitzador lexicogràfic es fa utilitzant expressions regulars. Un exemple: sigui el vocabulari {a,b} - L'expressió regular a+b defineix el conjunt {a, b} - L'expressió regular a·b defineix el conjunt {ab}. L'operador · es pot obviar sense cap classe d'ambigüitat. És a dir, es pot posar directament: ab en lloc de a·b. - L'expressió regular (a+b)·(a+b) defineix el conjunt {aa,ab,ba,bb}. És a dir, el conjunt de totes les cadenes de caràcters de llargada 2. Una altra manera de definir el mateix llenguatge és mitjançant l'expressió regular: aa+ab+ba+bb. - L'expressió regular a* defineix el conjunt infinit {ε, a,aa,aaa,aaaa, ...}. És a dir, el conjunt de totes les cadenes formades per 0 o més a's. L'epsilon és la notació utilitzada per especificar la cadena buida. - L'expressió regular (a+b)* defineix el conjunt de totes les cadenes formades per 0 o més a's o b's. Una altra manera de definir el mateix llenguatge és mitjançant l'expressió regular: (a*+b*)*.

Page 29: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

25

- L'expressió regular a+a*b defineix el conjunt format per la cadena a i per totes las cadenes començant per 0 o més a's i acabant per b. És a dir, {a,b,ab,aab,aaab, ...}

Definicions regulars

L'objectiu de determinar quines parts d'un llenguatge són regulars és minimitzar la gramàtica incontextual, deixant les tasques regulars per a l'analitzador lexicogràfic. La manera d'identificar els aspectes regulars és estudiant la sintaxi del llenguatge i determinant quines parts tenen forma regular. Una caracterització possible és que tot allò que pot ser reconegut per un autòmat d'estats finits és regular. Una altra possibilitat és determinar quines parts de la gramàtica incontextual poden ser definides utilitzant una gramàtica regular. Una vegada reconegudes les parts regulars, aquestes passen a ser terminals de la gramàtica incontextual. Per exemple, sigui la següent gramàtica definint la sintaxi dels identificadors d'un llenguatge de programació. La sintaxi defineix que el nom d'un identificador ha de començar amb una lletra i desprès pot tenir lletres o dígits o _.

Aquesta gramàtica és regular perquè el llenguatge dels identificadors ho és. Aleshores es pot definir el mateix llenguatge mitjançant les expressions regulars següents: (a+b+ ... +z)((a+b+ ... +z)+(0+1+ ... +9)+(_))* o lletra (lletra + dígit + _)*, on lletra representa l'expressió regular : (a+b+ ... +z) i dígit l'expressió regular: (0+1+ ... +9) Podeu consultar altres exemples en la referència.

[Aho1985] p96-p97

Page 30: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

26

Notacions curtes per expressions regulars

Per algunes construccions que es repeteixen en les expressions regulars és convenient introduir una notació més curta. Els generadors d'analitzadors lexicogràfics utilitzen aquesta notació. Si es vol indicar 1 o més vegades, s'utilitza l'operador + de forma postfixa. Per exemple, l'expressió regular : a+, defineix el conjunt de cadenes d'1 o més a's. Si es vol indicar 0 o 1 vegada, s'utilitza l'operador ? de forma postfixa. Per exemple, l'expressió regular : a?, defineix el conjunt format per a la cadena buida i per a la cadena a. És important, en el moment de definir expressions regulars en un generador d'analitzadors lexicogràfics conèixer quines són aquestes notacions.

Construccions no regulars

Hi ha moltes construccions dels llenguatges que no són regulars. Per exemple, el llenguatge dels parèntesis balancejats no es pot expressar mitjançant una expressió regular.

3.2 Esquema i funcionalitats

3.2.1 Esquema d'un analitzador lexicogràfic L'analitzador lexicogràfic pot ser una fase d'un compilador multi-passada o pot ser una rutina per l'analitzador sintàctic en un compilador d'una passada.

Fase d'un compilador multi-passada

En un compilador multi-passada, cada fase transforma la seva entrada produint una representació intermèdia per a la següent fase. En l'esquema següent, l'analitzador lexicogràfic llegeix el programa font transformant-lo en una llista de tokens per a la pròxima fase. L'anàlisi sintàctica no començarà fins que no acabi la fase anterior.

Page 31: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

27

Rutina d'un compilador d'una passada

En un compilador d'una passada es pot considerar que l'analitzador sintàctic és el programa principal (traducció dirigida per sintaxi). L'analitzador lexicogràfic és el programa que llegeix l'entrada i que dóna un token a l'analitzador sintàctic sota petició. L'analitzador lexicogràfic actua com un procediment.

3.2.2 Funcions d'un analitzador lexicogràfic Les funcions són les mateixes per a qualsevol analitzador lexicogràfic però depenen directament del llenguatge.

Tasques principals

La tasca principal d'un analitzador lexicogràfic és llegir els caràcters de l'entrada i produir com a sortida una llista de tokens (elements bàsics del llenguatge). És a dir, reconèixer tokens. Recordeu que aquests elements bàsics, que estudiarem en la pròxima sessió, són els terminals de la gramàtica incontextual que defineixen el llenguatge que volem compilar. Per determinar els tokens que ha de reconèixer l'analitzador hem d'estudiar el llenguatge i determinar-ne tots els aspectes regulars. És imprescindible conèixer el vocabulari sobre el qual està definit el llenguatge.

Altres tasques

Altres tasques que fa l'analitzador lexicogràfic són: - Saltar els comentaris ja que no són útils per al compilador. És a dir, l'analitzador lexicogràfic reconeix els comentaris segons la sintaxi regular corresponent però no genera cap token ja que l'analitzador sintàctic no els utilitza. - Saltar blancs, tabuladors i salts de línia. Els salts de línia i els tabuladors són caràcters que s'utilitzen, des del punt de vista del programador, per formatar el programa. L'analitzador lexicogràfic els reconeix però no genera cap token ja que no

Page 32: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

28

són útils per a les altres fases del compilador. Els blancs, en la majoria dels llenguatges de programació, s'utilitzen com separadors. En aquest cas l'analitzador lexicogràfic els reconeix però no genera cap token. - Comptar el número de línies. Això permet donar els errors lexicogràfics amb el número de línia corresponent. En algunes de les eines actuals per a la construcció de compiladors, el número de línia és calculat automàticament. - Donar els errors lexicogràfics que es produeixin.

3.2.3 Treball (opcional )

Aspectes regulars d'un llenguatge de programació

Busqueu en un llenguatge de programació conegut els aspectes regulars.

RESUM Els aspectes regulars dels llenguatges de programació poden ser expressats formalment mitjançant les expressions regulars. L'analitzador lexicogràfic pot ser una fase més en un compilador multi-passada o pot actuar com un procediment en un compilador d'una sola passada. Les tasques principals d'un analitzador lexicogràfic són: reconèixer tokens i saltar comentaris, tabuladors, blancs i salts de línia.

Page 33: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

29

SESSIÓ 6: Tokens i lexemes

FITXA DE LA SESSIÓ Nom: Tokens i lexemes Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no

OBJECTIUS Donar els conceptes de token i lexema. Mostrar els diferents tokens que podem trobar en un llenguatge de programació.

CONTINGUTS

3.3 Tokens i lexemes

3.3.1 Tokens i lexemes

Concepte de token

Un token és una unitat lexical indivisible. Dit d'una altra manera, un token és un element bàsic d'un llenguatge de programació. Des del punt de vista de la sintaxi, els tokens són els terminals de la gramàtica. Les paraules claus, els identificadors, els operadors i les constants són exemples de tokens. En el pròxim apartat estudiarem i comentarem els diferents tokens que ens podem trobar en un llenguatge de programació.

Concepte de lexema

Un token és una construcció regular llavors el seu patró pot ser descrit amb una expressió regular. Un lexema és una seqüència de caràcters que compleix amb el patró d'un token. Hi ha tokens que tenen un únic lexema mentre que uns altres tenen diversos lexemes.

Page 34: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

30

Alguns exemples

En la següent taula podeu veure alguns exemples i la diferència entre token i lexema. Per exemple el token ID té un nombre infinit de lexemes mentre que el token IF només té quatre lexemes.

Identificadors

Els identificadors són elements que apareixen molt sovint en els llenguatges de programació. Un identificador pot representar: una constant, una variable, una funció o un nom de tipus definit per l'usuari. El llenguatge defineix la sintaxi dels identificadors, la seva llargada i si són sensitius a les majúscules i a les minúscules. A partir d'aquesta definició es construirà l'expressió regular corresponent. El token corresponent és “identificador” (o el nom que li volem donar) i els lexemes són els diferents identificadors. Una possible expressió regular definint un token identificador pot ser: lletra(lletra+dígit)*. El lexema de l'identificador no és útil en l'anàlisi sintàctica però és fonamental per l'anàlisi semàntica.

Constants

Les constants són elements bàsics dels llenguatges de programació. Per a cadascun dels tipus predefinits, el programador té a la seva disposició una notació per les constants. La sintaxi de cadascuna d'aquestes constants pot ser definida mitjançant expressions regulars. Donat que cada constant de tipus té una sintaxi pròpia i diferent, podem definir un token diferent per cada tipus de constant. Així, les constants queden classificades segons el seu tipus. Per exemple, podem tenir els tokens següents: CTE_REAL, CTE_SENCERA, CTE_LOGICA,... Els lexemes corresponents són les constants mateixes. Exemple,

Page 35: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

31

Operadors

Els operadors estan agrupats lògicament. Normalment trobem operadors aritmètics, operadors relacionals, operadors lògics,.... Tenim dues possibilitats, definir per a cada tipus d'operador un token o definir un token per a cada operador. En el primer cas els lexemes seran els operadors corresponents i en el segon cas el token i el lexema seran el mateix. Aquesta decisió afecta la gramàtica i per tant defineix la sintaxi del llenguatge. El lexema de l'identificador no és útil en l'anàlisi sintàctica però és fonamental per a l'anàlisi semàntica i per a la generació de codi. Exemple,

Símbols especials

Normalment cada símbol especial és un token i el seu lexema a la vegada. Són símbols especials: (, ) :, ; , .., [, ], etc. Exemple,

Page 36: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

32

Paraules claus

En la majoria dels llenguatges de programació, les paraules claus estan reservades, és a dir, no es poden utilitzar noms de paraules claus com identificadors. En aquest cas, es defineixen tants tokens com paraules claus com hi hagi, de tal manera que cada token tingui com únic lexema a ell mateix. Exemple,

Tipus predefinits

Els tipus predefinits, per exemple, SENCER, REAL , CHAR ,... poden ser tokens individuals o poden ser agrupats. Aquesta decisió afecta la gramàtica. Exemple,

El lexema del tipus no és útil en l'anàlisi sintàctica però és fonamental per a l'anàlisi semàntica.

Noms de tokens

Els noms dels tokens han de correspondre amb els terminals de la gramàtica. Per exemple, sigui el següent fragment d'una gramàtica: inst --> IF expr THEN inst inst --> IF expr THEN inst ELSE inst expr --> terme OPER_REL terme expr --> terme terme --> ID terme --> CTE_SENCERA Els terminals IF, THEN, ELSE, ID, OPER_REL, ID, CTE_SENCERA són tokens reconeguts per a l'analitzador lexicogràfic.

Page 37: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

33

RESUM La unitat lexical indivisible d'un llenguatge de programació és un token. Cada token està definit mitjançant una expressió regular. Un token pot estar representant un únic lexema o diversos. La decisió a l'hora d'escollir els tokens afecta la gramàtica ja que aquests en són els terminals. Els identificadors, els operadors, les constants, les paraules claus , els símbols especials i els identificadors de tipus predefinits són tokens.

Page 38: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

34

Page 39: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

35

SESSIÓ 7: Implementació, errors i la seva recuperació

FITXA DE LA SESSIÓ Nom: Implementació, errors i la seva recuperació Tipus: teòrica Format: no presencial Durada: 3 hores Treball a lliurar: no

OBJECTIUS Donar les diferents maneres d'implementar un analitzador lexicogràfic. Caracteritzar els tipus d'errors que poden produir-se durant l'anàlisi lexicogràfica. Donar les estratègies per a la recuperació de l'analitzador lexicogràfic quan hi ha un error.

CONTINGUTS

3.4 Implementació d'un analitzador lexicogràfic

3.4.1 Implementació d'un analitzador lexicogràfic Un analitzador lexicogràfic és un autòmat d'estats finits. Per implementar-lo podem: 1. Implementar el diagrama de transicions de l'autòmat. 2. Implementar l'autòmat mitjançant casos (amb la instrucció case). 3. Utilitzar una eina per la construcció de compiladors i definir les diferents expressions regulars.

Taula de transicions

Un autòmat d'estats finits és un reconeixedor de llenguatges regulars. Cada expressió regular pot ser reconeguda per un autòmat finit. Un autòmat està format bàsicament per un conjunt d'estats i una taula de transicions que dóna el pròxim estat a partir de l'estat actual i de l'entrada. Com hem vist abans, un analitzador lexicogràfic reconeix un conjunt de tokens, cada token és una expressió regular, per tant cada token pot tenir el seu autòmat.

Page 40: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

36

L'analitzador serà la unió de tots els autòmats. Es pot implementar fàcilment un analitzador implementant la taula de transicions de l'autòmat que resulta de la unió.

Algorisme amb casos

Una altra manera d'implementar l'analitzador lexicogràfic és programar l'autòmat amb una seqüència de casos mitjançant un algorisme iteratiu.

Eines

La manera més fàcil i ràpida d'implementar un analitzador lexicogràfic és utilitzant una de les eines per la construcció de compiladors. Per poder fer-ho efectivament ràpid s'ha de saber definir tokens mitjançant expressions regulars. Com havíem comentat en sessions anteriors, es disposen de moltes eines per a la construcció d'analitzadors lexicogràfics.

3.4.2 Treballs (recomanats)

JavaCC i l'anàlisi lexicogràfica

Estudieu com es pot implementar un analitzador lexicogràfic amb l'eina JavaCC. Estudieu en detall la sintaxi de les expressions regulars. Feu una prova, implementant diferents tokens.

Llenguatge i els seus aspectes regulars

Busqueu la definició d'un llenguatge de programació i estudieu els seus aspectes regulars.

3.5 Errors i recuperació

3.5.1 Errors i la seva recuperació Els tipus d'error que poden ser donats per un analitzador lexicogràfic i les respectives estratègies per recuperar-se'n depenen de com s'implementi l'analitzador.

Page 41: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

37

Tipus d'error

Si utilitzem una eina amb la qual definim els tokens amb expressions regulars, es detectarà un error quan hi hagi un caràcter a l'entrada que no permeti aplicar cap dels patrons corresponents. L'error serà únic: “símbol no reconegut”. Si implementem directament l'autòmat d'estats finits podríem donar errors més precisos dins de cada expressió regular.

Rutines de recuperació

La recuperació d'errors és molt important en totes les fases d'un compilador ja que es vol donar el màxim número d'errors. Si hem implementat l'analitzador amb una eina, la manera més fàcil de recuperar-se és definir un token ERROR que serà una mena de pou. D'aquesta manera es reconeix el caràcter invàlid donant un missatge d'error i se segueix amb l'anàlisi lexicogràfica.

RESUM Un analitzador lexicogràfic és un autòmat d'estats finits. Es pot implementar programant la taula de transicions o programant tot l'autòmat. La manera més ràpida i fàcil és utilitzar una de les eines per a la construcció de compiladors. Els errors lexicogràfics i la seva recuperació depenen directament de com implementem l'analitzador.

Page 42: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

38

Page 43: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

39

SESSIÓ 8: Aplicacions

FITXA DE LA SESSIÓ Nom: Aplicacions Tipus: teòrica Format: no presencial Durada: 1 hores Treball a lliurar: no

OBJECTIUS Donar algunes aplicacions de la teoria que es fa servir en la construcció d'analitzadors lexicogràfics.

CONTINGUTS

3.6 Aplicacions

3.6.1 Aplicacions Les eines que hem estudiat per automatitzar la construcció d'analitzadors lexicogràfics permeten definir patrons (expressions regulars) i fer accions (codi en un llenguatge de programació) sobre aquests patrons. Aquesta característica dóna la possibilitat de programar aplicacions d'altres àrees que necessitin un tractament de patrons de forma fàcil i ràpida. Entre les aplicacions conegudes, destaquem: - Reconeixement d'imperfeccions en circuits impresos. Els circuits són escanejats i convertits en una seqüència de caràcters representant les línies i els angles. - Cerques bibliogràfiques. - Formatadors de textos. - Edició de textos. Podeu consultar detalls d'aquestes aplicacions en la bibliografia.

Page 44: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

40

3.6.2 Treball (opcional)

Aplicacions

Doneu dues aplicacions que puguin ser implementades utilitzant les tècniques de construcció d'analitzadors lexicogràfics.

RESUM L'utilització d'expressions regulars no està limitada a la construcció d'analitzadors lexicogràfics. Moltes aplicacions que necessiten reconèixer patrons poden ser implementades utilitzant les tècniques estudiades.

Page 45: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

41

SESSIÓ 9: Sintaxi i tipus de parsers

FITXA DE LA SESSIÓ Nom: Sintaxi i tipus de parsers Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no

PRECEDENTS Fins ara hem estudiat les fases següents del procés de la compilació: l'anàlisi lexicogràfica.

OBJECTIUS Introduir la fase d'anàlisi sintàctica d'un compilador. Introduir els dos tipus de parser (analitzadors sintàctics) que estudiarem en detall en les pròximes sessions: els analitzadors sintàctics descendents (LL) i els analitzadors sintàctics ascendents (LR).

Page 46: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

42

CONTINGUTS

4 L'anàlisi sintàctica

4.1 Sintaxi

4.1.1 Sintaxi

Revisió del concepte de gramàtica incontextual

El formalisme utilitzat, normalment, per descriure la sintaxi d'un llenguatge de programació és el de les gramàtiques incontextuals. Un vocabulari és una col·lecció de caràcters. El conjunt de caràcters ASCII és un bon exemple d'un vocabulari. Una paraula és una seqüència de caràcters del vocabulari. En la sintaxi dels llenguatges de programació es diu que una paraula és un token. Una sentència és una seqüència d'una o més paraules. Un llenguatge és un conjunt de sentències. En el cas d'un llenguatge de programació, cada sentència és un programa (sintàcticament correcte). Mitjançant una gramàtica s'especifica l'ordre que han de tenir les paraules per formar sentències vàlides. Una gramàtica incontextual consisteix d'un conjunt finit de terminals (T), un conjunt finit de no-terminals (N), un símbol axioma i un conjunt finit de produccions (P): 1. Els terminals són les paraules. En el cas d'una gramàtica que defineix un llenguatge de programació els terminals són els tokens i per tant la seva sintaxi és regular. Recordeu que els tokens són les construccions regulars dels llenguatges i per tant poden ser reconeguts per l'analitzador lexicogràfic. 2. Els no-terminals són variables sintàctiques que ajuden a definir la sintaxi. Els no-terminals són utilitzats conjuntament amb els terminals en les produccions. 3. En una gramàtica hi ha un no-terminal especial que és el símbol axioma (o objectiu) que s'utilitza per generar les sentències del llenguatge. Com veurem després tota derivació comença amb el símbol axioma. 4.Les produccions de la gramàtica especifiquen la manera de combinar-se els terminals i les no-terminals per formar sentències. Cada producció (regla) és de la forma següent: A --> α

Page 47: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

43

on A pertany a N, és a dir, la part esquerra de la regla és un no-terminal i α pertany a (NUT)*, és a dir, la part dreta de la regla és un conjunt de terminals i no-terminals. Per exemple la gramàtica amb les següents produccions defineix expressions aritmètiques: E --> E + T E --> T T --> T * F T --> F F --> ( E ) F --> id El conjunt dels terminals és T={+,*,(,),id}, el conjunt dels no-terminals és N={E,T,F} i el símbol axioma és E.

Revisió del concepte de derivació

Les gramàtiques són considerades formalismes generadors ja que la manera de veure el llenguatge que defineixen és generant-lo. Així, començant pel símbol axioma i derivant podem trobar una frase del llenguatge. És a dir, parem de derivar quan hem arribat a un string que només té tokens. La relació de derivació ens permet construir un string a partir d'un altre string i d'una regla de producció de la gramàtica. Aquesta relació (=>) es defineix com:

( ) ( ) αδγαβγδβαβγ ⇒∈→∪∈ ,*)( PiTNSi

Revisió de tipus de derivació

En cada pas d'una derivació, escollim el no-terminal que hem de substituir. Tenim dues maneres d'escollir el no-terminal, escollint el més a la dreta o escollint el més a l'esquerra. Així, podem dir que hi ha dues derivacions possibles per a cada frase, la derivació més a la dreta (=>d) i la derivació més a l'esquerra (=>e). Per exemple, sigui la següent gramàtica:

volem derivar la sentència id + id * id que pertany al llenguatge. A partir del símbol axioma E, la derivació més a l'esquerra és:

A partir del símbol axioma E, la derivació més a la dreta és:

Page 48: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

44

Revisió de llenguatge generat per una Gramàtica G

El llenguatge generat per una gramàtica, informalment, és el conjunt de totes les sentències derivades a partir del símbol axioma. Formalment,

}**,/{)( ωωω ⇒∈= STGL on S és el símbol axioma i la notació =>* expressa que es deriva en 0 o més passos però sempre en un nombre finit.

Arbres i derivacions

Un arbre de parser és una representació gràfica d'una derivació. Els nodes interns de l'arbre estan etiquetats amb no-terminals i les fulles són els tokens. L'arrel és el símbol axioma. Si construïm els arbres de parser per les dues derivacions (la més a la dreta i la més a l'esquerra) d'una mateixa frase, trobarem que els arbres són iguals. Per exemple, sigui la gramàtica següent:

La construcció de l'arbre de parser que correspon a la derivació més a l'esquerra és:

Page 49: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

45

La construcció de l'arbre de parser que correspon a la derivació més a la dreta és:

Fixeu-vos que en els dos casos els arbres obtinguts són el mateix. L'únic cas en què els arbres poden ser diferents és quan la gramàtica és ambigua. Aquest cas s'estudiarà en una sessió posterior.

4.2 Tipus de parsers

4.2.1 Tipus de "parser" Analitzar sintàcticament una sentència determinada és trobar per a ella un arbre de parser que tingui com arrel el símbol axioma de la gramàtica i com fulles la sentència tot i aplicant les regles de la gramàtica. Si es pot construir l'arbre aleshores la sentència correspon al llenguatge. En cas contrari, la sentència no pertany al llenguatge i es produeix un error sintàctic. Un analitzador sintàctic (parser d'ara endavant) pot reconèixer sintàcticament una entrada de dues formes: 1. Construint l'arbre sintàctic (o arbre de parser) començant per l'arrel. 2. Construint l'arbre sintàctic (o arbre de parser) començant per les fulles. La primera correspon a l'anàlisi sintàctica descendent i la segona a l'anàlisi sintàctica ascendent. En les pròximes sessions, estudiarem a fons els dos tipus de parsers.

Page 50: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

46

Anàlisi sintàctica descendent

L'anàlisi sintàctica descendent es fa utilitzant parsers descendents. També s'anomenen parsers top-down ja que construeixen l'arbre de dalt a baix. La construcció descendent equival a una derivació més a l'esquerra. En les pròximes sessions estudiarem dues famílies de parsers descendents: els recursius i els tabulars. Les gramàtiques per a les quals podem construir un parser descendent predictiu són anomenades gramàtiques LL. La primera L vol dir que l'entrada (la sentència a reconèixer) es llegeix d'esquerra (Left) a dreta i la segona L vol dir que es produeix una derivació més a l'esquerra (Left).

Anàlisi sintàctica ascendent

L'anàlisi sintàctica ascendent es fa utilitzant parsers ascendents. També anomenats parsers bottom-up ja que construeixen l'arbre de baix a dalt. La construcció ascendent equival a una derivació més a la dreta. En les pròximes sessions estudiarem tres famílies de parsers ascendents: els simples SLR, els canònics LR i els lookahead LR. Les gramàtiques per a les quals podem construir un parser ascendent són anomenades gramàtiques LR. La L vol dir que l'entrada es llegeix d'esquerra (Left) a dreta i la R vol dir que es produeix una derivació més a la dreta (Right).

RESUM Hem introduït els conceptes bàsics per estudiar els analitzadors sintàctics. Per descriure formalment la sintaxi d'un llenguatge de programació s'utilitzen gramàtiques incontextuals.

Page 51: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

47

SESSIÓ 10: Eliminació de recursivitat a esquerra i factorització

FITXA DE LA SESSIÓ Nom: Eliminació de recursivitat a esquerra i factorització Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no

OBJECTIUS Introduir els parsers descendents i estudiar les condicions que ha de tenir una gramàtica per ser LL(1).

CONTINGUTS

4.3 L'anàlisi descendent (LL)

4.3.1 El procés general Els parsers LL són analitzadors sintàctics que fan una anàlisi top down, és a dir, construeixen l'arbre de parser començant per l'arrel (etiquetada amb el símbol axioma) i acabant en les fulles (terminals de la gramàtica). Les produccions de la gramàtica són aplicades d'esquerra a dreta, és a dir, expandint el no-terminal de la part esquerra per la part dreta corresponent.

Parsers top-down

El procés que segueix un parser top-down per construir l'arbre de parser és el següent: 1. Crear el node arrel etiquetant-lo amb el símbol axioma de la gramàtica. 2. Repetir els següents passos:

2.1 En el node n etiquetat amb el no-terminal A seleccionar una de les produccions de A i construir tants fills a n com símbols tingui la part dreta de la producció escollida.

2.2 Seleccionar el pròxim node a partir del qual el subarbre serà construït.

Page 52: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

48

La construcció de l'arbre de parser amb aquesta tècnica és equivalent a construir una derivació més a l'esquerra de l'entrada utilitzant la gramàtica. Si la selecció de la producció en el pas 2.1 no es fa bé podria forçar un backtracking durant el procés. Si el pròxim node en el pas 2.2 és sempre el més a l'esquerra i la gramàtica és recursiva a esquerra, el procés podria entrar en un llaç infinit. Aquests dos motius ens portaran a estudiar quines condicions ha de complir la gramàtica per poder fer una anàlisi sintàctica eficient i predictiva.

Exemple de construcció de l'arbre de parser

Per a la gramàtica següent: Type --> Simple Type --> ^ id Type --> array [ Simple ] of Type Simple --> integer Simple --> char Simple --> num dotdot num La construcció parcial de l'arbre de parser per l'entrada array[num dotodot num] of integer és:

Page 53: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

49

Tipus de parser

Estudiarem dos tipus de parsers descendents: els recursius i els tabulars. Els recursius s'implementen amb un conjunt de procediments recursius (un per cada no-terminal de la gramàtica) i els tabulars amb una taula i un algorisme d'anàlisi.

4.3.2 Consideracions per a una anàlisi top-down eficient i predictiva

En primer lloc es donen les condicions que han de complir-se per poder fer una anàlisi sintàctica determinista i que finalitzi. Després es donen els algorismes que permeten transformar gramàtiques per aquesta finalitat.

Condicions necessàries

Per fer una anàlisi sintàctica que funcioni i sigui predictiva han de complir-se com a mínim les següents condicions: 1.La gramàtica no pot ser recursiva a esquerra ja que el parser no acabaria. Una gramàtica és recursiva a esquerra si el no-terminal de l'esquerra pot derivar en un o més passos en una forma sentencial començant pel mateix no-terminal. Per exemple, la gramàtica:

és recursiva a esquerra ja que té les produccions:

A aquesta mena de recursivitat és anomenada recursivitat immediata. Per exemple la gramàtica: S Aa S b A Ac A Sd A ε és recursiva a esquerra ja que té recursivitat immediata en la producció: A Ac i recursivitat indirecta en la producció: A Sd

Page 54: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

50

2.La gramàtica no pot tenir diverses produccions per a un mateix no-terminal que comencin amb els mateixos símbols. És a dir, la gramàtica ha d'estar factoritzada. Per exemple, la gramàtica: S i E t S S i E t S e S S a E b no està factoritzada ja que té les produccions:

Més endavant veurem que aquestes condicions són necessàries però no suficients. En els apartats següents estudiarem els algorismes per transformar les gramàtiques amb la finalitat d'acomplir les condicions anteriors.

Algorisme per a l'eliminació de recursivitat esquerra

Tota gramàtica incontextual recursiva a esquerra pot ser transformada mitjançant un algorisme. Esquemàticament, eliminar recursivitat a esquerra vol dir transformar l'arbre de l'esquerra en l'arbre de la dreta.

L'algorisme elimina tant la recursivitat immediata com la indirecta.

Page 55: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

51

Algorisme: 1. Numerar els no-terminals de la gramàtica: A1, A2, ... An 2. Per i = 1 fins n fer Inici 2.1 Per j = 1 fins i – 1 fer Substituir les produccions de la forma: Ai Aj γ

per les produccions: Ai δ1 γ / δ2 γ/.../ δk γ, On, Aj δ1 / δ2/... / δk són totes les produccions Aj actuals.

2.2 Eliminar la recursivitat immediata d'Ai substituint les produccions de la forma:

Ai Ai α1 / Ai α2 /... Ai αm / β1 / β2 /.../ βp per: Ai β1 Ai' / β2 Ai' / ... / βp Ai' Ai' α1 Ai' / α2 Ai' / .... / αm Ai'/ ε Fi

Un exemple d'eliminació de recursivitat esquerra

Utilitzant l'algorisme anterior, la gramàtica: E E + T E T T T * F T F F ( E ) F id pot ser transformada en: E T E' E' + T E' E' ε T F T' T' * F T' T' ε F ( E ) F id Podeu trobar la solució pas a pas en el problemari (problema 4.3).

Page 56: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

52

Algorisme per a la factorització

Tota gramàtica incontextual amb produccions no factoritzades pot ésser transformada mitjançant un algorisme. Algorisme: - Per tal que cada no-terminal A busqui el prefix α més llarg que sigui comú a dues o més parts dretes d'aquest no-terminal i apliqui la següent regla:

Si A α β1 / α β2 / ... / α βn / γ1 / γ2 / .... γk aleshores subsituir aquestes produccions per les produccions següents: A α A' / γ1 / γ2 / .... γk A' β1 / β2 / ... / βn

on A' és un nou no-terminal. Per transformar una gramàtica, primer s'ha d'eliminar la recursivitat a esquerra i després factoritzar-la.

Un exemple de factorització

Utilitzant l'algorisme anterior, la gramàtica:

S i E t S S i E t S e S S a E b

pot ser transformada en:

S i E t S S’ S a S’ e S S’ ε E b

RESUM Hem estudiat com funciona globalment un parser descendent i hem après a caracteritzar i a transformar una gramàtica per tal que sigui LL(1). Hem estudiat els algorismes per eliminar la recursivitat a esquerra de les gramàtiques i per factoritzar-les.

Page 57: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

53

Page 58: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

54

SESSIÓ 11: Analitzadors descendents recursius

FITXA DE LA SESSIÓ Nom: Analitzadors descendents recursius Tipus: teòrica Format: no presencial Durada: 3 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Elder1994]

OBJECTIUS Introduir la família de parsers descendents recursius i estudiar les condicions suficients que ha de complir una gramàtica per ser LL(1).

CONTINGUTS

4.3.3 Anàlisi descendent recursiva A partir d'una gramàtica que no sigui recursiva a esquerra i que estigui factoritzada podem, en principi, construir un parser predictiu recursiu. L'objectiu és escriure un procediment per cada no-terminal. Amb la part dreta de la producció construirem el cos del procediment.

Un exemple de parser descendent recursiu

Per a la gramàtica:

S c A d A a B B b B ε

podem construir el següent analitzador sintàctic descendent recursiu:

Proc S; Inici Acceptar(“c”); A; Acceptar(“d”); fi;

Page 59: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

55

Proc A; Inici Acceptar(“a”); B; fi; Proc B; Inici Si lookahead =”b” llavors Acceptar(“b”); fi; Proc Acceptar(t: token); Inici Si lookahead =t llavors lookahead := pròxim_token si no escriure(“error”); fi;

Com podeu observar tenim un procediment per a cada no-terminal i un procediment Acceptar que llegeix l'entrada i verifica que correspon amb el terminal esperat. En cas que no sigui així, es dóna un error. El programa principal seria el següent: Inici S; Si lookahead = <EOF> llavors escriure(“l'entrada ha estat acceptada”); fi; La crida S; en el programa principal correspon al símbol axioma de la gramàtica.

Regles per a la construcció automàtica d'un parser descendent recursiu

A partir d'una gramàtica i seguint un conjunt de regles, es pot construir automàticament un parser descendent. Aquesta tècnica és utilitzada per la majoria de les eines que trobem per a la construcció d'analitzadors sintàctics descendents. Podeu trobar el conjunt de regles per a la construcció d'un analitzador descendent recursiu en la referència.

[Elder1994] p86-p90

4.3.4 Condicions suficients LL(1) Les condicions de factorització i d'eliminació de recursivitat a esquerra no són suficients per assegurar una anàlisi top-down sense backtracking. Si per a la gramàtica següent:

Page 60: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

56

E A E F E ( L ) A i F i ( L ) L E L' L' , E L' L' ε

intentem construir un parser descendent recursiu, trobarem que en el procediment E, el “case” no és determinista ja que A pot començar amb i i F també. Això vol dir que aquestes condicions no són suficients.

Gramàtiques LL(k)

Una gramàtica per a la qual podem construir un analitzador eficient i predictiu (sense backtracking), és a dir, que sàpiga seleccionar la pròxima producció examinant els primers k símbols de l'entrada és anomenada LL(k). Per aplicacions pràctiques es restringeix a k =1, és a dir, a LL(1).

Símbols directors (DS)

Els símbols directors (DS) d'una producció A --> α, són el conjunt de terminals definit de la següent manera:

{ }FOLLOW(A) x llavors* si oFIRST( / x T x x,)DS(A, ε ε⇒ α )αεε=α Els símbols directors d'una producció representen tots els possibles terminals que poden aparèixer en l'entrada per als quals la producció es podria aplicar. Com podem observar la definició està en funció de dos altres conceptes: els FIRST's i els FOLLOW's, els quals passem a definir. Una vegada definits els DS, els FOLLOW's i els FIRST's donarem una condició suficient depenent dels DS que ha de complir una gramàtica per que sigui LL(1) i per tant per a la qual podrem construir un parser descendent deterministe .

FIRST's

Els FIRST's d'un string α formen el conjunt de terminals que poden aparèixer al començament de qualsevol string derivat des de α utilitzant la gramàtica. Si α deriva a ε , ε també pertany els FIRST's.

)*}(,*/{)( NTxTxFIRST ∪∈⇒∈= ββαα Els FIRST's s'utilitzen per calcular els DS, per tant normalment voldrem calcular els FIRST's d'una part dreta d'una producció. És a dir, voldrem calcular els FIRST( α) on α pertany (T U N)*.

Page 61: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

57

Per calcular FIRST( α), on α= X1X2...Xn i cada Xi és o un terminal o un no-terminal, podem seguir les següents regles:

- FIRST(x)={x}, per tot x que pertany a T. És a dir, els FIRST d'un terminal és el mateix terminal. - FIRST(A) = FIRST(X1X2.....Xn), per tot A que pertany a N i A --> X1X2.....Xn és una producció. És a dir, els FIRST d'un no-terminal són els FIRST de la seva part dreta. Si té més d'una part dreta, els FIRST del no-terminal és la unió dels FIRST de totes les seves parts dretes. - FIRST(X1X2.....Xn) = FIRST(X1) U FIRST(X2).... U FIRST(Xk), tal que 1<=k<=n , ε pertany a tots els FIRST(Xj) per 1<=j<=k-1 i ε no pertany a FIRST(Xk).

Per exemple, sigui la gramàtica següent:

E TE' E' +TE' E' ε T FT' T' *FT' T' ε F ( E ) F id

els FIRST's de les parts dretes són: FIRST(TE') =1 FIRST(T) =2 FIRST(FT') =3 FIRST(F)=4 FIRST((E)) U FIRST(id) =5 FIRST(() U {id} =6 {(,id} =1, ja que T no pot derivar a ε =2, ja que FT' és la part dreta del no-terminal T =3, ja que F no pot derivar a ε =4, ja que F té dos parts dretes =5, ja que ( és un terminal i per tant no deriva a ε i el FIRTS(id) = {id} =6, ja que els FIRST d'un terminal és el mateix terminal FIRST(+TE') = FIRST(+) = {+} FIRST(ε) = {ε} FIRST(FT') = FIRST(F) = FIRST((E)) U FIRST(id) =FIRST(() U {id} = {(,id} FIRST(*FT') = FIRST(*) = {*} FIRST((E)) = FIRST(() = {(} FIRST(id) = {id}

Page 62: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

58

FOLLOW's

Els FOLLOW's d'un no-terminal A formen el conjunt de terminals que poden aparèixer a la dreta d'A en qualsevol derivació que es faci des del símbol axioma de la gramàtica. Els FOLLOW's sempre es calculen per un no-terminal i mai contenen ε.

)*}(,,*/{)( NTAxSTxAFOLLOWS ∪∈⇒∈= βαβα Per calcular FOLLOWS(A), on A és un no-terminal, podem aplicar les següents regles fins que no puguem afegir cap nou terminal al conjunt:

1. Si A és el símbol axioma aleshores afegir als FOLLOWS(A) el terminal $. Aquest terminal marca la fi de l'entrada. 2. Si B αAβ aleshores afegir en els FOLLOWS(A) els FIRST(β) – {ε} 3. Si B αA o (B αAβ i ε pertany a FIRST(β)) alehores afegir en els FOLLOWS(A) els FOLLOWS(B).

Per exemple, sigui la gramàtica següent: E TE' E' +TE' E' ε T FT' T' *FT' T' ε F ( E ) F id els FOLLOWS de cada no-terminal són: FOLLOWS(E) = FIRST()) U {$} = {),$} ja que ) apareix després de E en una part dreta (regla 2) i $ per regla 1 FOLLOWS(E') =1 FOLLOWS(E) U FOLLOWS(E') =2 FOLLOWS(E) =3 {),$} =1, ja que E' apareix en dues parts dretes i al final (regla 3) =2, ja que FOLLOWS(E') és el que estem calculant =3, calculats abans FOLLOWS(T) =1 FIRST(E') U FOLLOWS(E) U FOLLOWS(E') = {+,),$} =1, ja que T apareix dues vegades en dues parts dretes i hem aplicat les regles 2 i 3 FOLLOWS(T') = FOLLOWS(T) U FOLLOWS(T') = FOLLOWS(T) = {+,),$} FOLLOWS(F) = FIRST(T') U FOLLOWS(T) U FOLLOWS(T') = FIRST(*FT') U {+,),$} = {*, +,),$}

Page 63: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

59

Condició LL(1)

Una vegada que sabem com calcular els FIRST's, els FOLLOW's i els Símbols Directors, podem verificar si la condició suficient LL(1) es compleix per a una gramàtica donada. Una condició necessària i suficient perquè una gramàtica sigui LL(1) és que per a cada no-terminal de la gramàtica, els símbols directors de les seves parts dretes han de ser conjunts disjunts. Com exemple verificarem que la gramàtica següent compleix la condició LL(1) mitjançant el concepte de símbol director:

E TE' E' +TE' E' ε T FT' T' *FT' T' ε F ( E ) F id

Per comprovar la condició LL(1) hem de calcular els símbols directors dels no-terminals que tinguin més d'una part dreta (E', T' i F) ja que si en tenen una sola no pot haver-hi cap conflicte de no-determinisme. DS(E', +TE') = {+} DS(E', ε) = FOLLOWS(E') = {),$} La intersecció d'aquests dos conjunts és buida per tant el no-terminal E' compleix la condició LL(1). DS(T', *FT') = {*} DS(T' , ε) = FOLLOWS(T') = {+,),$} La intersecció d'aquests dos conjunts és buida per tant el no-terminal T' compleix la condició LL(1). DS(F , ( E )) = {(} DS(F , id) = {id} La intersecció d'aquests dos conjunts és buida per tant el no-terminal F compleix la condició LL(1). Com tots els no-terminals compleixen la condició LL(1), la gramàtica és LL(1).

RESUM Hem après a construir parsers descendents recursius de forma automàtica a partir de la gramàtica. Hem estudiat una condició suficient per caracteritzar les gramàtiques LL(1) mitjançant els símbols directors.

Page 64: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

60

SESSIÓ 12: Analitzadors descendents tabulars

FITXA DE LA SESSIÓ Nom: Analitzadors descendents tabulars Tipus: teòrica Format: no presencial Durada: 3 hores Treball a lliurar: no

OBJECTIUS Introduir la família de parsers descendents tabulars i estudiar com l'ambigüitat de les gramàtiques afecta la construcció dels parsers.

CONTINGUTS

4.3.5 Anàlisi descendent tabular Per a una gramàtica LL(1) podem construir un analitzador sintàctic descendent tabular. Així, en lloc de mantenir una pila de forma implícita (per a les crides recursives), podem mantenir una pila de forma explícita.

Parts d'un parser tabular

Un parser descendent tabular està format per: una pila. l'entrada. una taula de parser. un algorisme de parser predictiu. una sortida.

Page 65: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

61

La pila conté inicialment els símbols $S, on $ marca el fons de la pila i S és el símbol axioma que està en el cim. La pila s'utilitza per expandir els no-terminals i anar creant parts de l'arbre de parser, per tant la pila pot tenir terminals i no-terminals. L'entrada és la seqüència que volem analitzar sintàcticament. Tota entrada es llegeix d'esquerra a dreta i té el símbol $ com marca de fi d'entrada. La taula de parser (M) indica quina producció hem d'aplicar depenent del no-terminal que tenim a la pila per expandir i el terminal actual de l'entrada. L'aplicació de la producció és una acció sobre la pila. La taula té dues dimensions M[X,a], on M és un no-terminal i a és un terminal o el símbol $. Cada casella de la taula pot ser, bé una producció de la gramàtica o bé pot estar buida. En aquest últim cas vol dir que aquesta configuració no està definida i per tant correspon a una errada sintàctica. L'algorisme de parser predictiu és el cos de l'analitzador sintàctic que controla tots els elements i produeix una sortida. La sortida pricipal és una llista d'errades sintàctiques si l'entrada no és correcta sintàcticament o un missatge d'acceptació si l'entrada és correcta sintàcticament. Abans d'aprendre a construir aquesta mena de parsers, n'estudiarem el funcionament.

Algorisme de parser predictiu

Inicialment el parser té la següent configuració:

• Pila = $ S • Entrada = w $, on w és la seqüència que volem analitzar sintàcticament • Taula de parser M = una matriu construïda a partir de la gramàtica del

llenguatge que volem reconèixer. Algorisme: Sigui lh (lookahead) el primer símbol (token) de l'entrada w$ Repetir X = símbol cim de la pila Si X és un terminal o X = $ llavors

Si X = lh llavors // el cim de la pila i l'entrada coincideixen Desempilar X de la pila lh = pròxim símbol de l'entrada si no // error sintàctic Donar l'error Cridar una rutina de recuperació d'error fisi

Page 66: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

62

si no // X és un no-terminal Si M[X,lh] = X --> Y1Y2....Yk llavors

// s'ha d'expandir el no-terminal de la pila cap a la seva corresponent part dreta

Desempilar X de la pila Empilar YkYk-1....Y2Y1 amb Y1 en el cim si no // error sintàcti Donar l'error Cridar una rutina de recuperació d'error fisi

fisi fins X = $ // pila buida Si lh = $ llavors escriure (“w pertany al llenguatge reconegut”) si no escriure(“w NO pertany al llenguatge reconegut”) fisi

Un exemple de taula de parser

Per a la gramàtica d'expressions transformada: (1) E TE' (2) E' +TE' (3) E' ε (4) T FT' (5) T' *FT' (6) T' ε (7) F ( E ) (8) F id La taula de parser és la següent:

En les pròximes sessions aprendrem a construir aquestes taules.

Anàlisi sintàctica d'una entrada

Per analitzar sintàcticament una entrada, hem d'aplicar l‘algorisme de parser sobre una entrada.

Page 67: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

63

Començant pel símbol axioma E en la pila i per l'entrada correcta del llenguatge generat per la gramàtica anterior id + id * id, l'anàlisi sintàctica és la següent:

Construcció de la taula de parser

A partir d'una gramàtica G podem construir una taula de parser utilitzant el següent algorisme. Algorisme: Entrada: G Sortida: Taula de parser per G 1. Per a cada producció de la gramàtica (i) A α de G fer

1.1 Per a cada terminal a en els FIRST( α) fer M[A,a] = i 1.2 Si ε pertany a FIRST( α) llavors 1.2.1.Per a cada terminal b en els FOLLOWS(A) fer M[A,b] = i 1.2.2 Si $ pertany a FOLLOWS(A) llavors M[A,$] = i

2. Totes les caselles buides representen errors i s'hauran de recuperar mitjançant rutines de recuperació. Si en construir la taula hi ha conflictes, és a dir, alguna entrada de la taula no està definida de forma única direm que la gramàtica no és LL(1). Una gramàtica per a la qual es pot construir una taula sense conflictes és anomenada LL(1). Podeu consultar la construcció de la taula de parser per a la gramàtica: (1) E TE'

Page 68: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

64

(2) E' +TE' (3) E' ε (4) T FT' (5) T' *FT' (6) T' ε (7) F ( E ) (8) F id en el problemari.

4.3.6 Ambigüitat en LL

Gramàtica ambigua

Una gramàtica és ambigua si per a alguna entrada poden construir-se dos arbres sintàctics diferents. Per demostrar que una gramàtica és ambigua s'ha de construir, per a una entrada correcta, dos arbres sintàctics diferents. A continuació donem alguns exemples de gramàtiques ambigües i les corresponents proves. a) La gramàtica: S i E t S S' S a S' e S S' ε E b és ambigua ja que per a l'entrada correcta: i b t i b t a e a, podem construir dos arbres diferents:

Page 69: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

65

b) La gramàtica: S a S b S S b S a S S ε és ambigua ja que per a l'entrada correcta: a b a b, podem construir dos arbres diferents:

Construccions ambigües

A continuació mostrem algunes formes que adopten les produccions que fan que la gramàtica sigui ambigua.

Page 70: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

66

Teorema

Cap gramàtica ambigua ni recursiva a esquerra no pot ser LL(1). La gramàtica següent és ambigua: S i E t S S' S a S' e S S' ε E b Fixeu-vos en la taula de parser que es dóna a continuació. Hi ha una entrada que té dues produccions, això vol dir que la taula no és determinista i, per tant, la gramàtica no és LL(1).

RESUM Hem après a construir parsers descendents tabulars i a identificar les gramàtiques ambigües demostrant que ho són.

Page 71: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

67

SESSIÓ 13: Recuperació d'errors

FITXA DE LA SESSIÓ Nom: Recuperació d'errors Tipus: teòrica Format: no presencial Durada: 1 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Aho1985] [Elder1994]

PRECEDENTS En les sessions precedents hem estudiat els diferents analitzadors sintàctics descendents que podem construir a partir de gramàtiques incontextuals.

OBJECTIUS Estudiar les diferents estratègies per recuperar els errors durant l'anàlisi sintàctica amb la finalitat de donar el màxim d'errors durant el procés i poder acabar de forma controlada.

CONTINGUTS

4.3.7 Recuperació d'errors en parsers descendents En els parsers recursius, un error es presenta quan el token actual (lookahead) no es correspon amb l'esperat. L'error es produeix en el procediment Acceptar. En els parsers tabulars, un error es presenta quan la taula no està definida pel símbol que està en el cim de la pila i el token actual (entrada). Quan es produeix un error, s'ha de donar l'error i seguidament aplicar una estratègia per recuperar-lo. Els objectius de la recuperació d'errors són: 1. Poder reprendre la compilació el més a prop possible del lloc on s'ha produït l'error. 2. Evitar la generació d'errors en cascada produïda per errors anteriors.

Recuperació en parsers top-down

En un punt de l'anàlisi sintàctica, l'entrada té la següent forma: wtp on w representa el tros d'entrada analitzat, t representa el token actual (terminal de l'entrada) i p representa el tros d'entrada que queda per analitzar.

Page 72: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

68

L'error es produeix perquè t no és el token esperat. Aquest error pot ser degut a algun dels següents motius:

1. Algun símbol o símbols precedint t han estat omesos per error. 2. t està substituint a un altre símbol per error. 3. t és un símbol estrany introduït per error (està de més).

S'ha de decidir per a cada cas l'estratègia a seguir. Les estratègies consisteixen bàsicament a tractar de sincronitzar l'entrada. Podeu consultar aquestes tècniques de recuperació d'errors en la referència donada.

[Elder1994] p98-p100

Recuperació en parsers recursius

L'aplicació de les estratègies estudiades en l'apartat anterior en el cas de parsers recursius implicaria associar a la funció Acceptar un codi d'error de manera que poguéssim transferir el control a diferents punts del procediment. Això complicaria molt la implementació. En lloc, doncs, d'aquesta estratègia, es pot utilitzar una altra que es basa en el concepte de sincronització. La idea és mantenir una sincronització raonable entre l'analitzador i l'entrada. La sincronització es fa a l'entrada i a la sortida de cada procediment. Com conjunts de sincronització s'utilitzen principalment els conjunts dels FOLLOW's i dels FIRST's. Podeu trobar una discussió detallada d'aquesta estratègia en la referència indicada.

[Elder1994] p100-p105

Recuperació en parsers tabulars

En els parsers tabulars es detecta un error quan, durant l'anàlisi sintàctica, es consulta la taula i l'entrada corresponent és buida. Això vol dir, que per al símbol que està en el cim de la pila i el token actual, la taula no està definida. L'estratègia de recuperació d'errors en aquesta mena de parsers és semblant a la del parser descendent ja que es fa mitjançant conjunts de sincronització. Una discussió d'aquesta estratègia i un exemple són en la referència.

[Aho1985] p192-195 (Exemple 4.20, Figures 4.18 i 4.19)

RESUM Hem estudiat les diferents estratègies per a la recuperació d'errors en parsers descendents tant recursius com tabulars

Page 73: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

69

SESSIÓ 14: Problemes (parsers descendents)

FITXA DE LA SESSIÓ Nom: Problemes (parsers descendents) Tipus: de problemes Format: no presencial Durada: 3 hores Dedicació: 4 hores Treball a lliurar: no

OBJECTIUS Exercitar-nos en la resolució de problemes relacionats amb els parsers descendents.

CONTINGUTS En aquesta sessió es proposen un conjunt de problemes per als parsers descendents.

4.3.8 Problemes A continuació es proposen un conjunt de problemes relatius als analitzadors sintàctics descendents.

Eliminació de recursivitat i factorització

Feu els exercicis 4.1, 4.2 i 4.3 del problemari.

Anàlisi sintàctica d'una entrada correcta

Feu els exercicis 4.4 i 4.5 del problemari.

Construcció d'un parser descendent recursiu

Feu els exercicis 4.6 i 4.7 del problemari.

Construcció d'un parser descendent tabular

Feu els exercicis 4.35 i 4.36 del problemari.

Page 74: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

70

Demostració de condicions LL(1)

Feu els exercicis 4.8 i 4.9 del problemari.

Eina JavaCC

Feu els exercicis 4.10 del problemari.

Estratègies de recuperació d'errors

Feu els exercicis 4.11 i 4.12 del problemari.

Page 75: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

71

SESSIÓ 15: Una introducció als parsers ascendents

FITXA DE LA SESSIÓ Nom: Una introducció als parsers ascendents Tipus: teòrica Format: no presencial Durada: 1 hora Dedicació: 1 hora Treball a lliurar: no Material:

o Bibliografia bàsica: [Aho1985]

OBJECTIUS Introduir els parsers ascendents i estudiar com s'analitza sintàcticament una entrada.

CONTINGUTS

4.4 L'anàlisi ascendent (LR)

4.4.1 El procés general Els parsers LR són analitzadors sintàctics que fan una anàlisi bottom-up, és a dir, construeixen l'arbre de parser començant per les fulles i acabant en l'arrel. Els parsers LR que estudiarem són parsers shift-reduce ja que, com veurem a continuació, l'anàlisi sintàctica es fa utilitzant dues operacions: shift i reduce.

Parsers shift-reduce

Els parsers shift-reduce construeixen l'arbre de parser per una entrada llegint-la d'esquerra a dreta i intenten formar una part dreta de producció. Aleshores, aquesta part dreta es pot reduir a la seva part esquerra (un no-terminal). Per a la gramàtica següent: Type Simple Type ^ id Type array [ Simple ] of Type Simple integer Simple char Simple num dotdot num La construcció de l'arbre de parser per a l'entrada array[num dotodot num] of integer és:

Page 76: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

72

Arbre de parser: Entrada: array [ num dotdot num ] of integer ---------------------------------------------------------------------------------- Arbre de parser: array Entrada: array [ num dotdot num ] of integer ---------------------------------------------------------------------------------- Arbre de parser: array [ Entrada: array [ num dotdot num ] of integer ---------------------------------------------------------------------------------- Arbre de parser: array [ num Entrada: array [ num dotdot num ] of integer ----------------------------------------------------------------------------------- Arbre de parser: array [ num dotdot Entrada: array [ num dotdot num ] of integer ----------------------------------------------------------------------------------- Arbre de parser: array [ num dotdot num Entrada: array [ num dotdot num ] of integer --------------------------------------------------------------------------- Arbre de parser:

Entrada: array [ num dotdot num ] of integer ----------------------------------------------------------------------------------

Page 77: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

73

Arbre de parser:

Entrada: array [ num dotdot num ] of integer ---------------------------------------------------------------------------------- Arbre de parser:

Entrada: array [ num dotdot num ] of integer ------------------------------------------------------------------------------------ Arbre de parser:

Entrada: array [ num dotdot num ] of integer ---------------------------------------------------------------------------------- Arbre de parser:

Entrada: array [ num dotdot num ] of integer ---------------------------------------------------------------------------------- Arbre de parser:

Entrada: array [ num dotdot num ] of integer ---------------------------------------------------------------------------------- La construcció de l'arbre de parser amb aquesta tècnica és equivalent a la construcció d'una derivació més a la dreta de l'entrada utilitzant la gramàtica.

Page 78: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

74

Concepte de handle

Per poder reduir una part dreta al no-terminal corresponent, aquesta ha de ser un handle. Això vol dir que un handle és un sub-string d'una forma sentencial de la derivació de l'entrada des del símbol axioma. En l'exemple anterior quan hem reduït el string num dotdot num al no-terminal Simple ho hem fet perquè era un handle. Més detalladament podem mostrar quina seria la derivació més a la dreta per l'entrada: array [ num dotdot num ] of integer. Type => array [ Simple ] of Type => array [ Simple ] of integer => array [ num dotdot num ] of integer En cada pas de la derivació hem subratllat el handle.

Concepte de prefix viable

El conjunt de prefixos de formes sentencials que poden aparèixer en la pila d'un parser shift-reduce s'anomenen prefixos viables. Aquest concepte l'utilitzarem quan estudiarem els parsers en detall.

Parts d'un parser

Un parser està format per:

una pila, en la qual es construiran els arbres parcials. l'entrada. una taula de parser amb dues parts (ACTION i GOTO). un algorisme de parser. una sortida.

Page 79: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

75

La pila emmagatzema un string de la forma: EoXo....XmEm on cada Ei és un estat i cada Xi és un terminal o un no-terminal de la gramàtica. Cada estat dóna informació del que ja s'ha analitzat. Inicialment, la pila té l'estat inicial Eo. El contingut de la pila varia segons el que indica la taula de parser . L'entrada és la seqüència que volem analitzar sintàcticament. Tota entrada es llegeix d'esquerra a dreta i té el símbol $ com marca de fi d'entrada. La taula de parser té dues parts: la taula ACTION i la taula GOTO. La part ACTION indica l'operació a realitzar (shift o reduce) depenent de l'estat en el cim de la pila i l'entrada. La part GOTO indica el pròxim estat. L'algorisme de parser és el cos de l'analiltzador sintàctic que controla tots els elements i produeix una sortida. La sortida pricipal és una llista d'errades sintàctiques si l'entrada no és correcta sintàcticament o un missatge d'acceptació si l'entrada és correcta sintàcticament. Abans d'aprendre a construir aquesta mena de parsers, estudiarem el seu funcionament. La taula de parser La taula de parser consisteix en dues parts: - l'ACTION que dóna l'operació a realitzar depenent de l'estat en el cim de la pila i l'entrada, - el GOTO que dóna el pròxim estat depenent de l'estat actual i de la reducció que s'acaba de fer.

Els ti són terminals (tokens) de l'entrada, els Ni són els no-terminals de la gramàtica i els Ei són els estats. Les operacions possibles en consultar ACTION(Em, a) poden ser:

shift Ek : indica que s'ha d'empilar l'entrada a i que el nou estat és Ek reduce i : indica que dins la pila hi ha la part dreta de la producció i per

tant hem de substituir-la pel no-terminal de l'esquerra acceptar error.

Les caselles GOTO(Em,N) tenen un número d'estat.

Page 80: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

76

Les configuracions (pila i entrada) van variant segons aquestes operacions. Hi ha dos problemes per resoldre quan s'analitza sintàcticament una entrada:

1. Localitzar un handle dins la pila per reduir-lo. 2. Determinar quina producció s'aplica si hi ha més d'una producció amb les mateixes parts dretes.

La taula és la que resol aquests problemes.

Algorisme de parser

La taula varia segons el tipus de parser ascendent que construïm però l'algorisme de parser que analitza sintàcticament una entrada és sempre el mateix. L'algorisme és molt senzill, comença amb un estat inicial Eo a la pila i va consultant la taula ACTION per saber si ha d'empilar (shift) o fer una reducció (reduce). Inicialment el parser té la següent configuració:

• Pila = Eo • Entrada = w $, on w és la seqüència que volem analitzar sintàcticament • Salida = Taula de parser ACTION i GOTO

Algorisme: Sigui lh (lookahead) el primer símbol (token) de l'entrada w$ Repetir Sigui e l'estat en el cim de la pila a = lh Segons ACTION[e,a]

cas shift j (Sj) - Empilar a // a és el terminal de l'entrada - Empilar j // nou estat j - lh = pròmixa entrada cas reduce k (Rk) // k és la regla A --> α

- Desempilar els símbols corresponent a la part dreta de la regla k amb els respectius estats, és a dir, desempilar 2 * | α| símbols

- e' = l'estat del cim de la pila - Empilar A - Empilar GOTO(e',A) cas acceptar (ACC) - Retornar cas si no // error sintàctic - Donar l'error - Cridar una rutina de recuperació d'error

fisegons fins sempre;

Page 81: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

77

Un exemple de taula de parser

Per a la gramàtica d'expressions: E E + T E T T T * F T F F ( E ) F id la taula de parser és:

En les pròximes sessions aprendrem a construir-les.

Anàlisi sintàctica d'una entrada

Per a analitzar sintàcticament una entrada, hem d'aplicar l'algorisme sobre una entrada. Començant amb l'estat inicial E0 i per a l'entrada id * ( id + id ) l'anàlisi sintàctica és:

Page 82: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

78

Tipus de parser

Estudiarem tres tipus de parsers LR:

LR Simples (SLR) LR Canònics (LR) LR Lookahead (LALR)

Es diferencien entre ells per com es construeix la taula de parser, que pot ser, en ocasions, llarga i tediosa. És per aquest motiu que existeixen eines per a la construcció automatitzada de parsers ascendents. Els parsers LR normalment són més poderosos i menys restrictius que els parsers descendents LL.

RESUM Hem estudiat com funciona globalment un parser ascendent i els tipus de parser que podem construir. Hem après a analitzar sintàcticament una entrada.

Page 83: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

79

SESSIÓ 16: Parsers simples SLR

FITXA DE LA SESSIÓ Nom: Parsers simples SLR Tipus: teòrica Format: no presencial Durada: 2 hores Dedicació: 2 hores Treball a lliurar: no

PRECEDENTS En la sessió anterior hem donat una introducció als parsers ascendents i hem vist que la família més senzilla és la dels parsers simples (SLR).

OBJECTIUS Aprendre els conceptes bàsics i els algorismes necessaris per a la construcció d'una taula de parser SLR a partir d'una gramàtica incontextual.

CONTINGUTS En aquesta sessió estudiarem com es construeix una taula de parser SLR. Primer veurem algunes definicions i després donarem els passos a seguir.

4.4.2 Analitzadors (parsers) ascendents simples (SLR)

La construcció d'una taula de parser es fa seguint aquests passos: 1. Construir la gramàtica augmentada. 2. Construir la col·lecció de conjunts d'ítems LR(0). 3. Per cada estat i per cada entrada (token) omplir la taula ACTION. 4. Per cada estat i per cada no-terminal omplir la taula GOTO.

Gramàtica Augmentada

Si G és una gramàtica amb símbol axioma S llavors G', anomenada la gramàtica augmentada, és G amb una nova producció S' S on S' és el símbol axioma de la nova gramàtica G' . L'objectiu d'augmentar una gramàtica és assegurar que només tingui una producció en què aparegui el símbol axioma a l'esquerra.

Page 84: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

80

Ítem LR(0)

Després d'augmentar la gramàtica, el pròxim pas és construir la col·lecció de conjunts d'ítems LR(0). Cada conjunt d'ítems representarà un estat del parser. Abans de construir els estats hem d'estudiar el concepte d'ítem LR(0). Un ítem LR(0) d'una gramàtica G és una producció de G amb un punt en alguna posició de la part dreta. Els ítems es construeixen mitjançant una operació que s'anomena “closure” sobre uns altres ítems. Inicialment es comença amb l'ítem: [S ● α] on S és el símbol axioma. Fixeu-vos que hi ha un punt (●) al començament de la part dreta. A partir d'una producció de la forma A --> X1 X2 .... Xk, potencialment, es poden generar els ítems: A ●X1 X2 .... Xk A X1 ●X2 .... Xk A X1 X2 ● .... Xk ..... A X1 X2.... Xk● Per exemple, l'ítem A X●YZ representa que hem reconegut una cadena (string) derivable de X (és a dir, X és un prefix viable) i esperem reconèixer una cadena derivable de YZ. És a dir, que hem construït el subarbre de parser per X. Les produccions de la forma A ε només poden generar l'ítem: A ●

Col·lecció de conjunts d'ítems

Com hem pogut veure en la taula de parser donada anteriorment, les files són estats. Cada estat representa en quin punt del parser estem, és a dir, que hem reconegut fins aquest moment. Per la construcció de la taula hem, per tant, de determinar quants i quins estats tenim. Cada estat és un conjunt d'ítems. El conjunt de tots els estats és una col·lecció de conjunts d'ítems. La col·lecció de conjunts d'ítems representarà un autòmat finit deterministe que reconeixerà prefixos viables. Per construir la col·lecció necessitem les operacions: CLOSURE (clausura) i goto (anar). L'operació CLOSURE calcularà quins ítems formen part d'un estat. L'operació goto calcularà a quants estats podem anar a partir dels ítems d'un estat. La col·lecció de conjunts d'ítems la representarem com I = {Io, I1, ....In} en què cada Ii és un estat.

Page 85: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

81

Operació CLOSURE

La construcció d'un estat es fa mitjançant l'operació CLOSURE(I), on I és un conjunt d'ítems. Per aplicar aquesta operació hem de tenir almenys un ítem, que anomenarem llavor. La clausura d'aquest ítem genera uns altres ítems que es tornen a clausurar i així successivament fins que l'estat se satura. És a dir, fins que no es poden afegir nous ítems. El primer estat que es construeix és l'estat inicial 0 agafant com llavor l'ítem [S' --> . S] corresponent a la producció del símbol axioma. Com que la gramàtica està augmentada aquesta producció és única. La construcció dels altres estats es fa en ordre. Les llavors de cada estat són donades per l'operació goto. L'estat inicial té una sola llavor però tots els altres poden tenir-ne més d'una. Algorisme per a calcular la clausura d'un conjunt d'ítems I Funció CLOSURE(I); Inici J = I: Repetir Per cada ítem [A α●Bβ] en J i per cada producció de la gramàtica de la forma B γ tal que l'ítem [B ●γ] no hi és en J fer

afegir l'ítem [B ●γ] a J fins que no es puguin afegir més ítems a J; retornar(J) Fi Exemple1: Sigui la gramàtica: E' --> E E --> E + T E --> T T --> T * F T --> F F --> ( E ) F --> id la CLOSURE( { [E' --> . E] }) és el conjunt d'ítems següents: [E' --> . E] [E --> . E + T] [E --> . T] [T --> . T * F] [T --> . F] [F --> . ( E )] [F --> . id]

Page 86: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

82

Exemple2: Sigui la gramàtica: S' --> S S --> ( L ) S --> x L --> S L --> L , S la CLOSURE( { [S' --> . S] }) és el conjunt d'ítems següents: [S' --> . S] [S --> . ( L )] [S --> . x]

Operació goto

Les transicions entre estats es fan mitjançant l'operació goto(I,X), on I és un conjunt d'ítems (representant un estat) i X és un símbol de la gramàtica (terminal o no-terminal). goto(I,X) és la clausura del conjunt d'ítems de la forma [A αX●β] tal que [A α●Xβ] està en I. Intuitivament, si I és l'estat vàlid per a un prefix viable γ, llavors goto(I,X) és l'estat vàlid per al prefix viable γX. Algorisme per a calcular el goto d'un conjunt d'ítems I i un símbol de la gramàtica Funció goto(I,X); Inici J = conjunt buit ; Per cada ítem [A α●Xβ] en I fer J = J U { [A αX●β] } retornar(CLOSURE(J)) Fi Fixeu-vos que el goto calcula primer les llavors del nou conjunt i després clausura aquest conjunt. Exemple1: Sigui la gramàtica: E' --> E E --> E + T E --> T T --> T * F T --> F F --> ( E ) F --> id

Page 87: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

83

Sigui Io : [E' --> . E] [E --> . E + T] [E --> . T] [T --> . T * F] [T --> . F] [F --> . ( E )] [F --> . id] El goto( Io,E) és el conjunt d'ítems següents: [E' --> E .] [E --> E . + T] en aquest cas els dos ítems són les llavors però la clausura d'aquest ítems no dóna res més. El goto( Io,() és el conjunt d'ítems següents: [F --> ( . E )] [E --> . E + T] [E --> . T] [T --> . T * F] [T --> . F] [F --> . ( E )] [F --> . id] en aquest cas el primer ítem és la llavor i els altres ítems han sigut produïts per a la clausura d'aquesta llavors. Podeu trobar aquest exemple resolt en el problemari.

Construcció de la col·lecció de conjunts d'ítems

Començant amb l'ítem [S' --> . S] i aplicant sobre ell l'operació CLOSURE trobarem el primer estat (de fet aquest serà l'estat inicial). A partir d'aquest estat i amb l'operació goto anirem trobant la resta dels estats. La col·lecció d'ítems LR(0) s'anomena també col·lecció canònica LR(0). A partir de la col·lecció de conjunts d'ítems LR(0) podrem construir la taula de parser més endavant. Entrada: Una gramàtica G' augmentada. Sortida: C = {Io,I1,....In}, col·lecció de conjunts d'ítems LR(0). És a dir, col·lecció d'estats. Procés: C = {CLOSURE([S' --> .S])} /* C = {Io}

Page 88: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

84

Repetir Per a cada conjunt d'ítems I en C i per a cada símbol X de G' tal que goto(I,X) no sigui buit fer C = C U goto(I,X) fins que no es puguin afegir nous conjunts d'ítems a C. Exemple1: La gramàtica: E' --> E E --> E + T E --> T T --> T * F T --> F F --> ( E ) F --> id té 12 estats, és a dir, la col·lecció d'ítems LR(0) és {Io,I1, ...I11}. Consulteu el problema resolt en el problemari.

Construcció d'una taula de parser SLR

A partir dels conceptes estudiats podem donar l'algorisme que ens permetrà construir la taula de parser per una gramàtica. Algorisme: Entrada: Una gramàtica G' augmentada Sortida: La taula de parser (ACTION i GOTO) SLR per la gramàtica G'. Procés: 1.Construir la col·lecció de conjunts d'ítems LR(0) C mitjançant el corresponent algorisme. C = {Io, I1, ... In}, cada Ii és un estat de la taula. Io es construeix a partir de l'ítem [S' ●S] 2. Construcció de la part de la taula ACTION Per cada conjunt Ii (estat i) fer Per cada ítem m en l'estat i fer Si m és de la forma [A α●aβ] , a és un terminal i goto(Ii,a)=Ij llavors ACTION[i,a] = shift j (Sj) si no

Si m és de la forma [A α●] i A no és el símbol axioma llavors ACTION[i,b] = reduce k (Rk) per a tots els b pertanyen als FOLLOWS(A), k és el número de la producció A α

si no

Page 89: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

85

Si m és [S' S●], S' és el símbol axioma llavors ACTION[i,$] = ACC

Fiper Fiper 3. Construcció de la part de la taula GOTO Per a cada estat i de la taula fer Per a cada no-terminal A de la gramàtica fer Si goto(Ii,A) = Ij llavors GOTO(i,A) = j Fiper Fiper 4. Les entrades no definides són errorades sintàctiques i haurem d'escriure rutines de recuperació d'errors. Si en construir la taula hi ha conflictes, és a dir, alguna entrada de la taula ACTION no està definida de forma única direm que la gramàtica no és SLR. Una gramàtica per a la qual es pot construir una taula sense conflictes és anomenada SLR.

RESUM Hem après com es construeix una taula de parser SLR a partir d'una gramàtica incontextual i per tant com caracteritzar una gramàtica depenent del parser que es pot construir.

Page 90: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

86

Page 91: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

87

SESSIÓ 17: Parsers canònics LR

FITXA DE LA SESSIÓ Nom: Parsers canònics LR Tipus: teòrica Format: no presencial Durada: 2 hores Dedicació: 2 hores Treball a lliurar: no

PRECEDENTS Després d'haver estudiat en la sessió anterior els parsers simples LR (SLR) abordarem la següent família d'analitzadors sintàctics ascendents: els LR canònics (LR).

OBJECTIUS Aprendre els conceptes bàsics i els algorismes necessaris per a la construcció d'una taula de parser LR a partir d'una gramàtica incontextual. En aquest cas la família de gramàtiques per a les quals podem construir un parser LR és més gran que la família de gramàtiques SLR. De fet aquesta última està inclosa en la primera.

CONTINGUTS En aquesta sessió estudiarem com es construeix una Taula de Parser LR. Primer veurem algunes definicions i després donarem els passos a seguir. La construcció es fa de forma molt similar a la construcció dels parsers SLR.

4.4.3 Analitzadors ascendents canònics LR (LR) Si observem el problema 4.16 del problemari en l'estat 2 trobem un conflicte shift-reduce, per tant la gramàtica de l'exercici no és SLR. El conflicte shift-reduce vol dir que estant en l'estat 2 i llegint de l'entrada un =, el parser no sap si ha d'empilar el caràcter = (shift) o reduir (reduce) la pila per la producció corresponent. Si féssim el reduce ens trobaríem amb un string en la pila que no seria cap forma sentencial per a la gramàtica. Això vol dir que els FOLLOW's no donen informació suficient. L'objectiu del parsers LR és tenir més informació en els estats de manera que no siguin els FOLLOW's sinó aquesta informació la que s'utilitzarà per a fer els reduce. La construcció d'una taula de parser es fa seguint aquests passos: 1. Construir la gramàtica augmentada. 2. Construir la col·lecció de conjunts d'ítems LR(1). 3. Per cada estat i per cada entrada (token) omplir la taula ACTION. 4. Per cada estat i per cada no-terminal omplir la taula GOTO.

Page 92: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

88

Com podeu observar els passos són els mateixos que en el cas del parsers SLR. El canvi substancial és que els estats són més complexos ja que contenen ítems LR(1), amb més informació, en lloc d'ítems LR(0). Per tant, els algorismes canvien adaptant-se als nous ítems.

Revisió del concepte de Gramàtica Augmentada

Si G és una gramàtica amb símbol axioma S llavors G', anomenada la gramàtica augmentada, és G amb una nova producció S' S on S' és el símbol axioma de la nova gramàtica G'. L'objectiu d'augmentar una gramàtica és assegurar que només tingui una producció en què aparegui el símbol axioma a l'esquerra.

Ítem LR(1)

Després d'augmentar la gramàtica, el pròxim pas és construir la col·lecció de conjunts d'ítems LR(1). Cada conjunt d'ítems representarà un estat del parser. Abans de construir els estats hem d'estudiar el concepte d'ítem LR(1). Els ítems LR(1) tenen la següent forma: [A α●β , a] on a pot ser un terminal de la gramàtica o el símbol $. La segona component de l'ítem (a) és el lookahead de l'ítem. Aquest es calcula en la clausura i serveix per tenir informació més precisa a l'hora de fer la taula de parser. Específicament, els reduce es faran només per a aquests símbols dels ítems corresponents i no per als FOLLOWS com en el cas dels parser SLR.

Revisió del concepte de col·lecció de conjunts d'ítems

La col·lecció de conjunts d'ítems representarà un autòmat finit determinista que reconeixerà prefixos viables. Per construir la col·lecció necessitem les operacions: CLOSURE (clausura) i goto (anar). L'operació CLOSURE calcularà quins ítems formen part d'un estat. L'operació goto calcularà a quants estats podem anar a partir dels ítems d'un estat. La col·lecció de conjunts d'ítems la representarem com C = {Io, I1, ....In} on cada Ii és un estat.

Operació CLOSURE

La construcció d'un estat es fa mitjançant l'operació CLOSURE(I), on I és un conjunt d'ítems. Per aplicar aquesta operació hem de tenir almenys un ítem, al que anomenarem llavor. La clausura d'aquest ítem genera uns altres ítems que es tornen a clausurar i

Page 93: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

89

així successivament fins que l'estat se satura. És a dir, fins que nos'hi poden afegir nous ítems. El primer estat que es construeix és l'estat inicial 0 agafant com llavor l'ítem [S' --> . S, $] corresponent a la producció del símbol axioma. Com la gramàtica està augmentada aquesta producció és única. La construcció dels altres estats es fa en ordre. Les llavors de cada estat són donades per l'operació goto. L'estat inicial té una sola llavor però tots els altres poden tenir-ne més d'una. Si ens fixem bé en l'algorisme, el símbol de lookahead ara juga un paper important per trobar la clausura. Algorisme per calcular la clausura d'un conjunt d'ítems I LR(1): Funció CLOSURE(I); Inici J = I: Repetir

Per cada ítem [A α ● B β , a] en J, per cada producció de la gramàtica de la forma B γ i cada terminal b en FIRST(βa) tal que l'ítem [B ● γ, b] no hi és en J fer

afegir l'ítem [B ● γ , b ] a J fins que no es puguin afegir més ítems a J; Retornar(J) Fi Exemple1: Sigui la gramàtica: E' --> E E --> E + T E --> T T --> T * F T --> F F --> ( E ) F --> id la CLOSURE( { [E' --> . E , $] }) és el conjunt d'ítems LR(1) següents: [E' --> . E , $] [E --> . E + T , $] [E --> . T , $] [E --> . E + T , +] [E --> . T , +] [T --> . T * F , $] [T --> . F , $] [T --> . T * F , +] [T --> . F , +] [T --> . T * F , *] [T --> . F , *]

Page 94: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

90

[F --> . ( E ) , $] [F --> . id , $] [F --> . ( E ) , +] [F --> . id , +] [F --> . ( E ) , *] [F --> . id , *] Per tenir una notació més curta, podem escriure els ítems de la manera següent: [E' --> . E , $] [E --> . E + T , $ / +] [E --> . T , $ / + / *] [T --> . T * F , $ / + / *] [T --> . F , $ / + / *] [F --> . ( E ) , $ / + / *] [F --> . id , $ / + / *]

Operació goto

Les transicions entre estats es fan mitjançant l'operació goto(I,X), on I és un conjunt d'ítems (representant un estat) i X és un símbol de la gramàtica (terminal o no-terminal). goto(I,X) és la clausura del conjunt d'ítems de la forma [A α X ● β , a] tal que [A α ● X β , a] està en I. Intuitivament, si I és l'estat vàlid per a un prefix viable γ, llavors goto(I,X) és l'estat vàlid per al prefix viable γX. Aquest algorisme és pràcticament el mateix que en el cas del parser SLR ja que el símbol lookahead no és significatiu. Algorisme per calcular el goto d'un conjunt d'ítems I i un símbol de la gramàtica: Funció goto(I,X); Inici J = conjunt buit ; Per cada ítem [A α ● X β , a] en I fer J = J U {[A α X ● β , a] } Fiper Retornar(CLOSURE(J)) Fi Fixeu-vos que el goto calcula primer les llavors del nou conjunt i després clausura aquest conjunt. Els símbols lookahead s'arrosseguen.

Page 95: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

91

Exemple1: Sigui la gramàtica: E' --> E E --> E + T E --> T T --> T * F T --> F F --> ( E ) F --> id Sigui Io : [E' --> . E , $] [E --> . E + T , $ / +] [E --> . T , $ / +] [T --> . T * F , $ / + / *] [T --> . F , $ / + / *] [F --> . ( E ) , $ / + / *] [F --> . id , $ / + / *] El goto( Io,E) és el conjunt d'ítems següents: [E' --> E . , $] [E --> E . + T , $ / +] en aquest cas els dos ítems són les llavors però la clausura d'aquests ítems no dóna res més. El goto( Io,() és el conjunt d'ítems següents: [F --> ( . E ) , $ / + / *] [E --> . E + T , ) / +] [E --> . T , ) / +] [T --> . T * F , ) / + / *] [T --> . F , ) / + / *] [F --> . ( E ) , ) / + / *] [F --> . id , ) / + / *] en aquest cas el primer ítem és la llavor i els altres ítems han sigut produïts per la clausura d'aquesta llavor.

Construcció de la col·lecció de conjunts d'ítems LR(1)

Començant amb l'ítem [S' ●S, $] i aplicant sobre ell l'operació CLOSURE trobarem el primer estat (de fet aquest serà l'estat inicial). A partir d'aquest estat i amb l'operació goto anirem trobant la resta dels estats. A partir de la col·lecció de conjunts d'ítems LR(1) podrem construir la taula de parser LR més endavant.

Page 96: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

92

Entrada: Una gramàtica G' augmentada. Sortida: C = {Io,I1,....In}, col·lecció de conjunts d'ítems LR(1). És a dir, col·lecció d'estats. Procés: C = {CLOSURE([S' ● S , $])} // C = {Io} Repetir Per cada conjunt d'ítems I en C i per cada símbol X de G' tal que goto(I,X) no sigui buit fer C = C U goto(I,X) fins que no es puguin afegir nous conjunts d'ítems a C. Exemple1: La gramàtica: S' --> S S --> L = R S --> R L --> * R L --> id R --> L té 14 estats, és a dir, la col·lecció d'ítems LR(1) és {Io,I1, ...I13}. Consulteu el problema resolt en el problemari.

Construcció d'una taula de parser LR canònic

A partir del conceptes estudiats podem donar l'algorisme que ens permetrà construir la taula de parser per a una gramàtica. Entrada: Una gramàtica G' augmentada Sortida: La taula de parser (ACTION i GOTO) LR per la gramàtica G'. Procés: 1.Construir la col·lecció de conjunts d'ítems LR(1) C mitjançant el corresponent algorisme. C = {Io, I1, ... In}, cada Ii és un estat de la taula. Io es construeix a partir de l'ítem [S' ● S , $]

Page 97: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

93

2. Construcció de la part de la taula ACTION Per cada conjunt Ii (estat i) fer Per ítem m en l'estat i fer Si m és de la forma [A α ● a β , b] , a és un terminal i goto(Ii,a)=Ij llavors ACTION[i,a] = shift j (Sj) si no Si m és de la forma [A α ● , b] i A no és el símbol axioma llavors ACTION[i,b] = reduce k (Rk) k és el número de la producció A α si no Si m és [S' S ● , $] , S' és el símbol axioma llavors ACTION[i,$] = ACC Fiper Fiper 3. Construcció de la part de la taula GOTO Per cada estat i de la taula fer Per cada no-terminal A de la gramàtica fer Si goto(Ii,A) = Ij llavors GOTO(i,A) = j Fiper Fiper 4. Les entrades no definides són errors sintàctics i haurem d'escriure-hi rutines de recuperació d'errors. Si en construir la taula hi ha conflictes, és a dir, alguna entrada de la taula ACTION no està definida de forma única direm que la gramàtica no és LR. Una gramàtica per a la qual es pot construir una taula sense conflictes és anomenada LR.

Relació entre gramàtiques SLR i gramàtiques LR

Tota gramàtica SLR(1) és una gramàtica LR(1) però si construïm un parser LR per una gramàtica SLR, aquest pot tenir més estats que el parser SLR.

RESUM Hem après com es construeix una taula de parser LR a partir d'una gramàtica incontextual i per tant caracteritzar una gramàtica depenent del parser que es pot construir.

Page 98: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

94

Page 99: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

95

SESSIÓ 18: Parsers LALR

FITXA DE LA SESSIÓ Nom: Parsers LALR Tipus: teòrica Format: no presencial Durada: 1 hora Treball a lliurar: no Material:

o Bibliografia bàsica: [Aho1985]

PRECEDENTS En les sessions anteriors hem estudiat els parsers simples (SLR) i els canònics (LR). L'única família que ens falta per estudiar és la dels parsers lookahead LR (LALR).

OBJECTIUS Aprendre els conceptes bàsics i els algorismes necessaris per a la construcció d'una taula de parser lookahead LR (LALR). Comparar les famílies de parsers estudiades.

CONTINGUTS En aquesta sessió estudiarem com es construeix una taula de parser LALR. Aquests parsers són els més utilitzats en la pràctica, sobretot perquè el nombre d'estats obtinguts és més petit que en el cas dels LR. A més, la majoria dels llenguatges de programació poden ser escrits amb una gramàtica LALR. La família de gramàtiques per a les quals podem construir un parser LALR és més gran que la família de gramàtiques SLR però més petita que la família de gramàtiques LR.

4.4.4 Analitzadors ascendents lookahead LALR (LALR)

L'objectiu bàsic d'un parser LALR és minimitzar el nombre d'estats d'un parser LR. Hi ha dos mètodes per construir aquesta família de parsers: 1. Construir primer el conjunt d'ítems LR(1) i fusionar els estats fusionables. 2. Construir només els kernels dels conjunts d'ítems LR(1) a partir dels quals es construeix la taula LALR.

Page 100: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

96

Algorisme de construcció d'una taula de parser LALR. Primer mètode

L'algorisme consisteix a construir primer la col·lecció de conjunts d'ítems LR(1) i després unir els estats que tenen el mateix core. El core d'un estat és el conjunt de les parts esquerres dels ítems. Si en fusionar els estats no hi ha conflictes aleshores es diu que la gramàtica és LALR. En cas d'haver-hi conflictes, aquests només poden ser del tipus reduce-reduce. Aquest mètode de construcció és el més fàcil però consumeix molt d'espai ja que hem de construir primer tots els ítems LR(1). Entrada: Una gramàtica augmentada G'. Sortida: La taula de parser (ACTION i GOTO) LALR per a la gramàtica G'. Procés: 1. Construir la col·lecció d'estats C = {Io,I1,...,In} LR(1) 2. Per cada “core” present en la col·lecció C, trobar tots els conjunts que tinguin el mateix “core” i reemplaçar aquests conjunts per un nou conjunt que sigui la unió. 3. Sigui C' = {Jo, J1, ...Jm} la nova col·lecció d'estats. La taula ACTION es construeix de la mateixa manera que en el cas LR(1). Si hi ha algun conflicte en la taula aleshores la gramàtica G' no és LALR(1). 4. La taula goto es construeix de la manera següent. Si J = I1 U I2...U Ik, és a dir, J és la unió d'estats LR(1), aleshores els “cores” de GOTO(I1,X) = GOTO(I2,X)=... = GOTO(Ik,X) són els mateixos. Sigui K la unió de tots els estats tenint el mateix “core” GOTO(I1,X). Llavors, goto(J,X) = K.

Un exemple

Sigui la gramàtica següent: S' --> S S --> C C C --> a C C --> d té 10 estats, és a dir, la col·lecció d'ítems LR(1) és {Io,I1, ...I9}. A partir d'aquesta col·lecció podem construir, per fusió d'estats amb els mateixos cores, 7 estats sense conflictes. Per tant la gramàtica és LALR(1). Consulteu el problema resolt en el problemari.

Page 101: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

97

Algorisme de construcció d'una taula de parser LALR. Segon mètode (opcional)

Els generadors de parsers ascendents que es troben normalment (YACC per exemple), construeixen taules LALR utilitzant aquest segon mètode ja que és més eficient. L'objectiu és construir només el que es necessita de cada estat (els kernels). Podeu consultar l'algorisme en la referència donada.

[Aho1985] p242 (Algorisme 4.13)

4.4.5 Comparació entre parsers ascendents Els parsers estudiats es poden comparar des de diversos punts de vista. A continuació en donem tres.

Nombre d'estats

Si una gramàtica és a la vegada SLR, LR i LALR, aleshores les taules SLR i LALR tindran el mateix nombre d'estats i la taula LR en tindrà més. Una gramàtica per un llenguatge de programació que tingui entre 50 i 100 terminals i 100 produccions, tindrà una taula de parser LALR de diversos centenars d'estats. En el cas de Pascal, la taula LALR té centenars d'estats en comparació amb la taula LR que tindria milers d'estats.

Entrades correctes i incorrectes

Si per una gramàtica hem construït parsers SLR, LR i LALR, l'anàlisi sintàctica d'una entrada correcta serà equivalent. En canvi, davant d'una entrada incorrecta (amb errors sintàctics), el parser LALR farà més reduce i per tant donarà l'error més tard.

Facilitat d'implementació

Els parsers SLR són més fàcils d'implementar. Els parsers LR són més poderosos però més cars d'implementar. Els parsers LALR s'implementen de manera eficient però amb esforç. La majoria de les gramàtiques per a llenguatges de programació són LALR.

Page 102: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

98

RESUM Hem après com es construeix una taula de parser LALR a partir d'una gramàtica incontextual i per tant a caracteritzar una gramàtica depenent del parser que es pot construir. Hem comentat alguns criteris de comparació.

Page 103: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

99

SESSIÓ 19: Ambigüitat en LR

FITXA DE LA SESSIÓ Nom: Ambigüitat en LR Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no

PRECEDENTS En les sessions precedents hem estudiat els diferents analitzadors sintàctics ascendents que podem construir a partir de gramàtiques incontextuals.

OBJECTIUS Caracteritzar una família de gramàtiques (les ambigües) per a les quals no podem construir directament cap parser ascendent però podrem resoldre els conflictes que apareixen.

CONTINGUTS Per les gramàtiques ambigües no es poden construir parsers ascendents sense conflictes. A continuació veurem la definició de gramàtica ambigua i explicarem com es poden resoldre els conflictes.

4.4.6 Ambigüitat en LR

Revisió del concepte de Gramàtica ambigua

Una gramàtica és ambigua si per a alguna entrada es poden construir dos arbres sintàctics diferents. Per demostrar que una gramàtica és ambigua s'han de construir, per a una entrada correcta, dos arbres sintàctics diferents.

Revisió de construccions ambigües

En sessions anteriors hem donat algunes construccions ambigües.

Page 104: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

100

Teorema

Cap gramàtica ambigua no pot ser SLR(k) ni LR(k) per a cap k.

Prioritat i Associativitat per a resoldre conflictes

Si una entrada té més d'un arbre sintàctic això vol dir que té més d'un significat. En compilació necessitem treballar amb gramàtiques que no siguin ambigües o amb gramàtiques ambigües però donant regles addicionals que resolguin l'ambigüitat. La raó, a la pràctica, d'utilitzar gramàtiques ambigües és que aquestes són més petites que si modifiquéssim la gramàtica per tornar-la no-ambigua. Moltes de les gramàtiques ambigües ho són perquè la precedència i l'associativitat dels operadors no estan especificades. Per exemple, considerem la gramàtica ambigua següent: E --> E + E E --> E * E E --> ( E ) E --> id Per a l'entrada id + id + id es poden construir dos arbres depenent de si es considera l'associativitat a esquerra o a dreta.

Per a l'entrada id + id * id es poden construir dos arbres depenent de si es considera que té més prioritat l'operador * o l'operador +.

Page 105: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

101

Si li construïm una taula de parser, hi haurà conflictes. Aquests conflictes es podran resoldre fixant unes regles d'associativitat i prioritat. Amb aquestes regles s'estudia en cada cas si el que convé és fer un shift o un reduce.

RESUM Hem après a identificar les gramàtiques ambigües i a demostrar que ho són. Hem estudiat com podem resoldre els conflictes que es presenten quan construïm taules de parser per a gramàtiques ambigües.

Page 106: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

102

Page 107: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

103

SESSIÓ 20: Recuperació d'errors

FITXA DE LA SESSIÓ Nom: Recuperació d'errors Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Aho1985]

PRECEDENTS En les sessions precedents hem estudiat els diferents analitzadors sintàctics ascendents que podem construir a partir de gramàtiques incontextuals.

OBJECTIUS Estudiar les diferents estratègies per recuperar els errors durant l'anàlisi sintàctica amb la finalitat de donar el màxim d'errors durant el procés i poder acabar de forma controlada.

CONTINGUTS

4.4.7 Recuperació d'errors en parsers ascendents Un error sintàctic es produeix quan es consulta la taula ACTION(estat, token) i aquest cas no està definit. El primer que cal fer és donar l'error i seguidament aplicar una estratègia per recuperar-lo. Podem aplicar, bàsicament, dues estratègies: 1. L'estratègia general, anomenada també, “mode pànic”. 2. L'estratègia específica.

Estratègia general (mode pànic)

Per introduir aquesta estratègia, imaginarem una situació durant l'anàlisi sintàctica. Suposem que la pila i l'entrada estan en un moment determinat de la manera següent: (pila) 0......E1X1E2X2 .... .EnXnEn+1 (entrada) a....$

Page 108: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

104

els Ei són estats i els Xi terminals o no-terminals de la gramàtica. També suposem que existeix una producció de la gramàtica (en realitat un ítem) de la forma:

B --> X1X2...Xn.Xn+1 ....Xm i que l'entrada ACTION(En+1,a) no està definida en la taula de parser. Els passos que es proposen per recuperar l'error són els següents: 1. Donar el missatge d'error corresponent, que seria del tipus: “s'esperava ...... i ha aparegut una a”. 2. Abandonar l'anàlisi de B. L'anàlisi de B s'abandona de la manera següent:

2.1 Desempilar els X1,...Xn amb els respectius estats de la pila. 2.2 Empilar el no-terminal B amb el seu respectiu estat. Aquest estat és l'indicat en l'entrada de la taula GOTO(E1,B), la pila queda: 0.....E1BXk

Fixeu-vos que és com si haguéssim reconegut B. 2.3 Consumir l'entrada fins que hi trobem un token pertanyent als FOLLOW's de B.

[Aho1985] p254-p255

Estratègia específica

L'objectiu d'aquesta estratègia és recuperar l'error en cada cas, aplicant una rutina específica per a cada entrada de la taula no definida. Cada rutina consisteix a modificar la pila (empilant o “desempilant”) i/o l'entrada (consumir) de forma que quedin sincronitzades i estables per poder continuar amb l'anàlisi sintàctica. La millor manera d'entendre aquesta tècnica és a través d'un exemple. Consulteu la taula de parser LR amb les rutines de recuperació d'errors donada a la referència. Com podeu observar, aquest parser és per a la gramàtica d'expressions: E --> E + E E --> E * E E --> ( E ) E --> id Tots els casos s'han resolt utilitzant quatre rutines d'errors. Estudieu-les per aprendre com actuen. Observeu que per a les entrades ACTION(7, id), ACTION(8, id), ACTION(9, id), ACTION(7, (), ACTION(8, (), ACTION(9, () en lloc d'aplicar una

Page 109: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

105

estratègia específica s'han posat reduce (el que convé per a cada cas). Amb aquests reduce es propaga l'error. Consulteu l'exercici 4.26 resolt.

RESUM Hem après a definir estratègies per recuperar els errors sintàctics en parsers ascendents.

Page 110: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

106

Page 111: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

107

SESSIÓ 21: Problemes (parsers ascendents SLR)

FITXA DE LA SESSIÓ Nom: Problemes (parsers ascendents SLR) Tipus: de problemes Format: no presencial Durada: 3 hores Treball a lliurar: no

OBJECTIUS Exercitar-nos en la resolució de problemes relacionats amb els parsers ascendents.

CONTINGUTS En aquesta sessió es proposen un conjunt de problemes per als parsers ascendents SLR.

4.4.8 Problemes (parsers SLR) A continuació es proposen un conjunt de problemes relatius els analitzadors sintàctics ascendents.

Taula de parser SLR

Construïu una Taula de Parser SLR per a la gramàtica següent: Bexp --> Bexp or Bterm Bexp --> Bterm Bterm --> Bterm and Bfactor Bfactor --> not Bfactor Bfactor --> ( Bexp ) Bfactor --> true Bfactor --> false Exercici 4.15a)

Anàlisi sintàctica d'una entrada

Analitzeu sintàcticament l'entrada not(true or false) utilitzant la taula de parser construïda en el problema anterior. Exercici 4.15b)

Page 112: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

108

Taula de parser SLR

Construïu una Taula de Parser SLR per a la gramàtica següent: S --> L = R S --> R L --> * R L --> id R --> L La taula construïda té conflictes, per tant la gramàtica no és SLR. En aquest cas la gramàtica no és ambigua. Exercici 4.16

Taula de parser SLR

Construïu una Taula de Parser SLR per a la gramàtica següent: E --> E + E E --> E * E E --> ( E ) E --> id La taula construïda té conflictes, per tant la gramàtica no és SLR. En aquest cas la gramàtica és ambigua. Exercici 4.17

Taula de parser SLR

Construïu una Taula de Parser SLR per a la gramàtica següent: S --> A A --> b B B --> c C B --> c C e C --> d A A --> a ¿La gramàtica és SLR? Justifiqueu vostra resposta. Exercici 4.18

Page 113: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

109

SESSIÓ 22: Problemes (parsers ascendents SLR)

FITXA DE LA SESSIÓ Nom: Problemes (parsers ascendents LR) Tipus: de problemes Format: no presencial Durada: 2 hores Treball a lliurar: no

OBJECTIUS Exercitar-nos en la resolució de problemes relacionats amb els parsers ascendents LR.

CONTINGUTS En aquesta sessió es proposen un conjunt de problemes per als parsers ascendents LR.

4.4.9 Problemes (parsers LR)

Taula de parser. Problema resolt

Construïu una taula de parser LR per a la següent gramàtica: S' --> S S --> C C C --> a C C --> d Exercici 4.19

Taula de parser. Problema resolt

Construïu una taula de parser LR per la gramàtica següent: S --> L = R S --> R L --> * R L --> id R --> L

Page 114: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

110

Si us en recordeu, aquesta gramàtica no és SLR(1) però és LR(1) llavors li podem construir una taula de parser LR sense conflictes. Exercici 4.20

Comparació de taules de parser SLR i LR

Compareu les taules de parser SLR i LR construïdes en les sessions anteriors, per a la gramàtica següent: S --> C C C --> a C C --> d Què es pot dir sobre el nombre d'estats? Exercici 4.21

Taula de parser

Construïu una taula de parser LR per a la gramàtica següent: E --> E + E E --> E * E E --> ( E ) E --> id La taula construïda té conflictes, per tant la gramàtica no és LR. En les pròximes sessions aprendrem a resoldre els conflictes que apareixen quan les gramàtiques són ambigües. Exercici 4.22

Page 115: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

111

SESSIÓ 23: Problemes

FITXA DE LA SESSIÓ Nom: Problemes Tipus: de problemes Format: no presencial Durada: 4 hores Treball a lliurar: no

OBJECTIUS Exercitar-nos en la resolució de problemes relacionats amb els parsers ascendents.

CONTINGUTS En aquesta sessió es proposen un conjunt de problemes per als parsers ascendents.

4.4.10 Problemes

Taula de parser. Problema resolt

Construïu una taula de parser LALR per a la següent gramàtica: S' --> S S --> C C C --> a C C --> d Per aquesta gramàtica ja havíem construït parsers SLR i LR. Si els comparem, veurem que les taules SLR i LALR tenen el mateix nombre d'estats i que aquest és més petit que el de la taula LR. Exercici 4.22

Taula de parser

Construïu una taula de parser LALR per a la següent gramàtica: S' --> S S --> L = R S --> R L --> * R L --> id R --> L

Page 116: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

112

Per aquesta gramàtica ja havíem construït el parser LR. Exercici 4.23

És LR(1) però no és LALR(1)

Demostreu que la següent gramàtica: S --> A a S --> b A c S --> B c S --> b B a A --> d B --> d és LR(1) però no LALR(1). Exercici 4.24

Anàlisi sintàctica d'una entrada

Feu els problemes 4.25a i 4.25b del problemari.

Taula de parser amb conflictes. Problema resolt

Construïu un parser SLR per a la gramàtica i resoleu els conflictes considerant associativitat a esquerra i que l'operador * té més prioritat que l'operador +. E --> E + E E --> E * E E --> ( E ) E --> id Podeu trobar la solució en l'exercici 4.26.

Taula de parser amb conflictes

Construïu un parser SLR per a la gramàtica i resoleu els conflictes. Escolliu les regles sobre associativitat i prioritat que vulgueu. R --> R + R R --> R R R --> R * R --> ( R ) R --> a R --> b

Page 117: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

113

Exercici 4.27

Anàlisi sintàctica d'una entrada errònia

Utilitzant la taula de parser LR construïda en exercicis anteriors per a la gramàtica: S' --> S S --> C C C --> a C C --> d Analitzeu sintàcticament l'entrada incorrecta cddd, aplicant com estratègia de recuperació d'errors, la general. Exercici 4.28a)

Estratègies de recuperació d'errors

Doneu estratègies específiques de recuperació d'errors per a la taula de parser LR construïda en exercicis anteriors per a la gramàtica: S' --> S S --> C C C --> a C C --> d Analitzeu sintàcticament l'entrada incorrecta cddd, aplicant les estratègies definides. Exercici 4.28b,c)

Page 118: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

114

Page 119: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

115

SESSIÓ 24: Generadors de parsers

FITXA DE LA SESSIÓ Nom: Generadors de parsers Tipus: teòrica Format: no presencial Durada: 1 hora Treball a lliurar: no Material:

OBJECTIUS Donar algunes de les eines per la construcció de parsers.

CONTINGUTS

4.5 Eines

4.5.1 Eines Normalment les eines disponibles en el mercat són ambients integrats que permeten el desenvolupament d'un compilador complet. Podríem dividir les eines en dos grups, les que implementen analitzadors sintàctics ascendents i les que implementen analitzadors sintàctics descendents. Els primers generadors i molts dels actuals implementen parsers ascendents, com és el cas del YACC. Recordeu que les gramàtiques LR són més poderoses que les LL. Però, cada vegada més, trobem generadors de parsers descendents perquè aquests són més fàcils d'entendre. Entre els generadors de parsers descendents podem citar el PCCTS i més recentment el JavaCC.

RESUM Existeixen moltes eines que ajuden a la implementació ràpida d'un analitzador sintàctic. La més coneguda és el YACC. Una de les més recents és el JavaCC.

Page 120: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

116

Page 121: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

117

SESSIÓ 25: Definicions

FITXA DE LA SESSIÓ Nom: Definicions Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Aho1985]

OBJECTIUS Donar el concepte de gramàtica d'atributs, tipus d'atributs i com s'avaluen.

CONTINGUTS En aquesta sessió estudiarem les gramàtiques d'atributs, els tipus d'atributs i com s'avaluen.

5 Traducció dirigida per sintaxi

5.1 Gramàtiques d'atributs

5.1.1 Gramàtiques d'atributs En l'anàlisi semàntica necessitarem informació no local per fer verificacions entre d'altres coses. En principi necessitaríem una gramàtica sensitiva al context i un parser, però el problema és P-space complet. La manera de treballar amb gramàtiques incontextuals i poder fer verificacions semàntiques és utilitzant un dels formalismes següents: gramàtiques d'atributs o esquemes de traducció. Utilitzarem les gramàtiques d'atributs en la teoria i els esquemes de traducció a la pràctica.

Definició dirigida per sintaxi

Una definició dirigida per sintaxi (DDS) és una extensió del concepte de gramàtica incontextual. Una DDS és una gramàtica incontextual en què cada no-terminal de la gramàtica té un conjunt d'atributs associats. Un atribut pot contenir informació diversa. Cada atribut es pot calcular en funció d'altres atributs i gairebé sempre són expressions.

[Aho1985] p280

Page 122: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

118

Gramàtica d'atributs

Una gramàtica d'atributs és un cas particular de DDS ja que li demanem que les accions semàntiques no tinguin efectes col·laterals. Cada no-terminal de la gramàtica pot ser vist com un registre, així els atributs es poden veure com camps. És per això que la notació utilitzada per als atributs és la notació de punt com en el cas dels camps d'un registre.

[Aho1985] p281 (Exemple 5.1)

Atributs i tipus

Com hem vist en la definició d'una DDS, els atributs poden ser: sintetitzats o heretats. Des del punt de vista de l'arbre sintàctic, els atributs sintetitzats “pugen” i els heretats “baixen”.

Atributs sintetitzats

En una regla de la gramàtica, un atribut sintetitzat correspon a un camp del no-terminal de l'esquerra. Un atribut sintetitzat es calcula a partir d'altres atributs sintetitzats dels no-terminals que apareixen en la part dreta de la producció. El valor d'un atribut sintetitzat en un node de l'arbre es calcula a partir dels valors dels atributs dels nodes fills. Els atributs sintetitzats s'inicialitzen en les fulles, és a dir, en les regles de la gramàtica que no tenen cap no-terminal en la part dreta.

[Aho1985] p281-p282 (Exemple 5.2)

Atributs heretats

En una regla de la gramàtica, un atribut heretat correspon a un camp d'un no-terminal de la dreta. Un atribut heretat es calcula a partir d'altres atributs heretats del no-terminal de la part esquerra de la producció. El valor d'un atribut heretat en un node de l'arbre es calcula a partir dels valors dels atributs dels nodes germans esquerres i del node pare. Els atributs heretats s'inicialitzen en l'arrel de l'arbre, és a dir, en la regla de la gramàtica corresponent al símbol axioma.

[Aho1985] p283-p284 (Exemple 5.3, Figures 5.4 i 5.5)

Avaluació dels atributs

Quan en una gramàtica d'atributs s'utilitzen atributs sintetitzats i heretats, es creen interdependències a l'hora d'avaluar-los.

Page 123: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

119

Les dependències entre atributs poden ser representades amb un graf dirigit anomenat graf de dependències. A partir del graf podem extraure un ordre d'avaluació. Un arbre de parser amb els valors dels atributs en cada node és anomenat arbre decorat.

[Aho1985] p284-p287

RESUM Les gramàtiques d'atributs són un formalisme per escriure accions semàntiques. Podem tenir atributs sintetitzats i heretats. L'avaluació dels atributs es fa decorant un arbre de parser.

Page 124: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

120

Page 125: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

121

SESSIÓ 26: Problemes

FITXA DE LA SESSIÓ Nom: Problemes Tipus: de problemes Format: no presencial Durada: 3 hores Treball a lliurar: no

OBJECTIUS Proposar exercicis en què s'utilitzen les gramàtiques d'atributs i poder veure les diferents aplicacions.

CONTINGUTS En aquesta sessió donem un conjunt de problemes resolts i en proposem d'altres.

5.1.2 Problemes

Gramàtica amb atributs heretats . Problema resolt

Consulteu el següent l'exercici 5.1 del problemari.

Gramàtica amb atributs sintetitzats

Feu l' exercici 5.2 del problemari.

Gramàtica d'atributs. Problema resolt

Consulteu l'exercici 5.3 del problemari.

Gramàtica d'atributs. Problema resolt

Consulteu l'exercici 5.4 del problemari.

Gramàtica amb atributs heretats

Feu l' exercici 5.5 del problemari.

Page 126: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

122

Gramàtica d'atributs

Feu l' exercici 5.6 del problemari.

RESUM Hem proposat un conjunt de problemes per a utilitzar gramàtiques d'atributs en la seva resolució.

Page 127: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

123

SESSIÓ 27: Problemes

FITXA DE LA SESSIÓ Nom: Esquemes de traducció Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Aho1985]

OBJECTIUS Donar el concepte d'esquema de traducció i els principis que ha de complir per poder-lo avaluar amb l'ordre depth-FIRST.

CONTINGUTS En aquesta sessió introduïm els esquemes de traducció els quals ens seran de gran utilitat a l'hora d'implementar un analitzador semàntic.

5.2 Esquemes de traducció

5.2.1 Esquemes de traducció Els esquemes de traducció són un altre formalisme per poder inserir accions semàntiques en les gramàtiques incontextuals.

Avaluació depth-first

Quan les accions semàntiques i l'anàlisi sintàctica es fan alhora, l'ordre d'avaluació dels atributs està lligat a l'ordre de creació dels nodes de l'arbre de parser. L'ordre d'avaluació dels atributs està donat per un algorisme.

[Aho1985] p297 (Figura 5.18)

Definicions L-atribuïdes

Si imposem condicions sobre els atributs heretats, podem sempre utilitzar l'ordre depth-first per avaluar els atributs. Les condicions són que cada atribut heretat només pot dependre dels atributs heretats del seu pare o dels seus germans esquerres. Les gramàtiques d'atributs L-atribuïdes inclouen totes les DSS basades en gramàtiques LL.

[Aho1985] p297 (Definició “L-Attributed”)

Page 128: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

124

Esquemes de traducció

Els esquemes de traducció s'utilitzen molt a la pràctica. Un esquema de traducció és una gramàtica incontextual amb atributs però les accions semàntiques estan inserides dintre de les parts dretes de les produccions.

[Aho1985] p298 (Exemple 5.12)

Principis

Si l'esquema de traducció utilitza només atributs sintetitzats, l'acció per calcular qualsevol atribut sintetitzat pot ser posada a la dreta de la producció. Quan en un esquema de traducció s'utilitzen atributs heretats i sintetitzats, s'han de complir les següents condicions: 1. Un atribut heretat d'un no-terminal T ha de ser calculat per una acció que apareix abans de T. 2. Un atribut sintetitzat d'un no-terminal T de la part esquerra d'una regla, ha de ser calculat després d'haver calculat tots els atributs dels quals depèn. L'acció associada pot posar-se generalment al final de la part dreta de la regla. 3. Una acció no es pot referir a un atribut sintetitzat d'un no-terminal que estigui més a la dreta que ella en la regla. Aquestes condicions asseguren que les accions no es refereixin a atributs que no estiguin avaluats.

[Aho1985] p299-p301 (Exemple 5.13)

RESUM Els esquemes de traducció són definicions L-atribuïdes. Els esquemes de traducció s'utilitzen molt a la pràctica. L'interès de tenir esquemes L-atribuïdes és per poder avaluar els atributs amb l'ordre depth-first.

Page 129: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

125

SESSIÓ 28: Problemes

FITXA DE LA SESSIÓ Nom: Problemes Tipus: de problemes Format: no presencial Durada: 3 hores Treball a lliurar: no

OBJECTIUS Proposar exercicis per aplicar els esquemes de traducció.

CONTINGUTS En aquesta sessió donem un conjunt de problemes resolts i en proposem d'altres.

5.2.2 Problemes

Esquema de traducció. Problema resolt

Consulteu el problema resolt 5.7 del problemari.

Esquema de traducció

Feu els problemes del 5.8 al 5.12 del problemari.

RESUM Hem proposat un conjunt de problemes per exercitar-nos en el disseny d'esquemes de traducció.

Page 130: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

126

Page 131: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

127

Problemes i Solucions

Rev. 2.1: Oct. 2009

Enunciats dels problemes

CAPÍTOL 1 LLENGUATGES DE PROGRAMACIÓ

PRO 1.1 Definició formal de llenguatges

Busqueu la definició d'un llenguatge de programació imperatiu. Estudieu com està definida la seva sintaxi i la seva semàntica.

CAPÍTOL 2 EL PROCÈS DE LA COMPILACIÓ No hi han exercicis per a aquest capítol.

CAPÍTOL 3 ANÀLISI LEXICOGRÀFICA

PRO 3.1 Anàlisi lexicogràfica

Busqueu en un llenguatge de programació conegut els aspectes regulars.

PRO 3.2 Eina JavaCC

Estudieu com es pot implementar un analitzador lexicogràfic amb l'eina JavaCC. Estudieu en detall la sintaxi de les expressions regulars. Feu una prova, implementant diferents tokens.

PRO 3.3 Aplicacions

Doneu dues aplicacions que puguin ser implementades utilitzant les tècniques de construcció d'analitzadors lexicogràfics.

Page 132: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

128

CAPÍTOL 4 ANÀLISI SINTÀCTICA

PRO 4.1 Recursivitat a esquerra i factorització

Transformeu la següent gramàtica eliminant la recursivitat a esquerra i factoritzant-la. A --> B A --> A ; B B --> C B --> [ A ] C --> D C --> C , D D --> x D --> ( c )

PRO 4.2 Recursivitat a esquerra i factorització

Transformeu la següent gramàtica eliminant la recursivitat a esquerra i factoritzant-la. a) S --> A S S --> b A --> SA A --> a b) S --> (L) S --> a L --> L,S L --> S c) Resolt S --> Aa S --> b A --> Ac A --> Sd A --> ε

PRO 4.3 Recursivitat a esquerra i factorització. Resolt

Transformeu la següent gramàtica eliminant la recursivitat a esquerra i factoritzant-la. E --> E + T E --> T T --> T * F T --> F F --> ( E ) F --> id

Page 133: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

129

PRO 4.4 Anàlisi sintàctica d'una entrada

Per a la següent gramàtica: S --> a S --> + S --> ( T ) T T , S T S Construïu l'arbre parser pas a pas, tal com ho faria un parser top-down per reconèixer l'entrada (((a,a),+(a)),a)

PRO 4.5 Analitzador sintàctic descendent recursiu

Per a la gramàtica: S --> c A d A --> a B B --> b B --> ε podem construir el següent analitzador sintàctic descendent recursiu: Proc S; Inici Si lookahead = c llavors Acceptar(“c”); A; Acceptar(“d”); si no escriure(“error”); Fi; Proc A; Inici Si lookahead = a llavors Acceptar(“a”); B; si no escriure(“error”); Fi; Proc B; Inici Si lookahead =”b” llavors Acceptar(“b”); Fi; Proc Acceptar(t: token); Inici Si lookahead =t llavors lookahead := pròxim_token si no escriure(“error”); Fi; Inici S; Si lookahead = <EOF> llavors escriure(“l'entrada ha estat acceptada”); si no escriure(“error”); Fi;

Page 134: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

130

Analitzeu sintàcticament l'entrada cabd amb el parser donat.

PRO 4.6 Parser Descendent recursiu

Escriviu un parser descendent recursiu per a la següent gramàtica: A --> B A --> A ; B B --> C B --> [ A ] C --> D C --> C , D D --> x D --> ( c ) Recordeu que aquesta gramàtica l'havíem transformat per eliminar-li la recursivitat a esquerra, en el problema 4.1.

PRO 4.7 Parser Descendent recursiu. Resolt

Escriviu un parser descendent recursiu per a la següent gramàtica: Type --> Simple Type --> ^ id Type --> array [ Simple ] of Type Simple --> integer Simple --> char Simple --> num dotdot num

PRO 4.8 Condicions LL (1)

Demostreu que la següent gramàtica no és LL(1): S --> c A d A --> a B B --> b B --> ε B --> d

PRO 4.9 Condicions LL (1)

Donada la següent gramàtica: S' --> S T S‘ --> a a T

Page 135: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

131

S' --> L T L --> L c L --> ε S --> a T --> b És LL(1)?. Si ho és, demostreu-ho, si no digueu per què.

PRO 4.10 Eina JavaCC

Implementeu un analitzador sintàctic amb l'eina JavaCC per a una gramàtica LL(1) simple.

PRO 4.11 Estratègies

Afegiu les estratègies de recuperació d'errors en el parser descendent recursiu donat en el problema 4.5 per a la gramàtica: S --> c A d A --> a B B --> b B --> ε

PRO 4.12 Estratègies

Afegiu les estratègies de recuperació d'errors en el parser descendent tabular següent: M id + * ( ) $

E 1 1

E’ 2 3 3 T 4 4

T’ 6 5 6 6 F 8 7

per a la gramàtica: (1) E --> TE' (2) E' --> +TE' (3) E' --> e (4) T --> FT' (5) T' --> *FT' (6) T' --> e (7) F --> ( E ) (8) F --> id

Page 136: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

132

PRO 4.13 Parser Descendent recursiu

Sigui la següent gramàtica: S 0S1 S A A A1 A ε Es pot construir un parser descendent recursiu determinista?.

PRO 4.14 Taula de parser SLR. Resolt

a) Construïu una taula de parser SLR per a la següent gramàtica: E --> E + T E --> T T --> T * F T --> F F --> (E) F --> id b) Reconeixeu l'entrada id*id+id utilitzant la taula de parser .

PRO 4.15 Taula de Parser SLR

a) Construïu una Taula de Parser SLR per a la gramàtica següent: Bexp --> Bexp or Bterm Bexp --> Bterm Bterm --> Bterm and Bfactor Bterm --> Bfactor Bfactor --> not Bfactor Bfactor --> ( Bexp ) Bfactor --> true Bfactor --> false b) Analitzeu sintàcticament l'entrada not(true or false) utilitzant la taula de parser construïda en el problema anterior.

PRO 4.16 Taula de Parser SLR . Resolt

Construïu una Taula de Parser SLR per a la gramàtica següent: S --> L = R S --> R L --> * R L --> id R --> L

Page 137: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

133

PRO 4.17 Taula de Parser SLR

Construïu una Taula de Parser SLR per a la gramàtica següent: E --> E + E E --> E * E E --> ( E ) E --> id La taula construïda té conflictes, per tant la gramàtica no és SLR. En aquest cas la gramàtica és ambigua.

PRO 4.18 Taula de Parser SLR

Construïu una Taula de Parser SLR per a la gramàtica següent: S --> A A --> b B B --> c C B --> c C e C --> d A A --> a La gramàtica és SLR? Justifiqueu la vostra resposta.

PRO 4.19 Taula de Parser LR. Resolt

Construïu una taula de parser LR per a la següent gramàtica: S' --> S S --> C C C --> c C C --> d i analitzeu sintàcticament la frase: aaaadaaad

PRO 4.20 Taula de Parser LR. Resolt

Construïu una taula de parser LR per a la gramàtica següent: S --> L = R S --> R L --> * R L --> id R --> L Si ho recordeu, aquesta gramàtica no és SLR(1) però és LR(1) així és que li podem construir una taula de parser LR sense conflictes.

Page 138: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

134

PRO 4.21 Comparació de mida de taules

Compareu les taules de parser SLR i LR construïdes en les sessions anteriors, per a la gramàtica següent: S --> C C C --> a C C --> d Què es pot dir sobre el nombre d'estats?

PRO 4.22 Taula de Parser LR

Construïu una taula de parser LR per a la gramàtica següent: E --> E + E E --> E * E E --> ( E ) E --> id La taula construïda té conflictes, per tant la gramàtica no és LR. En les pròximes sessions aprendrem a resoldre els conflictes que apareixen quan les gramàtiques són ambigües.

PRO 4.23 Taula de Parser LALR

Construïu una taula de parser LALR per a la següent gramàtica: S' --> S S --> L = R S --> R L --> * R L --> id R --> L Per aquesta gramàtica ja havíem construït el parser LR.

PRO 4.24 Taula de Parser LR

Demostreu que la següent gramàtica: S --> A a S --> b A c S --> B c S --> b B a A --> d B --> d és LR(1) però no LALR(1).

Page 139: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

135

PRO 4.25 Anàlisi Sintàctica

Per a la gramàtica: S' --> S S --> C C C --> a C C --> d a) Construïu el parser LALR donada la gramàtica.(La taula LR està construïda en el problema 4.19) b) Analitzeu sintàcticament l'entrada correcta aaadaad utilitzant les taules de parser LR (construïda en el problema 4.19) i LALR (construïda en l'apartat a d'aquest problema) . Compareu el nombre de passos. c) Analitzeu sintàcticament l'entrada incorrecta aad utilitzant les taules de parser LR (construïda en el problema 4.19) i LALR (construïda en l'apartat a d'aquest problema). Compareu el nombre de passos.

PRO 4.26 Parser SLR. Resolt

Construïu un parser SLR per a la gramàtica i resoleu els conflictes considerant associativitat a esquerra i que l'operador * té més prioritat que l'operador +. E --> E + E E --> E * E E --> ( E ) E --> id

PRO 4.27 Parser SLR

Construïu un parser SLR per a la gramàtica i resoleu els conflictes. Escolliu les regles sobre associativitat i prioritat que vulgueu. R --> R + R R --> R R R --> R * R --> ( R ) R --> a R --> b

PRO 4.28 Taula de Parser LR

Utilitzant la taula de parser LR construïda en el problema 4.19 per a la gramàtica: S' --> S S --> C C C --> a C C --> d

Page 140: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

136

a) Analitzeu sintàcticament l'entrada incorrecta addd, aplicant com estratègia de recuperació d'errors, la general. b) Doneu estratègies específiques de recuperació d'errors. c) Analitzeu sintàcticament l'entrada incorrecta addd, aplicant les estratègies definides.

PRO 4.29 Taula de Parser LL

Sigui la següent gramàtica: E - E E (E) E VE' E' - E E' ε V id V' V' (E) V' ε

a) Construïu la taula de parser LL(1). b) Analitzeu sintàcticament la frase –id(-id)-id utilitzant la taula de parser

generada en l'apartat a). Justifiqueu totes les vostres respostes.

PRO 4.30 Parsers ascendents

L'empresa COMPIS S. L. l'ha contractat perquè, a partir d'una gramàtica G donada, construeixi un “parser” ascendent. La seva primera idea és construir un “parser” LR(1) i efectivament funciona.

a) Què es pot dir de la gramàtica G? Sigui el més exhaustiu possible.

b) Un cop l'empresa prova el “parser” decideix que va massa lent i li demana que revisi la seva idea original per millorar l'eficiència.

b.1) Expliqueu les diferents possibilitats (solucions) que, a la vostra manera de veure, poden millorar l'eficiència b.2) Escolliu una solució millor (si existeix) i justifiqueu-la.

Page 141: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

137

PRO 4.31 Parser LR i LALR

Sigui la següent gramàtica: P { D Q S } D int id ; D D ε Q int id ( ) { S } Q Q ε S id ( ); S S ε El terminals estan en negreta.

a) Aquesta gramàtica no és LALR (1). Mostreu clarament per què no és LALR (1).

b) És LR(1)? Si ho és, demostreu-ho donant la seva taula de parser; si no ho és mostreu els conflictes i resoleu-los.

PRO 4.32 LR, LALR

Sigui la següent gramàtica : S A B ε C ε A BCA A a

a) Calculeu el conjunt d'ítems LR (1). b) Si es pot, construïu una taula LR. c) Proveu de construir un parser LALR (1). La gramàtica és LALR(1)?

PRO 4.33 Shift-reduce, LL

Considereu la següent gramàtica: S a S * S ( T ) T T , S T S

a) Sigui la frase ( ( ( a , a ) , * , ( a ) ) , a ) Doneu els passos que faria un parser shift-reduce per reconèixer aquesta frase.

b) Elimineu recursivitat a l'esquerra i factoritzeu la gramàtica. És LL(!)? Si ho és,

construïu la taula de parser predictiu.

Page 142: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

138

PRO 4.34 Anàlisi lexicogràfica i anàlisi sintàctica

En Common Lisp existeix una instrucció de tipus condicional amb la següent estructura: (cond (condició1 expressió*) (condició2 expressió*) (condició3 expressió*) ........ (condición expressió*) Aquesta instrucció funciona de la següent manera: executa l'expressió que representa condició1. Si torna veritable, executa una a una les expressions que apareixen a continuació de condició1 (fins al parèntesi de tancament), el cond acaba la seva execució i torna el que torni l'última. Si no hi haguessin expressions desprès de condició1, el cond tornaria el que torni la condició1. Si condició1 torna fals, el cond executa l'expressió que representa la condició2. Si torna veritable, executa una a una les expressions que poden aparèixer a continuació de condició2, el cond acaba la seva execució i torna l'última. Si no hi haguessin expressions després de condició2, el cond tornaria el que tornaria la condició2. Si condició2 torna fals, executa aquests mateixos passos (si cap condició no torna veritable) fins l'última condició: condición. Si cap condició ha tornat veritable, el cond torna NIL. A continuació donem una possible gramàtica G per a aquesta instrucció: C ( cond R ) E (or O ) R ( E V ) R E ( and A ) R ( E ) R E (not E ) R ( E V) E (setf id E) R ( E ) E ( =I ) V E V E (+M ) V E E ( - S ) O E O E id O ε E num A E A M E M A ε M ε I E I' S E S' I' I S' S I' ε S' ε Un exemple: (cond ( exito ( setf result T)) ( ( and ( =p pmax) estable ) ( setf result ( + vp 10 (- vc 5 ))) ) ( ( = p pmax ) (setf repetir T) (setf result NIL) ) ( T (seft repetir T ) ) ) nota: T i NIL són considerats identificadors però a diferència d'altres identificadors T té com valor T (que per ser diferent de NIL, és veritable) i l'identificador NIL té com valor NIL (que és fals).

Page 143: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

139

a) Definiu els tokens necessaris per a l'anàlisi lexicogràfica. Definiu-los tal com ho haguéssiu fet en JavaCC (és a dir, amb termes d'expressions regulars i amb un ordre específic). Ha de ser fidel a la gramàtica donada.

b) Analitzeu lexicogràficament l'exemple donat especificant la llista de tokens i els

seus lexemes. Analitzeu només fins al símbol estable incloent-lo.

c) La gramàtica G donada no és LL (1). Demostreu per què no ho és i modifiqueu-la construint una G' per poder fer una anàlisi sintàctica descendent LL (1).

d) Calculeu els FIRST's i els FOLLOW ‘s (en forma de taula) de cada no-terminal.

e) Construïu la taula LL(1).

f) Què passa amb l'anàlisi sintàctica si el símbol p té com a valor NIL?

g) Haguéssiu pogut construir un parser LR per a la gramàtica G'? I per G?.

Justifiqueu la vostra resposta sense construir la taula d'un parser LR?

PRO 4.35 Parser Tabular Predictiu. Resolt

Construïu una taula de parser LL(1) per a la gramàtica següent: E --> TE' E' --> +TE' E' --> ε T --> FT' T' --> *FT' T' --> ε F --> ( E ) F --> id i mostreu la pila donada l'entrada id + id * id.

PRO 4.36 Parser Tabular Predictiu. Resolt

Construïu una taula de parser LL(1) per a la gramàtica següent: E --> I ( E ) E --> I [ E ] E --> I I --> a I --> f I --> z

Page 144: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

140

PRO 4.37 Taula de Parser SLR

Construïu la Taula de Parser SLR per a la següent gramàtica: S' --> S S --> ( L ) S --> x L --> S L --> L , S

PRO 4.38 Taula de Parser SLR

Demostreu que la gramàtica següent no és SLR: S --> E E --> bEa E --> aEb E --> ba

PRO 4.39 Taula de Parser SLR. Resolt

Donades les següents gramàtiques: a)

S --> AB A --> 0 A 1 A --> ε B --> 1 B B --> 1

b)

S' --> S S --> 0 S 1 S --> A A --> 1 A A --> 1

c)

S' --> S S --> S + A S --> A A --> (S) A --> a (S) S --> a

Indiqueu quines són SLR(1) justificant la vostra resposta.

Page 145: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

141

CAPITOL 5 GRAMÀTIQUES D'ATRIBUTS

PRO 5.1 Atributs heretats. Resolt

La següent gramàtica defineix una llista d'identificadors, volem comptar el nombre d'identificadors. Escriviu una gramàtica d'atributs per fer-ho. Avalueu els atributs decorant l'arbre de parser per a l'entrada: id1, id2, id3. S --> L L --> id , L L --> id Solució S --> L , L.count:= 1 L --> id , L' , L'.count:= L.count + 1 L --> id , print (L.count) L'atribut count és heretat, de tipus sencer i funciona com un comptador.

PRO 5.2 Atributs sintetitzats

L'esquema de traducció de l'exercici anterior utilitza un atribut heretat. Doneu un esquema de traducció que faci el mateix però utilitzant un atribut sintetitzat. Indiqueu els principis aplicats.

Page 146: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

142

PRO 5.3 Tipus d'atributs

La següent gramàtica d'atributs avalua números binaris amb signe, és a dir, transforma el número binari de l'entrada en un número decimal. N --> S L , L.pos:= 0 N.val := si S.neg llavors – L.val sinó L.val S --> +, S.neg:= fals S --> -, S.neg:= cert L --> B, B.pos := L.pos L.val:=B.val L --> L' B, L'.pos := L.pos + 1 B.pos := L.pos L.val:= L'.val + B.val B --> 0, B.val := 0 B --> 1, B.val:= 2^B.pos Observeu que quan necessitem referir-nos a un no-terminal i aquest figura diverses vegades utilitzem el símbol '. També es poden utilitzar subíndexs o superíndexs. Indiqueu els tipus dels atributs i per què s'utilitzen. Avalueu els atributs per a l'entrada: -1011.

PRO 5.4 Gramàtica d'atributs. Resolt

La següent gramàtica defineix seqüències de 0`s i 1's. Escriure una gramàtica d'atributs per traduir l'entrada transformant-la en l'invers. Avalueu els atributs decorant l'arbre de parser per a l'entrada: 001010 S --> 0 S S --> 1 S S --> ε Solució S --> 0 S', S.trad := S'.trad & “0” S --> 1 S', S.trad := S'.trad & “1” S --> ε, S.trad := “” L'atribut trad és sintetitzat i de tipus string . L'operador & és la concatenació.

Page 147: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

143

PRO 5.5 Gramàtica d'atributs

La gramàtica d'atributs de l'exercici anterior utilitza un atribut sintetitzat. Doneu una gramàtica d'atributs que faci el mateix però utilitzant un atribut heretat.

PRO 5.6 Gramàtica d'atributs

La següent gramàtica defineix expressions. Escriviu una gramàtica d'atributs per traduir l'entrada transformant-la en la seva derivada. Avalueu els atributs decorant l'arbre de parser per a l'entrada: sin(cos(x)) + x. E --> E + T E --> T T --> T * F T --> F F --> ( E ) F --> sin ( E ) F --> cos ( E ) F --> x F --> 0 F --> 1 Considereu que: La derivada d'una constant és 0

Page 148: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

144

La derivada de x és 1 La derivada de la suma, f + g = derivada de f + derivada de g La derivada del producte, f * g = (f * derivada de g) + (g * derivada de f) La derivada del cos, cos f = - sin f * derivada de f La derivada del sin, sin f = cos f * derivada de f

PRO 5.7 Esquema de traducció. Resolt

La següent gramàtica defineix una llista d'identificadors, volem comptar el nombre d'identificadors. Doneu un esquema de traducció que ho faci. Utilitzeu atributs heretats. Indiqueu quin principi estem aplicant. S --> L L --> id , L L --> id Solució S --> {L.count := 1} L L --> id , {L'.count := L.count + 1} L' L --> id {print(L.count)}

PRO 5.8 Esquema de traducció

L'esquema de traducció de l'exercici anterior utilitza un atribut heretat. Doneu un esquema de traducció que faci el mateix però utilitzant un atribut sintetitzat. Indiqueu els principis aplicats.

PRO 5.9 Esquema de traducció

La següent gramàtica d'atributs avalua números binaris amb signe, és a dir, transforma el número binari de l'entrada en un número decimal. Doneu un esquema de traducció que faci el mateix. N --> S L , L.pos:= 0 N.val := si S.neg llavors – L.val si no L.val S --> +, S.neg:= fals S --> -, S.neg:= cert L --> B, B.pos := L.pos L.val:=B.val L --> L' B, L'.pos := L.pos + 1 B.pos := L.pos L.val:= L'.val + B.val B --> 0, B.val := 0 B --> 1, B.val:= 2^B.pos

Page 149: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

145

PRO 5.10 Esquema de traducció

La següent gramàtica defineix arbres binaris amb números naturals en els nodes. Doneu un esquema de traducció per decidir si és un arbre binari de cerca (per tot subarbre els naturals en el subarbre de l'esquerra són menors que el natural de l'arrel i els nodes del subarbre de la dreta són majors) A --> A nat A A --> ;

PRO 5.11

La següent gramàtica defineix arbres binaris i els seus recorreguts (preordre i postordre). Introduïm un atribut L.ll de tipus llista que és sintetitzat i un atribut elem.elem del tipus sencer per al símbol terminal elem i que ens dóna el número. Feu un disseny d'atributs i rutines semàntiques per tal que L.ll contingui al final la llista associada al recorregut corresponent. L --> pre A L --> pos A A --> A A elem A --> ( A ) A --> ; La dificultat del problema rau en el fet que no podeu utilitzar construccions iteratives (bucles) dins les rutines semàntiques i que només podeu fer crides a les funcions: llistabuida: ---> llista afe_esq: elem x llista ---> llista afe_drt: elem x llista ---> llista i evidentment podeu fer assignacions entre atributs del mateix tipus. La funció llistabuida crea una llista buida, la funció afe_esq afegeix un element a l'esquerra de la llista i la funció afe_drt afegeix un element a la dreta de la llista.

PRO 5.12 Esquema de traducció

La següent gramàtica genera una certa classe de declaracions en el llenguatge PL/I. D --> ( L ) M L --> id , L L --> D , L L --> id L --> D M --> m1 M --> m2 . . M --> mk

Page 150: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

146

Les m1, m2,..mk són les possibles k característiques que podem assignar a un identificador. Per exemple, la declaració (id1,(id2,id3)m1)m2 assigna a id2 i id3 la característica m1 i a id1, id2 i id3 la característica m2. Doneu un esquema de traducció per traduir qualsevol entrada en k llistes on cada llista i tingui exactament els identificadors que tenen com característica mi. Utilitzeu les funcions sobre llistes que us calguin.

Algunes Solucions

PRO 4.2

c) S --> Aa S --> Aa S --> Aa S --> b S --> b S --> b A --> Ac A --> Ac A --> bdA' A --> Sd A --> Aad A --> A' A --> ε A --> bd A' --> cA' A --> ε A' --> adA' A' --> ε

PRO 4.3

E --> E + T E --> T E' E --> T E' E --> T E' --> + T E' E' --> + T E' T --> T * F E' --> � E' --> � T --> F T --> T * F T --> F T' F --> ( E ) T --> F T' --> * F T' F --> id F --> ( E ) T' --> � F --> id F --> ( E ) F --> id

PRO 4.7

Proc Type; Inici Select lookahead opc “^”: Acceptar(“^”); Acceptar(“id”); opc “array”: Acceptar(“array”); Acceptar(“[“); Simple; Acceptar(“]”); Acceptar(“of”); Type;

Page 151: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

147

opc “integer”, “char”, “num”: Simple; default: escriure(“error sintàctic”) fiselect; Fi; Proc Simple; Inici Select lookahead opc “integer”: Acceptar(“integer”); opc “char”: Acceptar(“char”); opc “num”: Acceptar(“num”); Acceptar(“dotdot”); Acceptar(“num”); default: escriure(“error sintàctic”) fiselect; Fi; Proc Acceptar(t: token); Inici Si lookahead =t llavors lookahead := pròxim_token si no escriure(“error sintàctic”); Fi; Inici Type; Si lookahead = <EOF> llavors escriure(“l'entrada ha estat acceptada”); Fi;

PRO 4.14

0 E' --> E 1 E --> E + T 2 E --> T 3 T --> T * F 4 T --> F 5 F --> (E) 6 F --> id La col·lecció d'ítems és la següent:

Page 152: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

148

0 5 E' .E

E 1 F id.

E .E + T T 2

E .T F 3

6

T .T * F ( 4

E E + .T T 9

T .F id 5

T .T * F F 3

F .( E ) T .F ( 4

F .id F .( E ) id 5

F .id 1 E' E.

+ 6 7

E E .+ T T T * .F F 10

F .( E ) ( 4

2 F .id id 5

E T. * 7

T T .* F 8 F ( E. )

) 11 3 E E. + T

+ 6 T F. 9 4 E E + T.

* 7

F (.E ) E 8 T T .* F

E .E + T T 2

E .T F 3

10

T .T * F ( 4

T T * F.

T .F id 5

F .( E ) 11 F .id F ( E) .

Page 153: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

149

i la taula: id + * ( ) $ E T F 0 S5 S4 1 2 3 1 S6 ACC 2 R2 S7 R2 R2 3 R4 R4 R4 R4 4 S5 S4 8 2 3 5 R6 R6 R6 R6 6 S5 S4 9 3 7 S5 S4 10 8 S6 S11 9 R1 S7 R1 R1 10 R3 R3 R3 R3 11 R5 R5 R5 R5 PILA ENTRADA 0 id * id + id $ 0 id 5 * id + id $ 0 F 3 * id + id $ 0 T 2 * id + id $ 0 T 2 * 7 id + id $ 0 T 2 * 7 id 5 + id $ 0 T 2 * 7 F 10 + id $ 0 T 2 + id $ 0 E 1 + id $ 0 E 1 + 6 id $ 0 E 1 + 6 id 5 $ 0 E 1 + 6 F 3 $ 0 E 1 + 6 T 9 $ 0 E 1 $

Page 154: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

150

PRO 4.16

La taula construïda té conflictes, per tant la gramàtica no és SLR. En aquest cas la gramàtica no és ambigua. 0 6 S' .S

S 1 S L = .R

R 9 S .L = R

L 2 R .L

L 8 S .R

R 3 L .*R

* 4 L .* R

* 4 L .id

id 5 L .id

id 5

R .L 7 L *R. 1 S' S. 8 R L. 2 S L . = R

= 6 9

R L.$ S L=R. 3 S R. 4 L *.R R 7 R . L L 8 L . *R * 4 L . id id 5 5 L id. * id = $ S L R 0 S4 S5 1 2 3 1 ACC 2 S6/R5 3 R2 4 S4 S5 8 7 5 R4 R4 6 S4 S5 8 9 7 R3 R3 8 R5 R5 9 R1

Page 155: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

151

PRO 4.19

0 S' S 1 S CC 2 C aC 3 C d 0 6

S' .S , $

S 1 C a.C , $

C 9

S .CC , $

C 2 C .aC , $

a 6

C .aC , a/d

a 3 C .d , $

d 7

C .d , a/d

d 4

7 1

C d. , $

S' S. , $

8

C aC. , a/d

2

S C.C , $

C 5 9

C .aC , $

a 6 C aC. , $

C .d , $

d 7

3

C a.C , a/d

C 8

C .aC , a/d

a 3

C .d , a/d

d 4

4

C d. , a/d

5

S CC. , $

Page 156: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

152

a D $ S C 0 S3 S4 1 2 1 ACC 2 S6 S7 5 3 S3 S4 8 4 R3 R3 5 R1 6 S6 S7 9 7 R3 8 R2 R2 9 R2 Observeu que els estats 3 i 6 s'assemblen, ja que difereixen en la segona component. Donada aquesta gramàtica podem construir un parser SLR. Si comparem els dos parsers, el LR té més estats. Analitzeu sintàcticament la frase: aaaadaaad 0 aaaadaaad$ 0a3 aaadaaad$ 0a3a3 aadaaad$ 0a3a3a3 adaaad$ 0a3a3a3a3 daaad$ 0a3a3a3a3d4 aaad$ 0a3a3a3a3C8 aaad$ 0a3a3a3C8 aaad$ 0a3a3C8 aaad$ 0a3C8 aaad$ 0C2 aaad$ 0C2a6 aad$ 0C2a6a6 ad$ 0C2a6a6a6 d$ 0C2a6a6a6d7 $ 0C2a6a6a6C9 $ 0C2a6a6C9 $ 0C2a6C9 $ 0C2C5 $ 0S1 $ …acc

Page 157: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

153

PRO 4.20

0 S' S 1 S L = R 2 S R 3 L * R 4 L id 5 R L En primer lloc construïm el conjunt d'ítems LR(1). 0 6 13 S' .S , $

S 1 S L=.R , $

R 9 L *R. , $

S .L=R , $ L 2

R .L , $ L 10

S .R , $ R 3

L .*R , $ * 11

L .*R , =/$ * 4

L .id , $ id 12

L .id , =/$ id 5

R .L , $ 7 L *R. , =/$ 1 S' S. , $ 8 R L. , =/$ 2 S L.=R , $

= 6 9

R L. , $ S L=R. , $ 3 10 S R. , $ R L. , $ 4 11 L *.R , =/$

R 7 L *.R , $

R 13

R .L , =/$ L 8

R .L , $ L 10

L .*R , =/$ * 4

L .*R , $ * 11

L .id , =/$ id 5

L .id , $ id 12

5 12 L id. , =/$ L id. , $

Page 158: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

154

A partir d'aquest conjunt construïm la següent taula de parser: = * id $ S L R 0 S4 S5 1 2 3 1 ACC 2 S6 R5 3 R2 4 S4 S5 8 7 5 R4 R4 6 S11 S12 10 9 7 R3 R3 8 R5 R5 9 R1 10 R5 11 S11 S12 10 13 12 R4 13 R3 La taula no té conflictes.

Page 159: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

155

PRO 4.26

0 E' E 1 E E+E 2 E E*E 3 E (E) 4 E id Conjunt d'ítems: 0 4 8 E' .E

E 1 E E + .E

E 7 E E * E.

+ 4 E .E+E

( 2 E .E + E

( 2 E E.+ E

* 5 E .E*E

id 3 E .E * E

id 3 E E.* E

E . (E)

E . (E)

E . id E . id 9 E (E). 1 5 E' E. E E * .E

E 8

E E.+ E + 4

E .E + E ( 2

E E.* E * 5

E .E * E id 3

E .(E)

2

E . id

E (.E) E 6

E .E + E ( 2

6

E .E * E id 3

E (E.) ) 9

E .(E) E E. + E + 4

E .id E E. * E * 5

3 7 E id . E E + E. E E.+ E

+ 4

E E.* E * 5

Page 160: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

156

taula de parser: id + * ( ) $ E 0 S3 S2 1 1 S4 S5 ACC 2 S3 S2 6 3 R4 R4 R4 R4 4 S3 S2 7 5 S3 S2 8 6 S4 S5 S9 7 S4/R1 S5/R1 R1 R1 8 S4/R2 S5/R2 R2 R2 9 R3 R3 R3 R3 Perquè dóna conflicte S/R? En aquest cas és perquè la gramàtica és ambigua. Teorema: Tota gramàtica ambigua no és LR. Certes gramàtiques ambigües són útils per a l'especificació i per a la implementació de llenguatges de programació. En general són més curtes i més naturals. Si les fem servir, hem de tenir un conjunt de regles per treure l'ambigüitat i assegurar un parser determinista. Per resoldre els conflictes que es generen (S/R) es fan servir les regles de precedència i d' associativitat. Anàlisi sintàctica d' id + id + id : 0 id + id + id $ 0 id 3 + id + id $ 0 E1 + id + id $ 0 E1 + 4 id + id $ 0 E1 + 4 id 3 + id $ 0 E1 + 4 E7 + id $ Si escollim el reduce R1 aleshores estaríem associant a esquerra. Anàlisi sintàctica d' id + id * id: 0 id + id + id $ 0 id 3 + id + id $ 0 E1 + id + id $ 0 E1 + 4 id + id $ 0 E1 + 4 id 3 + id $ 0 E1 + 4 E7 * id $ Si escollim el reduce R1 estaríem donant més prioritat a l'operador +. Si escollim el shift S5 aleshores estaríem donant més prioritat a l'operador * que al +. Llavors en aquest cas el que més ens convé és el shift.

Page 161: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

157

PRO 4.35

(1) E --> TE' (2) E' --> +TE' (3) E' --> ε (4) T --> FT' (5) T' --> *FT' (6) T' --> ε (7) F --> ( E ) (8) F --> id La taula de parser és la següent: first(TE')=first(T)=first(F)={ ( , id } first(+TE')={ + } follow(E')=follow(E)={ $ , ) } first(FT')={ ( , id } first(*FT')={ * } follow(T')=follow(T)=first(E')={ + } U follow(E')={ $ , ) } first( (E) )={ ( } first(id) = { id } M id + * ( ) $ E 1 1 E’ 2 3 3 T 4 4 T’ 6 5 6 6 F 8 7

Page 162: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

158

PRO 4.36

first(I(E))=first(I)={ a , f , z } first(I[E])=first(I)={ a , f , z } first(I)={ a , f , z } first(a)={ a } first(f)={ f } first(z)={ z }

PRO 4.39

a) És SLR(1), ja que no presenta conflictes. 0 S --> AB 1 A --> 0 A 1 2 A --> ε 3 Β −−> 1 Β 4 Β −−> 1 0 4

S .AB

A 1 B 1.B B 6

A .0A1

0 2 B 1. 1 4

A .

B . 1B

B . 1

1

S A.B

B 3 5

B .1B

1 4 A 0A. 1 1 7

B .1

6 2

B 1B.

A 0 . A 1

A 5

A .0A1

0 2 7

A .

A 0A1.

3

S AB.

Page 163: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

159

I la taula de parser és: 0 1 $ S A B 0 S2 R2 1 1 S4 3 2 S2 R2 5 3 ACC 4 S4 R4 6 5 S7 6 R3 7 R1 Com es pot veure, la taula no presenta conflictes, per tant podem concloure que la gramàtica és SLR(1). b) No és SLR(1), ja que presenta conflictes. 0 S' --> S 1 S --> 0 A 1 2 S --> Α 3 Α −> 1 Α 4 Α −> 1 0 3 S' .S

S 1 S A.

S .0A1 0 2

S . A A 3

4

A .1A 1 4

A 1.A B 6

A .1 A 1. 1 4 A . 1A 1 A . 1 S' S. ... 2 S 0 . S 1

S 5

S .0S1 0 2

S . A A 3

A . 1A 1 4

A . 1 No cal seguir, ja que en l'estat 4 hi ha un conflicte amb l'1. Follow(A)= {1} U first(B) = {1}

Page 164: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

160

0 1 $ S' S A 4 S4/R4 6 Com es pot veure hi ha un conflicte shift/reduce en l'estat 4. Per tant podem concloure que la gramàtica NO és SLR(1). c) És SLR(1), ja que no presenta conflictes. 0 S' --> S 1 S --> S + A 2 S --> Α 3 S --> a 4 A --> ( S ) 5 A --> a ( S ) 0 6 S' .S

S 1 A A ( .S )

S 10 S .S + A

A 2 S .S + A

A 2 S . A

a 3 S . A a 3

S .a ( 4

S .a ( 4

A .( S ) A . ( S ) A . a ( S ) 7 1 A ( S .)

S S. + A ) 11 + 5

S' S. + 5 S S. + A 8 S S + A. 2 S A. 9 A a . ( S) ( 6 3 S a. ( 6 10 S a . (S) S S .+ A

+ 5 A a ( S .) ) 12 4 A (.S) S 7 11 S . S + A A 2 A ( S) . S . A a 3 S . a ( 4 12 A . ( S ) A a ( S) . A . a ( S ) 5 S S + . A A 8 A . ( S ) ( 4 A . a ( S ) a 9

Page 165: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

161

Follow (S) = { + , ) , $} Follow (A) = Follow(S) ={ + , ) , $} La taula de parser és la següent: ( ) a + $ S A 0 S4 S3 1 2 1 S5 ACC 2 R2 R2 R2 3 S6 R3 R3 R3 4 S4 S3 7 2 5 S4 S9 8 6 S4 S3 10 2 7 S11 8 R1 R1 R1 9 S6 10 S12 S5 11 R4 R4 R4 12 R5 R5 R5 Com es pot veure la taula no presenta conflictes, per tant, la gramàtica és SLR(1).

Page 166: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

162

Page 167: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

163

Bibliografia

LLIBRES

Compilers. Principles, Techniques and Tools Aho, Afred V.; Sethi, Ravi; Ullman, Jefrey D. Addison-Wesley Publishing Company 1985 [Aho1985]

Compiler Construction. A Recursive Descent Model Elder, John Prentice Hall 1994 [Elder1994]

Page 168: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

164

Page 169: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

165

Glossari

Back end Fase d'un compilador independent del codi font i dependent de la màquina per la que es compila.

DDS Una definició dirigida per sintaxi (DDS) és una extensió del concepte de gramàtica incontextual. Una DDS és una gramàtica incontextual en què cada no-terminal de la gramàtica té un conjunt d'atributs associats. Un atribut pot contenir informació diversa. Cada atribut es pot calcular en funció d'altres atributs i gairebé sempre són expressions

FIRST, Primer Els first's d'una cadena de caràcters són els primers terminals que poden ser generats a partir d'ella. Aquesta informació s'utilitza en els parsers predictius per determinar els terminals que poden ser generats per la part dreta d'una producció de la gramàtica.

FOLLOW, Següent Els follow's són el conjunt de terminals que poden aparèixer a la dreta d'un símbol no-terminal en la derivació d'una frase. S'utilitzen per a la construcció de les taules de parsers predictius. També es poden utilitzar com el conjunt de sincronització en l'estratègia pànic de recuperació d'errors sintàctics

Front end Fase d'un compilador dependent del codi font i independent de la màquina per la que es compila.

Gramàtica incontextual Formalisme per expressar la sintaxi d'un llenguatge. Una gramàtica incontextual anomenada també lliure de context, té els següents components: un conjunt de terminals (tokens), un conjunt de no-terminals, un conjunt de produccions (regles sintàctiques) i un no-terminal especial anomenat símbol axioma. Les produccions són de la següent forma: A --> w, on A és un no-terminal i w és una cadena de terminals i no-terminals.

Gramàtica d'atributs Una gramàtica d'atributs és un cas particular de DDS ja que li demanem que les accions semàntiques no tinguin efectes col·laterals. Cada no-terminal de la gramàtica pot ser vist com un registre, així els atributs es poden veure com camps. És per això que la notació utilitzada per als atributs és la notació de punt com en el cas dels camps d'un registre.

Handle Part dreta d'una producció d'una gramàtica que es troba en la pila durant el reconeixement sintàctic i la reducció per la seva corresponent part esquerra significarà un pas cap al revers d'una derivació més a l'esquerra.

Page 170: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

166

LL Les gramàtiques LL (Left-Left) són un subconjunt de les gramàtiques lliures de context. A tota gramàtica LL se li pot construir un parser descendent predictiu. La primera L vol dir que l'entrada a analitzar es llegeix d'esquerra a dreta i la segona L vol dir que durant l'anàlisi sintàctica les produccions són aplicades d'esquerra a dreta. Els parsers construïts a partir de gramàtiques LL s'anomenen parsers LL.

LALR, lookahead LR Una gramàtica és anomenada LALR si li podem construir un parser LALR. La construcció d'un parser LALR consisteix a, primer, construir la col·lecció de conjunts d'ítems LR(1) i després unir els estats que tenen el mateix core. El core d'un estat són les parts esquerres dels ítems.

LR, canònics LR Les gramàtiques per a les quals li podem construir un parser ascendent canònic són anomenades gramàtiques LR. La primera L vol dir que l'entrada es llegeix d'esquerra (Left) a dreta i la R vol dir que es produeix una derivació més a la dreta (Right)

Parser ascendent, Parser bottom up , Parser shift-reduce Els parsers ascendents són analitzadors sintàctics que fan una anàlisi bottom up, és a dir, construeixen l'arbre de parser començant en les fulles i acabant en l'arrel. Els parsers LR que estudiarem són parsers shift-reduce ja que l'anàlisi sintàctica es fa amb dues operacions: shift i reduce.

Parser descendent, Parser top down Els parsers descendents són analitzadors sintàctics que fan una anàlisi top down, és a dir, construeixen l'arbre de parser començant en l'arrel (etiquetada amb el símbol axioma) i acabant amb les fulles (terminals de la gramàtica). Les produccions de la gramàtica són aplicades d'esquerra a dreta, és a dir, expandint el no-terminal de la part esquerra per la part dreta corresponent.

Parser descendent predictiu Un parser descendent és predictiu (sense backtracking) si en cada pas de l'anàlisi sintàctica, sap seleccionar la pròxima producció examinant els primers k símbols de l'entrada.

Parser, Analitzador sintàctic Un analitzador sintàctic o parser és un algorisme capaç de reconèixer la sintaxi de qualsevol entrada corresponent al llenguatge de programació implementat. Dit d'una altra manera, és l'autòmat que reconeix el llenguatge que una gramàtica defineix.

Prefix viable Prefix d'una forma sentencial que apareix en el cim de la pila d'un parser shift reduce.

Scanner, Analitzador lexicogràfic L'analitzador lexicogràfic o scanner és la fase del compilador que analitza linealment el programa font, vist com una seqüència de caràcters, i agrupa aquests caràcters en unitats lexicals anomenades tokens.

Page 171: La Salle - Creative Commons License Deed...La sintaxi d'un llenguatge de programació especifica les regles sintàctiques, és a dir, descriu com s'escriu un programa. La semàntica

167

SLR, simples SLR Les gramàtiques per a les quals podem construir un parser ascendent simple són anomenades gramàtiques SLR. La construcció d'un parser SLR consisteix a, primer, construir la col·lecció de conjunts d'ítems LR(0) i després construir la corresponent taula.

Símbol director, SD, DS Els símbols directors d'una producció representen tots els possibles terminals que poden aparèixer en l'entrada per als quals la producció es podria aplicar. La definició està en funció de dos altres conceptes: els FIRST's i els FOLLOW's.

Token Elements bàsics del llenguatge. Aquests elements bàsics són els terminals de la gramàtica incontextual que defineixen el llenguatge que volem compilar. Per determinar els tokens que ha de reconèixer l'analitzador, hem d'estudiar el llenguatge i determinar tots els aspectes regulars. És imprescindible conèixer el vocabulari sobre el qual està definit el llenguatge.