140 likes | 375 Views
Renzi Alberto. ANTLR V.3. www.antlr.org. ANTLR. Strumento automatico che permette di generare parser ricorsivi discendenti usando LL(*) (un estensione dell’LL(k) che usa un lookahead arbitrario per prendere decisioni)
E N D
Renzi Alberto ANTLR V.3 www.antlr.org
ANTLR • Strumento automatico che permette di generare parser ricorsivi discendenti usando LL(*) (un estensione dell’LL(k) che usa un lookahead arbitrario per prendere decisioni) • Sviluppato in Java permette di generare codice in Java, C#, Python, Ruby, Ce C++. • Mette a disposizioneunostrumentograficodisviluppochiamato ANTLR-Works con ilquale è possibileanchedebuggare I parser generati. • Supportagrammatiche EBNF e la generazionedialberi.
ANTLR • Questo strumento può produrre in automatico il codice relativo a: • Lexer: parte lessicale dove si definiscono i token e i separatori da ignorare • Parser: parte grammaticale contenente le regole di produzione • TreeParser: un parser che riconosce un albero • Ognuno di questi oggetti può contenere azioni semantiche
ANTLR: schema di funzionamento Fasi: • Il lexer prepara i token da passare al parser • Il parser accetta uno stream dei token preparati dal lexer e cerca di riconoscere la struttura della frase. Se non vengono prodotti AST può semplicemente eseguire azioni in accordo al significato della frase. In alternativa può produrre un albero da passare ad un TreeParser • TreeParser: è un parser che accetta un AST che se richiesto viene prodotto dal parser previa descrizione nella grammatica del parser.
ANTLR: relazione tra caratteri, token e AST ANTLR al posto di creare un oggetti stringa per ogni token crea token contenenti i riferimenti che permettono di recuperare il valore del token. Per l’AST (nella versione base “CommonTree” fornita con ANTLR) i nodi possono semplicemente puntare al token dal quale sono stati creati.
ANTLR: sintassi lexer Sezioni importanti: • Dichiarazione del nome della classe che deve perforza coincidere con il nome della grammatica del lexer (in questo caso NostroLexer.g dovrà essere il nome del file che specifica la grammatica del lexer e NostroLexer.java sarà la classe generata) lexer grammar NostroLexer; • Nella sezione degli options possiamo indicare il linguaggio di output , in questo caso Java options { language=Java; } • Nella sezione @Header possiamo indicare il package e gli import necessari @header { package miopackage; import java.util.*; } • Nella sezione @members possiamo specificare metodi e variabili che saranno disponibili nella classe “NostroLexer.java” @members { public void metodo() { ..... } }
ANTLR: sintassi lexer • Successivamente è possibile elencare i token INT: ('0'..'9')+ ; PLUS: '+' ; COMMENT: '//'(~('\r'|'\n'))+ {skip();}; • E i separatori da ignorare: WS : ( ' ' | '\t' | '\r' | '\n' )+ {skip();} ;
ANTLR: Parser Sezioni importanti: • Come per il lexer il file della grammatica deve incominciare con la dichiarazione del nome del parser: parser grammar NostroParser; • Nella sezione degli options possiamo indicare il linguaggio di output, il vocabolario dei token da utilizzare, il K della grammatica e se il parser dovrà generare l’AST options { tokenVocab = CalendarLexer; language=Java; k=1; output = AST; } • Nella sezione @Header possiamo indicare il package e gli import necessari @header { package miopackage; import java.util.*; } • Nella sezione @members possiamo specificare metodi e variabili che saranno disponibili nella classe “NostroParser.java” @members { public void metodo() { ..... } }
ANTLR: Parser • Nella sezione @rulecatch possiamo indicare una strategia personalizzata in caso di errore durante il riconoscimento di una regola @rulecatch { catch (RecognitionException ex) { …. } } • Elenco delleproduzionidellagrammatica (metasimboli in minuscolo, Token in maiuscolo): expr: expr PLUS term | term ; term: term TIMES factor | factor ; factor: INT ;
Azioni Semantiche Metasimbolo: {operazioni preliminari} : lato destro della produzione {azioni semantiche} ; Esempio exprreturns [int res] {//Eventuali inizializzazioni} : a:expr PLUS b:term{$res = $a+$b;} | c:term {$res = $c} ; E’ anche possibile associare azioni semantiche per ogni simbolo che si incontra nella parte destra exprreturns [int res] {//Eventuali inizializzazioni} : a:expr {$res=$res+$a; } PLUS b:term {$res = $res+$b;} | c:term {$res = $c;} ; Inoltre per accedere al payload di un token richiamando la proprietà “.text”. termreturns [int res] : INT {$res = $INT.text;} ;
ANTRL: TREE • ANTLR dalla versione 3 da la possibilità di creare alberi omogenei e eterogenei. • Per gli alberi omogenei fornisce un implementazione di base chiamata CommonTree con il relativo CommonTreeAdaptor che funge sia da Factory che da Adaptor allo stesso tempo. • Per gli alberi eterogenei è necessario implementare l’interfaccia TreeAdaptor che da la possibilità ad antlr di poter creare e navigare l’albero senza conoscerne l’implementazione.
ANTLR: Generazione dell’AST • Il tipo di AST generato dal parser avviene indicando per ogni regola il tipo di albero generato. Ciò e possibile specificarlo in due modi all’interno della grammatica del parser: • Tramite i simboli ^ e !: • Con ^: si indica quale token farà da radice • Con !: possiamo indicare i token che non andranno a far parte dell’albero • Es la regola width: WIDTH^ DUEP! INT SEMICOLON! ; genera un albero con WIDTH come radice e un solo figlio INT perchè è l’unico senza !. • Tramite una riscrittura indicata con “->” al termine della produzione: width: WIDTH DUEP INT SEMICOLON -> ^(WIDTH INT); dopo la “->” si aspetta che si elenchino radice e figli dell’albero ^( radice figlio1 figlio2 ....)
ANTLR: TreeParser • La specifica del TreeParser avviene in modo analogo alla specifica del lexer e del parser con le sezioni “options” “@header” “@members” ecc.. • Mentre per le regole della grammatica che descrivono l’albero si possono “estrarre” dopo aver eseguito un copia e incolla delle regole del parser semplicemente cancellando le regole sintattiche e lasciando solo le riscritture che descrivono l’AST: Es. Width: WIDTH^ INT; //Per il primo tipo Width: ^(WIDTH INT); //Per il secondo tipo
Bibbliografia • Antlr site: www.antlr.org • The Definitive ANTLR Reference, Terence Parr.