Analizzatori Lessicali con JLex Giuseppe Morelli.

24
Analizzatori Lessicali con JLex Giuseppe Morelli

Transcript of Analizzatori Lessicali con JLex Giuseppe Morelli.

Page 1: Analizzatori Lessicali con JLex Giuseppe Morelli.

Analizzatori Lessicali con JLex

Giuseppe Morelli

Page 2: 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.

– 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 Giuseppe Morelli.

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 Giuseppe Morelli.

• 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 Giuseppe Morelli.

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 Giuseppe Morelli.

• 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 Giuseppe Morelli.

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 Giuseppe Morelli.

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 Giuseppe Morelli.

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 Giuseppe Morelli.

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 Giuseppe Morelli.

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 Giuseppe Morelli.

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 Giuseppe Morelli.

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 Giuseppe Morelli.

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 Giuseppe Morelli.

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 Giuseppe Morelli.

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 Giuseppe Morelli.

Espressioni regolari

Page 18: Analizzatori Lessicali con JLex Giuseppe Morelli.
Page 19: Analizzatori Lessicali con JLex Giuseppe Morelli.
Page 20: Analizzatori Lessicali con JLex Giuseppe Morelli.

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 Giuseppe Morelli.

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 Giuseppe Morelli.
Page 23: Analizzatori Lessicali con JLex Giuseppe Morelli.

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 Giuseppe Morelli.

Esempi

• Riconoscitore di Numeri ed identificatori• Riconoscitore di Numeri ed identificatori evoluto• Utilizzo degli stati per il riconoscimento di

“stringhe”