75
javacc Analisi Lessicale Nicola Fanizzi Corso di Linguaggi di Programmazione Dipartimento di Informatica Università degli Studi di Bari 10 aprile 2014

javacc Analisi Lessicale - LACAM

  • 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