Upload
others
View
15
Download
0
Embed Size (px)
Citation preview
javaccAnalisi LessicaleNicola FanizziCorso di Linguaggi di Programmazione
Dipartimento di Informatica
Università degli Studi di Bari
10 aprile 2014
Sommario
1 JavaCC
Installazione
Nozioni Preliminari
2 Espressioni Regolari Estese
Operatori
Insiemi di Caratteri
Denominazione dei token
3 File di specifica
Sezioni
File prodotti da JavaCC
Regole di match del token
manager
Azioni nel token manager
Opzioni & Debug
4 Argomenti Avanzati
Regole SPECIAL_TOKENRegole MORE
5 Esercizi
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 2 / 75
JavaCCSommario
1 JavaCC
Installazione
Nozioni Preliminari
2 Espressioni Regolari Estese
Operatori
Insiemi di Caratteri
Denominazione dei token
3 File di specifica
Sezioni
File prodotti da JavaCC
Regole di match del token
manager
Azioni nel token manager
Opzioni & Debug
4 Argomenti Avanzati
Regole SPECIAL_TOKENRegole MORE
5 Esercizi
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 3 / 75
JavaCC InstallazioneJavaCC
JavaCC = Java Compiler CompilerPartendo dalla specifica di una grammatica, genera
le classi Java che realizzano
un analizzatore sintattico top-down edun analizzatore lessicale per tale grammatica
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 4 / 75
JavaCC InstallazioneInstallazione JavaCCSiti ufficiali:
http://javacc.java.net/http://java.net/projects/javacc
Versione corrente 5.0Multipiattaforma:
Pacchetto in molte distribuzioni GNU/Linux
es. per Ubuntu-Linux
http://packages.ubuntu.com/search?keywords=javaccper Windows: decomprimere e settare opportunamente le
var. d’ambiente PATH e CLASSPATHPlugin per IDE Java principali
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 5 / 75
JavaCC Nozioni PreliminariGenerazione Automatica con JavaCC ISi possono usare programmi detti token manager generator(detti anche lexical analyzer generator) per scrivere un tokenmanager
Si danno in input espressioni regolari che definiscono i tokenche si vogliono identificare
Il generatore di token manager produrrà il token manager
corrispondente in Java
espressione
regolare
generatore di
token
manager
codice Java
del TM
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 6 / 75
JavaCC Nozioni PreliminariGenerazione Automatica con JavaCC IISi può usare un programma analogo parser generator perscrivere l’analizzatore sintattico.
si dà in input una grammatica del linguaggio
il generatore restituisce il parser in Java
grammatica
del linguaggio
generatore di
parser
codice Java
del parser
Ci soffermeremo sull’approccio top-down ricorsivo discendente:per ogni non-terminale si scrive un metodo basato sulle
produzioni della grammatica
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 7 / 75
JavaCC Nozioni PreliminariGenerazione Automatica con JavaCC IIIJavaCC combina i generatori di token manager e di parser
effettua a sua volta una compilazione:traduce il suo input in un compilatore
pertanto appartiene alla categoria dei compiler-compiler(compilatori di compilatori), da cui il suffisso nel nome
accetta un file di specifica contenenteespressioni regolari (per il token manager)
grammatica (specifica per il parser o traduttore)
espressioni
regolari
grammatica
JavaCCcodice Java
del compilatore
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 8 / 75
JavaCC Nozioni PreliminariGenerazione Automatica con JavaCC IV
Vantaggi dell’uso di JavaCC1 si riduce il tempo di produzione di un compilatore
2 si producono compilatori più affidabili
la maggioranza dei bachi nei compilatori scritti a mano sono
introdotti nel processo di calcolo degli insiemi di selezione
(first+follow)
JavaCC solleva da questi compiti e li svolge automaticamente,producendo meno errori (nessuno se si danno specifiche
corrette)
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 9 / 75
JavaCC Nozioni PreliminariToken Manager I
Il Token Manager (detto anche scanner o lexer)analizza il flusso di caratteri in input spezzandolo in
sequenze riconosciute dette lessemiassegnando ad ognuno di loro un tipo o token
spesso si usa lo stesso nome (token) per entrambi
Esempio (sorgente in C):
1 int main() {2 /* a short program */3 return 0; }
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 10 / 75
JavaCC Nozioni PreliminariToken Manager II1 int main() {2 /* a short program */3 return 0; }
Il token manager divide il flusso nelle seguenti stringhe:
"int", " ", "main", "(", ")", " ", "{", "\n", "\t","/* a short program */", "\n", "\t", "return", . . .Spaziatura e commenti tipicamente vengono saltati
Ogni stringa viene classificata secondo uno dei tipi di token:
Ad es. nel caso precedente:
KWINT, ID, LPAR, RPAR, LBRACE, KWRETURN, INTCONST,SEMICOLON, RBRACE
I pattern che permettono di operare questo riconoscimento
e di far generare automaticamente l’automa relativo,
sono descritti attraverso espressioni regolariN. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 11 / 75
Espressioni Regolari EsteseSommario
1 JavaCC
Installazione
Nozioni Preliminari
2 Espressioni Regolari Estese
Operatori
Insiemi di Caratteri
Denominazione dei token
3 File di specifica
Sezioni
File prodotti da JavaCC
Regole di match del token
manager
Azioni nel token manager
Opzioni & Debug
4 Argomenti Avanzati
Regole SPECIAL_TOKENRegole MORE
5 Esercizi
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 12 / 75
Espressioni Regolari EsteseEspressioni Regolari Estese INelle espressioni regolari estese di JavaCC,i simboli dell’alfabeto vanno racchiusi tra doppi apici
Esempio (doppi apici)
per rappresentare le due stringhe "b" e "c":"b"|"c"
I doppi-apici aiutano a distinguere i simboli dell’alfabeto dai
meta-simboli, come le parentesi e gli operatori
Esempio (doppi apici – cont.)
La barra verticale è un operatore (non è racchiusa tra i doppi
apici)
Invece, "b|c" rappresenta la sola stringa "b|c"Qui la barra è un carattere da interpretare letteralmente
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 13 / 75
Espressioni Regolari EsteseEspressioni Regolari Estese II
Esempio (spazi ignorati)
"a"|"z" e "a"| "z" sono equivalentiMa "a"|"z" e "a "|"z" non lo sono;lo spazio dopo la a nell’ultima espressione è all’interno degli apici
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 14 / 75
Espressioni Regolari Estese OperatoriOperatori
Operatori (postfissi) per iterazione / selezione
* (zero o più)+ (uno o più)? (zero o uno)
JavaCC richiede che gli argomenti di questi operatori siano
racchiusi tra parentesi tonde
Esempio (iterazione)
per indicare tutte le stringe di zero o più b,si scrive ("b")* e non "b"*
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 15 / 75
Espressioni Regolari Estese Insiemi di CaratteriInsiemi di Caratteri I
Usando le par. quadre ([ ]),si specifica un insieme di caratteri singoli;elementi successivi vanno separati con delle virgole (,):
Esempio (insiemi di caratteri)
per indicare l’insieme contenente b, c e dsi può scrivere ["b","c","d"]che è anche equivalente a "b"|"c"|"d"
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 16 / 75
Espressioni Regolari Estese Insiemi di CaratteriInsiemi di Caratteri II
Si possono anche specificare intervalli di caratteri usando iltrattino (-) tra due caratteri:
Esempio (intervalli di caratteri)
per specificare tutte le lettere maiuscole e minuscole
si possono indicare gli intervalli da A a Z e da a a z tra quadre:["A"-"Z","a"-"z"]che risulta molto più compatta dell’elenco di 52 lettere
["A","B",. . .,"Z","a","b",. . .,"z"]
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 17 / 75
Espressioni Regolari Estese Insiemi di CaratteriInsiemi di Caratteri III
NB: nelle quadre vanno solo caratteri singoli e non stringhe:
Esempio (intervalli di caratteri – errori tipici)
["a"-"z", "AZ", "\n"] è un’espressione errata:"a"-"z" e "\n" sono leciti (range e singolo car. di newline),invece "AZ" è una stringa
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 18 / 75
Espressioni Regolari Estese Insiemi di CaratteriInsiemi di Caratteri IVL’operatore di complemento ~si applica solo ad insiemi di caratteri definiti con l’op. [ ]
Esempio (complemento di set di caratteri)
~["z"] rappresenta tutti i caratteri tranne la z~["a","z"] rappresenta tutti i caratteri tranne a e zInvece non è lecita l’espressione: ~"z"il complemento è definito per set di caratteri non per caratteri
singoli
Diversamente da *, + e ?, non si usano le tonde con l’operatore ~:
Esempio (complemento – errori tipici)
~(["z"]) errata, ~("z") errata
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 19 / 75
Espressioni Regolari Estese Insiemi di CaratteriInsiemi di Caratteri V
[] rappresenta l’insieme vuoto,quindi ~[] rappresenta tutti i caratteri disponibili
Esercizio Scrivere un’espressione regolare estesa che
rappresenti l’insieme di tutte le possibili stringhe
Risposta: (~[])*Si noti che le parentesi tonde servono all’op. * non a ~
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 20 / 75
Espressioni Regolari Estese Insiemi di CaratteriEsempio – token per le costanti numeriche ISi definiscano i token per gli interi senza segno:
uno o più cifre
(["0"-"9"])+Si supponga di voler specificare anche i numeri senza segno ma
con la parte decimale: 68, 3.14, 54., .22
Prima proposta (zero o più cifre prima o dopo il punto decimale):
(["0"-"9"])* "."(["0"-"9"])*non funziona per numeri come 68comprende anche il caso (errato) della stringa “.”
Dividiamo le stringhe nei vari casi:
1 cifre senza punto decimale (come 68)2 cifre prima e dopo il punto decimale (come 3.14)3 cifre solo prima del punto decimale (come 54.)4 cifre solo dopo il punto decimale (come .22)
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 21 / 75
Espressioni Regolari Estese Insiemi di CaratteriEsempio – token per le costanti numeriche II
Si può scrivere l’espressione cercata, unendo 4 espressioni con |(["0"-"9"])+ (1)
| (["0"-"9"])+ "." (["0"-"9"])+ (2)
| (["0"-"9"])+ "." | (3)
| "." (["0"-"9"])+ (4)
che equivale a:
(["0"-"9"])+ (1)
| (["0"-"9"])+ "." (["0"-"9"])* (2+3)
| "." (["0"-"9"])+ (4)
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 22 / 75
Espressioni Regolari Estese Insiemi di CaratteriEsempio – token per identificatori
Fornire l’espressione regolare per identificatori fatti da una letteraeventualmente seguita da lettere o cifre.Una soluzione
["A"-"Z", "a"-"z"] (["A"-"Z","a"-"z","0"-"9"])*
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 23 / 75
Espressioni Regolari Estese Insiemi di CaratteriCaratteri specialiSiccome doppi apici (") e backslash (\) sono caratteri specialise si vuole specificare letteralmente uno di essi (escape)bisognerà farlo precedere da un backslash
Esempio (escape)
per specificare la stringa fatta da A, \, " e Z si scrive
"A\\\"Z"
Alcuni altri caratteri normali, preceduti da backslash, hanno
significati speciali. Ad esempio,
"\n" newline"\r" return"\t" tab
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 24 / 75
Espressioni Regolari Estese Denominazione dei tokenDenominazione dei token IJavaCC consente di dare un nome alle espressioni regolari:si racchiudono nome ed espressione tra partentesi angolari < >,separandoli con :
Esempio (nomi di espressioni)
per associare il nome UNSIGNED all’espressione regolare per gliinteri senza segno, si scrive
<UNSIGNED: (["0"-"9"])+>
Per convenzione, si usano le MAIUSCOLE per i nomi, come
per le costanti Java
Associato un nome ad una espressione, ci si può riferire allacategoria di tokenmediante tale nomeN. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 25 / 75
Espressioni Regolari Estese Denominazione dei tokenDenominazione dei token II
Dato un nome ad un’espressione, lo si può riusare (tra parentesi
angolari) per definire altre espressioni:
Esempio (riutilizzare i nomi)
Data <DIGIT: ["0"-"9"]> si può riscrivere l’espressione per gliinteri senza segno come segue:
<UNSIGNED: (<DIGIT>)+>
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 26 / 75
File di specificaSommario
1 JavaCC
Installazione
Nozioni Preliminari
2 Espressioni Regolari Estese
Operatori
Insiemi di Caratteri
Denominazione dei token
3 File di specifica
Sezioni
File prodotti da JavaCC
Regole di match del token
manager
Azioni nel token manager
Opzioni & Debug
4 Argomenti Avanzati
Regole SPECIAL_TOKENRegole MORE
5 Esercizi
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 27 / 75
File di specificaFile di specifica II file di specifica di JavaCC per convenzione hanno estensione .jjStruttura di un tipico file1 options {2 // opzioni di JavaCC3 }4
5 PARSER_BEGIN(NomeParser)6 // Sezione per la classe del parser e classi accessorie7 PARSER_END(NomeParser)8
9 TOKEN_MGR_DECLS: {10 // dichiarazioni di var e metodi per il token manager11 }12
13 SKIP: {14 // espr.reg. di token da saltare senza passarle al parser15 }16
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 28 / 75
File di specificaFile di specifica II
17 TOKEN: {18 // espr.reg. di token da riconoscere e passare al parser19 }20
21 // sezione della grammatica
Sono consentiti commenti Java-style, su singola linea con // o supiù linee, delimitati da /* e */
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 29 / 75
File di specifica SezioniSezioni Ila sez. options serve a settare opzioni di JavaCC.
Es. STATIC = false; serve a generare metodi non staticila sez. PARSER_BEGIN/PARSER_END contiene il codice Java dafornire a JavaCC
deve contenere almeno la classe del parser
(indicata tra parentesi)
classi addizionali
(es. per la symbol table o generatore di codice)
non è obbligatorio che la classe parser contenga codice Java
1 PARSER_BEGIN (Sample)2 public class Sample {3 /*4 public static void main (String[] args) {5 ...6 }7 */8 }9 PARSER_END (Sample)
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 30 / 75
File di specifica SezioniSezioni II
la sez. TOKEN_MGR_DECLS contiene dichiarazioni di variabili emetodi ad uso del token manager
una sez. SKIP contiene espressioni regolari per i token che iltoken manager non deve passare al parser
1 SKIP: {2 " "3 | "\n"4 | "\r"5 | "\t"6 }
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 31 / 75
File di specifica SezioniSezioni III
la sez. TOKEN contiene espressioni regolari per i token che iltoken manager deve passare al parser; i nomi saranno poi
utilizzati nella grammatica
1 TOKEN: {2 <PRINTF: "printf"> |3 <UNSIGNED: (["0"-"9"])+> |4 <ID: ["A"-"Z","a"-"z"] (["A"-"Z","a"-"z","0"-"9"])*>5 }
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 32 / 75
File di specifica SezioniSezioni IVL’ordine conta: se due espressioni corrispondono alla stessa
immagine di car. in input, JavaCC userà la prima della lista
ad es. se si leggesse la stringa printf sull’input,sia <PRINTF> sia <ID> troverebbero corrispondenza;ma sarebbe restituito <PRINTF> che viene primain alternativa, si può specificare "printf" come tokenanonimo nella grammatica per il parserNB: i token anonimi sono considerati come inseriti
virtualmente alla fine della sez. TOKENI token elencati nelle sez. TOKEN e SKIP che non siano stringheletterali vanno delimitati da par. angolari:
1 TOKEN: {2 ("i")+ // errato, dovrebbe essere <("i")+>3 "while" // corretto, scritto anche <"while">4 }
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 33 / 75
File di specifica File prodotti da JavaCCFile prodotti da JavaCCClassi generiche (file prodotti se non già esistenti)SimpleCharStream.java flussi di caratteri in input
Token.java classe degli oggetti tokenTokenMgrError.java errore dell’analizzatore lessicale
ParseException.java eccezioni: non conformità allagrammatica del parser
Classi/interfacce specifiche (prefisso NN)NN.java classe del parser
NNTokenManager.java classe dell’analizzatore lessicale;contiene il metodo getNextToken()
NNConstants.java interfaccia che associa nomi simbolici(costanti) alle classi di token
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 34 / 75
File di specifica File prodotti da JavaCCMetodo getNextToken()
Il metodo getNextToken() del token managerimplementa la simulazione del DFA che riconosce i token
descritti dalle espressioni regolari
alla chiamata
cerca la corrispondenza tra le espressioni regolari e
le stringhe di caratteri nelle sequenza di input
restituisce il token (oggetto) relativo alla prima
corrispondenza trovata
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 35 / 75
File di specifica File prodotti da JavaCCClasse Token
Token.java contiene i campi:1 public int kind; // tipo di token2
3 /* posizione di inizio e fine4 del token nel file di input */5 public int beginLine;6 public int beginColumn;7 public int endLine;8 public int endColumn;9
10 public String image; // immagine del lessema
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 36 / 75
File di specifica File prodotti da JavaCCGenerazione del solo token manager ISe non si include una grammatica,
JavaCC non genera il codice per il parser.
Il blocco PARSER_BEGIN/PARSER_END può essere usato percodice Java ad uso del solo token manager
es. minimalmente per il main()
1 options {2 STATIC = false;3 }4
5 PARSER_BEGIN(SenzaParser)6 import java.io.*;7 class SenzaParser {8 public static void main(String[] args) throws IOException {9 Token t;10 FileInputStream in=new FileInputStream(args[0]);11
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 37 / 75
File di specifica File prodotti da JavaCCGenerazione del solo token manager II12 SenzaParserTokenManager tm =13 new SenzaParserTokenManager(new SimpleCharStream(in));14
15 t = tm.getNextToken();16 while (t.kind != EOF) {17 System.out.println(tokenImage[t.kind] + " " + t.kind);18 t = tm.getNextToken();19 } // while20 } // main21 } // class22 PARSER_END(SenzaParser)23
24 SKIP: {25 " "26 | "\n"27 | "\r"28 | "\t"29 }30
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 38 / 75
File di specifica File prodotti da JavaCCGenerazione del solo token manager III31 TOKEN: {32 "printf" |33 <UNSIGNED: (["0"-"9"])+> |34 <ID: ["A"-"Z","a"-"z"] (["A"-"Z","a"-"z","0"-"9"])*> |35 <ERROR: ~[]>36 }
da cui, utilizzando un file contenente
1 345printf area x+
si otterrebbero le stampe1:
1 <UNSIGNED> 3452 "printf" printf3 <ID> area4 <ID> x5 <ERROR> +
1L’array String[] tokenImage è definito nel file dell’interfaccia con le
costanti SenzaParserConstants.java.N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 39 / 75
File di specifica Regole di match del token managerRegole di match del token manager ICercando la corrispondenza tra le espr. regolari e il flusso di
caratteri in input, il token manager generato segue 2 regole:1 Cercare sempre il più lungo match possibile
Esempio (match)
1 TOKEN: {2 <Ti: ("i")+>3 }Se si legge "iiixyz" allora <Ti> trova corrispondenza con tresotto-stringhe: "i", "ii" e "iii"ma il token manager restituirà la piùlunga "iii"
2 A parità di lunghezza, si sceglie la corrispondenza che viene
prima nell’elenco.
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 40 / 75
File di specifica Regole di match del token managerRegole di match del token manager II
EsercizioData la sezione
1 TOKEN: {2 <UNO: "123">3 |4 <DUE: "123456">5 }
Quale token verrebbe restituito,
se il token manager avesse in input "123456789" ?
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 41 / 75
File di specifica Regole di match del token managerErrori Lessicali I
1 TOKEN: {2 <ASSIGN: "="> |3 <UNSIGNED: (["0"-"9"])+> |4 <ID: ["A"-"Z","a"-"z"] (["A"-"Z","a"-"z","0"-"9"])*>5 }
leggendo lato += 10 il token manager avrebbe un problemasu "+", e lancerebbe un’eccezione non essendo possibiletrovare alcuna corrispondenza nella sezione
Diversamente dal parser, esso non sa cosa aspettarsi dal
flusso quando incontra un car. non valido
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 42 / 75
File di specifica Regole di match del token managerErrori Lessicali IIApproccio alternativo1 far restituire al token manager il bad token al parser.
Il parser potrebbe comprendere l’errore e lanciare
un’eccezione, segnalando un errore, con più info a
disposizione.
Vanno previsti appositi blocchi catch2 per catturare i bad token, si può includere alla fine della sez.
TOKEN l’espr. <ERROR: ~[]> che rappresenta singoli carattericaveat: se si usassero token anonimi nella grammatica JavaCC
li includerebbe a fine sez. TOKEN dopo ERROR.Conviene allora elencare nella sez. TOKEN tutti i token possibiliprima di ERROR
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 43 / 75
File di specifica Regole di match del token managerRegole SKIP / I
Le regole nel blocco SKIP indicano quello che va ignorato:tipicamente i blank ma anche i commenti
1 SKIP:2 {3 <espressioneRegolare1>4 | <espressioneRegolare2>5 | ...6 | <espressioneRegolaren>7 }
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 44 / 75
File di specifica Regole di match del token managerRegole SKIP / IIEsempio1
2 PARSER BEGIN(File2)3
4 public class File2{5
6 }7
8 PARSER END(File2)9
10 SKIP:11 {12 <" ">13 | <"\n">14 | <"\t">15 }16
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 45 / 75
File di specifica Regole di match del token managerRegole SKIP / III17 TOKEN:18 {19 <ELSE: "else">20 | <SEMICOLON: ";">21 | <FOR: "for">22 | <UNSIGNED: (["0"-"9"])+>23 | <IDENTIFIER: ["a"-"z"](["a"-"z","0"-"9"])*>24 }
Per l’input:
1 else ;2 23 for
viene restituita la sequenza:
<ELSE> <SEMICOLON> <UNSIGNED> <FOR>
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 46 / 75
File di specifica Regole di match del token managerRegole SKIP / IV
EsempioIgnorare i commenti C++ (singola linea):
1 SKIP:2 {3 <"//" (~["\n"])* "\n">4 }
regola poco espressiva
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 47 / 75
File di specifica Regole di match del token managerStati lessicali IOgni regola di tipo TOKEN o SKIP può essere etichettata conuno stato lessicaleLe regole non etichettate sono considerate regole nello stato
lessicale DEFAULTIl token manager deve trovare corrispondenze con le sole
regole etichettate con lo stato lessicale in cui si trova
1 <STATO_VECCHIO> // etichetta stato lessicale2 SKIP:3 {4 <EspressioneRegolare>: STATO_NUOVO5 }
Trovata la corrispondenza tra EspressioneRegolare e unaporzione dell’input, il token manager passa da STATOVECCHIOa STATONUOVO
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 48 / 75
File di specifica Regole di match del token managerStati lessicali II1 ...2
3 SKIP: // stato di DEFAULT4 { <" ">5 | <"\n">6 | <"\t">7 }8
9 SKIP: // stato di DEFAULT10 {11 <"/*"> : IN_COMMENTO12 }13
14 <IN_COMMENTO>15 SKIP:16 {17 <"*/"> : DEFAULT
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 49 / 75
File di specifica Regole di match del token managerStati lessicali III18 | <~[]>19 }20
21 TOKEN:22 {23 <ELSE: "else">24 | <SEMICOLON: ";">25 | <FOR: "for">26 | <UNSIGNED: (["0"-"9"])+>27 | <IDENTIFIER: ["a"-"z"](["a"-"z","0"-"9"])*>28 }
cosa succede con
1 else /* commento */2 12/* commento */;
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 50 / 75
File di specifica Azioni nel token managerAzioni nel token manager ISi possono associare azioni alle espr. regolari per definire il
funzionamento del token manager.
L’azione viene eseguita in corrispondenza del match con
l’espressione che la precede
Le azioni sono espresse (come anche nella grammatica)
attraverso codice Java tra graffe
Esempio1 TOKEN: {2 ... |3 <UNSIGNED: (["0"-"9"])+>4 { System.out.println("UNSIGNED"); } |5 ...6 }
stampa UNSIGNED ogni volta che si restituisce un token al parser
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 51 / 75
File di specifica Azioni nel token managerAzioni nel token manager IIIl token restituito è disponibile attraverso la variabile
matchedToken che può essere usata anche nelle azioni
Esempio1 TOKEN: {2 ... |3 <UNSIGNED: (["0"-"9"])+>4 { System.out.println ("immagine: " + matchedToken.image);} |5 ...6 }
ogni volta che si trova un tokan UNSIGNED, viene mostrato ilcampo image del tokenAd es. se l’input fosse 123 7645 allora si mostrerebbe:immagine: 123immagine: 7645
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 52 / 75
File di specifica Azioni nel token managerAzioni nel token manager III
Supponendo di voler mostrare l’immagine di ogni token passato
al parser senza aggiungere tante azioni come quella dell’esempio
si mette l’azione nel metodo CommonTokenActionaggiungendolo alla sezione TOKEN_MGR_DECLS e si settaCOMMON_TOKEN_ACTION a true nella sezione optionsIl token manager chiamerà CommonTokenAction passandogli iltoken corrente prima di fornirlo al parser
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 53 / 75
File di specifica Azioni nel token manager
Esempio1 options {2 STATIC = false;3 COMMON_TOKEN_ACTION = true;4 }5
6 PARSER_BEGIN(NomeParser)7 public class NomeParser {8 /* specifica della classe del parser */9 }10
11 /* specifica classi accessorie */12 PARSER_END(NomeParser)13
14 TOKEN_MGR_DECLS: {15 void CommonTokenAction() {16 System.out.println ("immagine: " + matchedToken.image);17 }18 }19
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 54 / 75
File di specifica Azioni nel token manager
20 SKIP: {21 " "22 | "\n"23 | "\r"24 | "\t"25 }26
27 TOKEN: {28 <ASSIGN: "="> |29 <SEMICOLON: ";"> |30 <LPAR: "("> |31 <RPAR: ")"> |32 <MINUS: "-"> |33 <PLUS: "+"> |34 <UNSIGNED: (["0"-"9"])+> |35 <ID: ["A"-"Z","a"-"z"] (["A"-"Z","a"-"z","0"-"9"])*> |36 <ERROR: ~[]>37 }38
39 // sezione della grammatica
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 55 / 75
File di specifica Azioni nel token manager
Data in input
area = 12;il token manager stamperebbe:
1 immagine: area2 immagine: =3 immagine: 124 immagine: ;
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 56 / 75
File di specifica Azioni nel token manager
Esempio rimozione commenti
1 PARSER_BEGIN(RimCommenti)2 public class RimCommenti {3 }4 PARSER_END(RimCommenti)5
6 TOKEN_MGR_DECLS:7 {8 public static int numCommenti = 0;9 }10
11 SKIP:12 {13 <"/*"> : IN_COMMENTO14 }15
16 SKIP:17 {18 <"//" (~["\n"])* "\n" > { numCommenti++;}
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 57 / 75
File di specifica Azioni nel token manager
19 }20
21 <IN_COMMENTO>22 SKIP :23 {24 <"*/"> { numCommenti++; SwitchTo(DEFAULT);}25 // altra maniera per cambiare stato26 }27
28 <IN_COMMENTO>29 SKIP :30 {31 < ~[] >32 }33
34 TOKEN :35 {36 <ANY: ~[]>37 }
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 58 / 75
File di specifica Opzioni & DebugOpzioni
Le opzioni si settano un assegnazione nella sez. options blockoppure sulla linea di comando, ad es.:
javacc -NOSTATIC -COMMON_TOKEN_ACTION Parser.jj
settano STATIC a false e COMMON_TOKEN_ACTION a trueOgni opzione booleana ha il corrispondente opposto con
prefisso NOSTATIC / NOSTATICCOMMON_TOKEN_ACTION ha il val. default false
Se si usano entrambe le modalità di impostazione,
quella su linea di comando prevale sull’assegnazione
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 59 / 75
File di specifica Opzioni & DebugDebug del token managerIl metodo CommonTokenAction() fornisce uno strumento utile aldebug: il trace dei token
mostra l’immagine di ogni token passato al parser per poter
controllare la corretta analisi lessicale
per far sì che il token manager non produca il trace:
ometterla dalla command line (per default è false), osettare COMMON_TOKEN_ACTION a false, oppurespecificare -NOCOMMON_TOKEN_ACTION su command line
In alternativa, JavaCC fornisce info in modo automatico settando
l’opzione DEBUG_TOKEN_MANAGERil token manager generato mostrerà moltissime info sul
processo di analisi lessicale
per il parsing c’è l’analoga opzione DEBUG_PARSER
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 60 / 75
File di specifica Opzioni & Debug
Esempio come il precedente, aggiungendo il main()1 class RimCommenti {2 public static void main(String args[]) {3
4 if (args.length < 1) {5 System.err.print("Nome file mancante!");6 return 1;7 }8
9 // apertura stream file sorgente10 java.io.inputStream in;11 try {12 in = new java.io.FileInputStream(args[0]);13 } catch (java.io.FileNotFoundException e) {14 System.err.println("File" + args[0] +15 "non trovato");16 return 1;17 }18
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 61 / 75
File di specifica Opzioni & Debug
19 RimCommentiTokenMenager tm = new20 RimCommentiTokenMenager(new21 SimpleCharStream(in));22
23 // loop lettura token24 Token t = tm.getNextToken();25 while (t.kind != RimCommentiConstants.EOF) {26 System.out.println(t);27 t = tm.getNextToken();28 }29 // stampa finale30 System.out.println("\n N. commenti rimossi:"31 + tm.numCommenti);32 } // mainstring33 } // class
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 62 / 75
Argomenti AvanzatiSommario
1 JavaCC
Installazione
Nozioni Preliminari
2 Espressioni Regolari Estese
Operatori
Insiemi di Caratteri
Denominazione dei token
3 File di specifica
Sezioni
File prodotti da JavaCC
Regole di match del token
manager
Azioni nel token manager
Opzioni & Debug
4 Argomenti Avanzati
Regole SPECIAL_TOKENRegole MORE
5 Esercizi
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 63 / 75
Argomenti Avanzati Regole SPECIAL_TOKENRegole SPECIAL_TOKEN IL’espressione regolare SPECIAL_TOKEN descrive token speciali chenon hanno significato autonomo
I token speciali sono comunque passati al parser
precisamente vengono passati in congiunzione con i token
normali attraverso il campo specialToken di Tokenil campo punta al token speciale immediatamente precedente
rispetto al token corrente (speciale o normale)
Se il token precedente è normale (non è uno speciale), allora il
campo è nullo.
I token speciali sono utili all’elaborazione di lessemi come icommenti che non hanno significato per il parsing ma sonosignificativi per il file in input
Si può accedere ad ogni token speciali usando azioni nella
specifica lessicale / sintattica
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 64 / 75
Argomenti Avanzati Regole SPECIAL_TOKENRegole SPECIAL_TOKEN IIEsempio1 SPECIAL_TOKEN:2 {3 <B: "b">4 |5 <C: "c">6 }7 TOKEN:8 {9 <D: "d">10 |11 <E: "e">12 }
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 65 / 75
Argomenti Avanzati Regole SPECIAL_TOKENRegole SPECIAL_TOKEN IIISupponiamo di avere in input "dbce":
"d" viene identificato nel blocco TOKENl’oggetto relativo viene restituito al parser
"b" viene identificato come SPECIAL_TOKENsi crea un token "b", ma non lo si restituisce
"c" viene identificato come SPECIAL_TOKENsi crea un nuovo token e il campo specialToken lo concatenaal token speciale precedente
"e" viene identificato come TOKENsi crea un token ("e") e lo si collega al token normaleprecedente ("d") attraverso il campo nextsi collega il token anche al precedente token speciale
attraverso il campo specialTokenil token viene quindi restituito al parser
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 66 / 75
Argomenti Avanzati Regole MORERegole MORE I
A volte è utile costruire gradualmente un token da passare al
parser
La corrispondenza con questo tipo di espressioni regolari
viene salvata in un buffer fino alla corrispondenza con token
normali o speciali
Quindi tutte le corrispondenze nel buffer e i token normali o
speciali finali vengono concatenate per formare un unico
token normale o speciale che viene passato al parser
Se invece si incontra una corrispondenza con una regola di
SKIP il contenuto del buffer viene eliminato
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 67 / 75
Argomenti Avanzati Regole MORERegole MORE IIEsempio1 SKIP :2 {3 "/*" : IN_COMMENTO4 }5
6 <IN_COMMENTO> SKIP :7 {8 "*/" : DEFAULT9 }10
11 <IN_COMMENTO> MORE :12 {13 <~[]>14 }15
16 TOKEN_MGR_DECLS :17 {
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 68 / 75
Argomenti Avanzati Regole MORERegole MORE III18 int lungStringa;19 }20
21 MORE :22 {23 "\"" { lungStringa = 0;} : IN_STRINGA24 }25
26 <IN_STRINGA> TOKEN :27 {28 <STRLIT: "\"">29 {System.out.println("|S| = " + lungStringa);} : DEFAULT30 }31
32 <IN_STRINGA> MORE :33 {34 <~["\n","\r"]> {lungStringa++;}35 }
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 69 / 75
Argomenti Avanzati Regole MORERegole MORE IVEsempio stringhe con escape di doppi apici e backslash
1 SKIP:2 {3 ...4 }5
6 MORE :7 {8 "\"" : IN_STRINGA9 }10
11 TOKEN:12 {13 ...14 }15
16 <IN_STRINGA> MORE :17 {
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 70 / 75
Argomenti Avanzati Regole MORERegole MORE V18 "\\\"" // backslash e doppi apici19 | "\\\\" // backslash due volte20 | <~["\"","\n","\r"]> // tutto tranne " \n e \r21 }22
23 <IN_STRINGA> TOKEN:24 {25 <STRINGA: "\"" > : DEFAULT // apici a fine stringa26 }27
28 <*>29 TOKEN:30 {31 <ERROR: "~[]"> // tutti gli altri casi32 }
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 71 / 75
EserciziSommario
1 JavaCC
Installazione
Nozioni Preliminari
2 Espressioni Regolari Estese
Operatori
Insiemi di Caratteri
Denominazione dei token
3 File di specifica
Sezioni
File prodotti da JavaCC
Regole di match del token
manager
Azioni nel token manager
Opzioni & Debug
4 Argomenti Avanzati
Regole SPECIAL_TOKENRegole MORE
5 Esercizi
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 72 / 75
EserciziEsercizi I1 Scrivere le espressioni regolari per il riconoscimento di
costanti intere in base ottale (prefisso O), decimale (senzaprefisso), esadecimale (prefisso ox).Oltre al riconoscimento (per le non decimali) si può stampare
il valore. [dal Galles]
2 Come il precedente ma usando suffissi del tipo x<base> con<base> carattere tra 0 e 9 o tra A e Z.Se la <base> è vuota il numero è decimale.
Es. 101x2 (binario) rappresenta il 5 in base decimale.[dal Galles]
3 Scrivere le specifiche di un riconoscitore di numeri interi in
cifre arabe che stampi/converta i numeri corrispondenti in
cifre romane. [dal Galles]
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 73 / 75
EserciziEsercizi II
4 Scrivere le specifiche di un riconoscitore di date gg/mm/aache le stampi/converta nel formato gg/mm/aaaacon: aa< 50→ 19aa e aa≥ 50→ 20aa. [dal Galles]
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 74 / 75
RiferimentiRiferimenti
D. Galles: Modern Compiler Design. Scott/Jones PublishingA.J. Dos Reis: Compiler Construction Using Java, JavaCC, andYacc, Wiley-IEEE Computer Society PressT. S. Norvell. Java TutorialN. Fanizzi: Manualetto JavaCC
N. Fanizzi Linguaggi di prog.+Lab javacc – Analisi Lessicale 10 aprile 2014 75 / 75