/* Riconoscitore ricorsivo discendente 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 */ import lt2.calc.Scanner; import lt2.calc.Token; import static lt2.calc.TipoToken.*; //importazione delle costanti //permette di evitare di specificare il nome della classe TipoToken //davanti ai nomi delle costanti come PIU, MENO, ecc. import java.io.*; public class ParserEspressioni { 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 file di input scanner = new Scanner(new StringReader(s)); //preleva il primo token t = scanner.getProssimo(); try { espressione(); //alla fine dell'espressione i token dovrebbero essere finiti if (t.getTipo() == FINE) 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()); } } public static void espressione() throws IOException { termine(); while ((t.getTipo() == PIU) || (t.getTipo() == MENO)) { t = scanner.getProssimo(); termine(); } } public static void termine() throws IOException { fattore(); while ((t.getTipo() == PER) || (t.getTipo() == DIVISO)) { t = scanner.getProssimo(); fattore(); } } public static void fattore() throws IOException { while (t.getTipo() == MENO) t = scanner.getProssimo(); if (t.getTipo() == NUMERO) t = scanner.getProssimo(); else if (t.getTipo() == TONDA_APERTA) { t = scanner.getProssimo(); espressione(); if (t.getTipo() == TONDA_CHIUSA) t = scanner.getProssimo(); else throw new EspressioneException("Parentesi chiusa attesa"); } else throw new EspressioneException("Stringa non aspettata: " + scanner.yytext()); } } class EspressioneException extends RuntimeException { public EspressioneException(String m) { super(m); } }