analizzatori lessicali con jlex
DESCRIPTION
Analizzatori Lessicali con JLex. Giuseppe Morelli. Terminologia. Tre concetti sono necessari per comprendere la fase di analisi lessicale: TOKEN: rappresenta un oggetto in grado di rappresentare una specifica classe di unità lessicali. In genere è rappresentato da un nome ed un attributo. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/1.jpg)
Analizzatori Lessicali con JLex
Giuseppe Morelli
![Page 2: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/2.jpg)
Terminologia
• Tre concetti sono necessari per comprendere la fase di analisi lessicale:– TOKEN: rappresenta un oggetto in grado di
rappresentare una specifica classe di unità lessicali. In genere è rappresentato da un nome ed un attributo.
– PATTERN o MODELLO: è una descrizione compatta delle possibili forme che una unità lessicale può assumere
– LESSEMA: è una sequenza di caratteri del programma sorgente che corrisponde al pattern di un token (istanza specifica di un token)
![Page 3: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/3.jpg)
Compiti di un analizzatore lessicale
• È la prima fase del processo di compilazione ed ha il compito principale di leggere il programma sorgente (sequenza di caratteri), raggrupparli in lessemi, e produrre in uscita una sequenza di token corrispondente ai lessemi trovati, interagendo con la tabella dei simboli.
• Trattando direttamente il programma sorgente l’analizzatore lessicale è in grado di svolgere ulteriori operazioni e/o compiti
![Page 4: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/4.jpg)
• Elimina e/o ignora spazi vuoi e delimitatori in genere (spazi, tabulazioni, ritorni a capo)
• Associa i messaggi di errore prodotti dal compilatore al programma sorgente ( es. conta il numero di CR e lo restituisce in presenza di un errore, o si occupa di riscrivere il programma sorgente con “iniettato” il messaggio di errore nella linea corrispondente)
• Se nel programma sorgente sono presenti delle macro potrebbe occuparsi della relativa espansione
![Page 5: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/5.jpg)
Fasi analisi lessicale
• A volte gli analizzatori lessicali sono visti come composizione di due distinti processi:
• La scansione o scanning: eliminazione di separatori e commenti espansione di macro etc. …ovvero tutte le attività che non richiedono la tokenizzazione
• L’analisi lessicale vera e propria: produzione della sequenza di TOKEN a partire dalla sequenza già “scansionata”.
![Page 6: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/6.jpg)
• Un analizzatore lessicale ha lo scopo di suddividere un “flusso” di caratteri in input in TOKEN.
• Realizzare un analizzatore lessicale da zero, può risultare un lavoro alquanto complicato.
• La miglior utility per la costruzione di un analizzatore lessicale è il programma Lex (generatore di analizzatori lessicali per Unix) che, dato un file di specifiche, genera il codice C di un analizzatore che soddisfa le specifiche
![Page 7: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/7.jpg)
JLex
• JLex è una utility basata sul modello Lex, prende infatti delle specifiche simili a quelle accettate da Lex, quindi, crea un sorgente Java che implementa un analizzatore lessicale soddisfacente le specifiche.
![Page 8: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/8.jpg)
Download ed installazione
• Il Link : http://www.cs.princeton.edu/~appel/modern/java/JLex/
• È possibile scaricare il sorgente del generatore: Main.java (naturalmente è scritto in Java)
• Si mette in una directory JLex (il cui path sta nel PATH di ambiente)
• Si compila
• Si richiama su un file di specifica con :java JLex.Main source.lex
• Nello stesso sito: manuale, readme, esempi.
![Page 9: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/9.jpg)
Struttura di un file di specifica Lex
• Tre sezioni separate dal simbolo “%%”:1. User Code: viene ricopiata nel file java finale “as is”;
fornisce “spazio” per implementare classi di supporto etc..
2. JLex directives: Vengono definite le Macro e vengono dichiarati i nomi degli stati
3. JLex rules: vengono definite le regole per l’analisi ognuna delle quali consiste di tre parti: lista degli stati (opzionale), espressione regolare, azione
User code%%Jlex directives%%JLex rules
![Page 10: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/10.jpg)
User Code Section
• Contiene le classi per:– Utilizzo del lexer
(potrebbe non esserci se utilizzato in combinazione con un generatore di parser)
– Funzioni, proprietà, variabili e/o costanti di supporto
– La definizione degli oggetti TOKEN
![Page 11: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/11.jpg)
Note: JLex Directives
• Yylex: è la classe generata dal lexer che implementa l’analizzatore lessicale
• Per l’utilizzo del lexer nella sezione user code viene istanziato un oggetto e poi utilizzato come precedentemente mostrato
• Vedremo in seguito che si può inserire codice in tale classe – Inserendo metodi e/o proprietà %{ code %}– Modificandone il costruttore (con o senza gestione
delle eccezioni) %init{ code %init}– Inserendo codice eseguibile quando la fine del file
viene raggiunta %eof{ code %eof}
![Page 12: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/12.jpg)
JLex Directives – Definizione di Macro
• Una macro è di fatto la definizione di una espressione regolare;
• Consiste di : <nome> = <definzione> dove nome è un identificatore, definizione è una espressione regolare;
• Una definizione di macro può contenere l’espansione di altre macro
![Page 13: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/13.jpg)
JLex Directives - Dichiarazione di stato
• Gli stati lessicali sono utilizzati per controllare il matching di alcune espressioni regolari.
• La dichiarazione avviene:%state state[0], state[1], state[2] …..
dove state[0], state[1], state[2] … sono identificatori validi
• YYINITIAL è lo stato implicito di ogni lexer generato con JLex
• Tali stati compaiono opzionalmente all’inizio di ogni regola per la selezione della stessa.
![Page 14: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/14.jpg)
JLex Directives
• %char permette di attivare il conteggio dei caratteri(yychar)in input (0 based)
• %line permette di attivare il conteggio dei caratteri(yyline)in input (0 based) utile per la gestione e la segnalazione degli errori
• La funzione Yylex.yylex() è la funzione da invocare per avere i TOKEN di tipo YytokenSi possono modificare le cose con:– %class <name> cambio Yylex in name– %function <name> cambio yylex in name– %type <name> cambio Yytoken in name
![Page 15: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/15.jpg)
JLex Rules: Regolar Expression
• Si tratta delle regole che consentono la suddivisione in TOKEN dell’input.
• Si associano espressioni regolari, che rappresentano i lessemi del linguaggio, ad azioni (ovvero codice Java…. tokenizzazione)
• Ogni regola ha tre parti:[<stati>] <espressione> {<azione>}
• Se più di una regola è soddisfatta da una stringa di input viene eseguita la prima in ordine di apparizione (maggiore priorità)
![Page 16: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/16.jpg)
Stati ed espressioni
• <stato0, stato1,…>: elenco di stati, opzionali, che permettono di attivare una regolaSe la funzione yylex() è chiamata con il lexer che si trova nello stato X, il lexer potrà fare il matching con regole che hanno X nell’elenco degli stati
• Nessuno stato -> la regola è selezionata in tutti gli stati
• L’alfabeto per JLex è rappresentato dal set di caratteri Ascii (0 – 127):– Metacaratteri ? * + | ( ) ^ $ . [ ] { } “ \– Escape \b \n \t \f \r \ddd \^C \c – Concatenazione r1r2 concatenazione di r1 ed r2– Scelta r1 | r2 r1 oppure r2
![Page 17: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/17.jpg)
Espressioni regolari
![Page 18: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/18.jpg)
![Page 19: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/19.jpg)
![Page 20: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/20.jpg)
Azione
• L’azione associata ad una regola lessicale consiste in un blocco di codice Java{ codice }
• Tale codice dovrebbe prevedere un valore di ritorno.. Altrimenti il lexer va in loop alla ricerca di un altro lessema(coincide ad una chiamata ricorsiva a yylex())
• Attenzione alla ricorsione ed alla giusta gestione di yyline e yychar (non tail recursion vs tail recursion)
![Page 21: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/21.jpg)
Transizione degli stati
• La transizione degli stati è fatta da una azione attraverso la chiamata alla funzione yybegin(state)
• state deve essere uno stato valido dichiarato nella sezione JLex Directives
• YYINITIAL è l’unico stato implicito ed è lo stato in cui il lexer rimane fino a che una non viene effettuata una transizione
![Page 22: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/22.jpg)
![Page 23: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/23.jpg)
Il Lexer generato: note
• Risiede in una classe Yylex• La funzione di accesso al lexer è Yylex.yylex()
che restituisce token di tipo Yytoken• La classe Yytoken deve essere dichiarata nella
USER CODE Section: – può ridefinire anche tipi primitivi– Si possono definire gerarchie di classi per token
![Page 24: Analizzatori Lessicali con JLex](https://reader035.vdocuments.mx/reader035/viewer/2022062516/56812be5550346895d905db9/html5/thumbnails/24.jpg)
Esempi
• Riconoscitore di Numeri ed identificatori• Riconoscitore di Numeri ed identificatori evoluto• Utilizzo degli stati per il riconoscimento di
“stringhe”