/* Riconoscitore a discesa ricorsiva per le espressioni aritmetiche. Nel caso si incontri un errore viene sollevata un'eccezione. Sarebbe piu' elegante scrivere il riconoscitore in modo che i metodi corrispondenti ai nonterminali restituiscano un boolean, anziche' sollevare eccezioni. Tuttavia, l'uso delle eccezioni facilita poi la modifica del codice in modo che, oltre a verificare la correttezza sintattica, venga anche calcolato il risultato. Autore: Giovanni Pighizzini - Maggio 2015 */ import lt.calc.*; import java.io.*; import static lt.calc.TipoToken.*; //importazione delle costanti //permette di evitare di specificare il nome della classe TipoToken //davanti ai nomi delle costanti come PIU, MENO, ecc. class Riconoscitore { private static Token t; //variabile destinata a contenere il riferimento //al prossimo token da esaminare private static Scanner scanner; //riferimento all'analizzatore lessicale public static void main(String[] args) throws IOException { //creazione del canale di input BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); //lettura della stringa da esaminare System.out.print("Espressione? "); String s = in.readLine(); //creazione dell'analizzatore lessicale: la stringa riferita da s //e' vista come stream di input scanner = new Scanner(new StringReader(s)); //preleva il primo token t = scanner.getNext(); try { espressione(); //alla fine dell'espressione i token dovrebbero essere finiti if (t.getTipo() == EOF) System.out.println("L'espressione e' costruita correttamente"); else throw new EspressioneException("Stringa non aspettata: " + scanner.yytext()); } catch (EspressioneException e) { System.err.println(e.toString()); } } private static void espressione() throws IOException { termine(); while (t.getTipo() == PIU || t.getTipo() == MENO) { t = scanner.getNext(); termine(); } } private static void termine() throws IOException { fattore(); while (t.getTipo() == PER || t.getTipo() == DIVISO) { t = scanner.getNext(); fattore(); } } private static void fattore() throws IOException { while (t.getTipo() == MENO || t.getTipo() == PIU) t = scanner.getNext(); if (t.getTipo() == NUMERO) t = scanner.getNext(); else if (t.getTipo() == IDENT) t = scanner.getNext(); else if (t.getTipo() == TONDA_APERTA) { t = scanner.getNext(); espressione(); if (t.getTipo() == TONDA_CHIUSA) t = scanner.getNext(); else throw new EspressioneException("Parentesi chiusa attesa"); } else throw new EspressioneException("Stringa non aspettata: " + scanner.yytext()); } }