// File di specifica JavaCup per un valutatore di espressioni import java_cup.runtime.*; init with {: System.out.println("Inserire l'espressione da calcolare " + "seguita da " + "( per terminare) "); :}; /* Simboli terminali (token restituiti dallo scanner). */ terminal PIU, MENO, PER, DIVISO; terminal UNARIO, TONDA_APERTA, TONDA_CHIUSA, FINE_EXPR; terminal Integer NUMERO; /* Non terminali */ non terminal Integer expr; non terminal espressione, listaEspressioni; /* Precedenze e associativita' */ precedence left PIU, MENO; precedence left PER, DIVISO; precedence left UNARIO; /* Simbolo iniziale */ start with listaEspressioni; /* Produzioni */ listaEspressioni ::= listaEspressioni espressione | ; espressione ::= expr:e {: System.out.println("Risultato = " + e.intValue()); System.out.println("Inserire l'espressione da calcolare " + "seguita da " + "( per terminare) "); :} FINE_EXPR /* Si noti che l'azione semantica e' scritta prima del token FINE_EXPR. Questo evita che il token FINE_EXPR sia "consumato" prima di svolgere l'azione semantica o, in altre parole, che il parser vada a leggere il token successivo prima di compiere l'azione (che provocherebbe l'attesa di nuovo input fornito dall'utente, cioe' di una nuova espressioni, prima che vengano forniti i messaggio delle due istruzion println). Si consiglia di sperimentare questo comportamento spostando l'azione semantica alla fine della produzione. */ ; expr ::= expr:e1 PIU expr:e2 {: RESULT = new Integer(e1.intValue() + e2.intValue()); :} | expr:e1 MENO expr:e2 {: RESULT = new Integer(e1.intValue() - e2.intValue()); :} | expr:e1 PER expr:e2 {: RESULT = new Integer(e1.intValue() * e2.intValue()); :} | expr:e1 DIVISO expr:e2 {: RESULT = new Integer(e1.intValue() / e2.intValue()); :} | NUMERO:n {: RESULT = n; :} | MENO expr:e {: RESULT = new Integer(0 - e.intValue()); :} %prec UNARIO | PIU expr:e {: RESULT = e; :} %prec UNARIO | TONDA_APERTA expr:e TONDA_CHIUSA {: RESULT = e; :} ;