24
Analizzatori Lessicali con JLex Giuseppe Morelli

Analizzatori Lessicali con JLex

Embed Size (px)

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 Presentation

Citation preview

Page 1: Analizzatori Lessicali con JLex

Analizzatori Lessicali con JLex

Giuseppe Morelli

Page 2: Analizzatori Lessicali con JLex

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

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

• 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

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

• 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

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

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

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

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

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

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

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

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

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

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

Espressioni regolari

Page 18: Analizzatori Lessicali con JLex
Page 19: Analizzatori Lessicali con JLex
Page 20: Analizzatori Lessicali con JLex

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

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

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

Esempi

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

“stringhe”