1 / 24

Analizzatori Lessicali con JLex

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.

Download Presentation

Analizzatori Lessicali con JLex

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Analizzatori Lessicali con JLex Giuseppe Morelli

  2. 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)

  3. 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

  4. 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

  5. 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”.

  6. 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

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

  8. 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.

  9. Struttura di un file di specifica Lex • Tre sezioni separate dal simbolo “%%”: • User Code: viene ricopiata nel file java finale “as is”; fornisce “spazio” per implementare classi di supporto etc.. • JLex directives: Vengono definite le Macro e vengono dichiarati i nomi degli stati • 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

  10. 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

  11. 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}

  12. 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

  13. 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.

  14. 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

  15. 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à)

  16. 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

  17. Espressioni regolari

  18. 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)

  19. 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

  20. 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

  21. Esempi • Riconoscitore di Numeri ed identificatori • Riconoscitore di Numeri ed identificatori evoluto • Utilizzo degli stati per il riconoscimento di “stringhe”

More Related