/** file: Exp.java - Espressioni (con assegnamento) in java */
/**
Interprete del linguaggio generato dalla grammatica:
Exp ::= Exp + Term | Term (PiuExp)
Exp ::= Exp - Term | Term (MenExp)
Term ::= Term * Factor | Factor (PerExp)
Term ::= Term / Factor | Factor (DivExp)
Factor::= Num (NumExp)
Factor::= Ident (IdentExp)
Factor::= ( Exp ) (NumExp)
Factor::= sqr Factor (SqrExp)
Factor::= sqrt Factor (SqrtExp)
Factor::= inv Factor (InvExp)
Exp ::= Assign (AssignExp)
Assign::= Ident = Exp
Gerarchia delle Classi: ([x]=classe astratta)
[Exp]
+---[OpExp]
| +-----PiuExp
| +-----MenExp
| +-----PerExp
| +-----DivExp
| +-----AssignExp
+---[UnExp]
| +-----SqrExp
| +-----SqrtExp
| +-----InvExp
+----NumExp
+----IdentExp
+-----IdentRefExp
*/
/** ====================================
CLASSI per la GERARCHIA DI "EXP"
==================================== */
/** "EXP" e' la classe astratta da cui vengono specializzate le
sottoclassi di operatori, numeri e identificatori. */
abstract class Exp {
/** Accetta un Visitor (puo' generare un'eccezione) */
public abstract void accept(ExpVisitor v) throws Exception;
} //Exp(astratta)
/** "OpExp" e' la classe astratta (che eredita da "Exp") che serve
da "modello" per tutti gli operatori BINARI */
abstract class OpExp extends Exp {
/** "left" e "right" servono per puntare ai due operandi dell'
operazione contenuta in "OpExp" (nell'istanza di una delle
sue sottoclassi).
Grazie al collegamento-ritardato (late-binding) queste due
variabili sono definite come "Exp" ma possono essere
assegnate a un'istanza di qualsivoglia sottoclasse di "Exp".*/
Exp left,
right;
/** Il costruttore salva in "left" e "right" i riferimenti
agli oggetti "Exp" passati (che rappresentano gli operandi).*/
public OpExp (Exp l, Exp r) {
left=l;
right=r; // SALVA puntat.a oggetti sottostanti
}
/** Accetta un "visitor". Viene definita nelle sottoclassi. */
public abstract void accept (ExpVisitor v);
/** Rende l'oggetto (operando) di "sinistra" */
public Exp left() { return left; }
/** Rende l'oggetto (operando) di "destra" */
public Exp right() { return right; }
/** Rende l'operazione dell'oggetto */
public String op() { return myOp(); }
/** Rende una stringa rappresentante l'operatore
(viene definita nelle sottoclassi). */
protected abstract String myOp ();
/** Rende una rappresentazione in stringa dell'oggetto */
public String toString() {
return left.toString() + myOp() + right.toString();
}
} //OpExp/** Classe per l'operazione di SOMMA */
class PiuExp extends OpExp { // operazione +
public PiuExp (Exp l, Exp r) { super(l,r); }
public String myOp () { return "+"; }
public void accept (ExpVisitor v) { v.VisitaPiuExp(this); }
}
/** Classe per l'operazione di MOLTIPLICAZIONE */
class PerExp extends OpExp { // operazione *
public PerExp (Exp l, Exp r) { super (l,r); }
public String myOp () { return "*"; }
public void accept (ExpVisitor v) { v.VisitaPerExp(this); }
}
/** Classe per l'operazione di SOTTRAZIONE */
class MenExp extends OpExp { // operazione -
public MenExp (Exp l, Exp r) { super (l,r); }
public String myOp () { return "-"; }
public void accept (ExpVisitor v) { v.VisitaMenExp(this); }
}
/** Classe per l'operazione di DIVISIONE */
class DivExp extends OpExp { // operazione /
public DivExp (Exp l, Exp r) { super(l,r); }
public String myOp () { return "/"; }
public void accept (ExpVisitor v) { v.VisitaDivExp(this); }
}
/** "UnExp" e' la classe astratta (che eredita da "Exp") che serve
da "modello" per tutti gli operatori UNARI */
abstract class UnExp extends Exp {
/** "ahead" serve per puntare all'unico operando dell'operazione
contenuta in "UnExp" (nell'istanza di una delle sue
sottoclassi). */
Exp ahead;
public UnExp (Exp a) {
ahead=a; // SALVA puntat.a oggetto sottostante
}
/** Accetta un "visitor". Viene definita nelle sottoclassi. */
public abstract void accept (ExpVisitor v);
/** Rende l'oggetto (operando) puntato */
public Exp ahead() { return ahead; }
/** Rende l'operazione dell'oggetto */
public String op() { return myOp(); }
/** Rende una stringa rappresentante l'operatore
(viene definita nelle sottoclassi). */
protected abstract String myOp ();
/** Rende una rappresentazione in stringa dell'oggetto */
public String toString() {
return myOp() + ahead.toString();
}
} //UnExp
/** Classe per l'operazione di QUADRATO */
class SqrExp extends UnExp { // operazione sqr
public SqrExp (Exp a) { super(a); }
public String myOp () { return "sqr"; }
public void accept (ExpVisitor v) { v.VisitaSqrExp(this); }
}
/** Classe per l'operazione di RADICE QUADRATA */
class SqrtExp extends UnExp { // operazione sqrt
public SqrtExp (Exp a) { super(a); }
public String myOp () { return "sqrt"; }
public void accept (ExpVisitor v) { v.VisitaSqrtExp(this);}
}
/** Classe per l'operazione di INVERSO */
class InvExp extends UnExp { // operazione inv
public InvExp (Exp a) { super(a); }
public String myOp () { return "inv"; }
public void accept (ExpVisitor v) { v.VisitaInvExp(this); }
}
/** Classe per memorizzare un NUMERO (double).
"NumExp" e' una sottoclasse di "Exp". */
class NumExp extends Exp { // un numero (intero)
/** "val" serve per mantenere memorizzato il proprio valore */
protected double MioVal;
public NumExp (double v) { MioVal = v; }
/** Rende il valore dell'oggetto */
public double Val () { return MioVal; }
/** Stampa il valore (senza eventuale ".0") */
public String toString () { // toglie il ".0" se c'e'
if (MioVal != Math.floor(MioVal)) // floor=approssima per difetto
return MioVal+"";
else {
int IVal = (new Double(MioVal)).intValue();
return IVal+"";
}
}
public void accept(ExpVisitor v) { v.VisitaNumExp(this); }
}
/** Classe per l'operazione di ASSEGNAZIONE */
class AssignExp extends OpExp { // Assegnazione
public AssignExp (Exp l, Exp r) { super (l,r); }
public String myOp () { return "="; }
public void accept (ExpVisitor v) { v.VisitaAssignExp(this);}
}
/** Classe per memorizzare un IDENTIFICATORE */
class IdentExp extends Exp {
/** Stringa per memorizzare il nome dell'indentificatore */
protected String MioIDStr;
public IdentExp (String v) { MioIDStr = v; }
public String Val () { return MioIDStr; }
public String toString () { return MioIDStr; }
public void accept (ExpVisitor v) throws Exception
{ v.VisitaIdentExp(this); }
}
/** Classe per memorizzare il VALORE di un IDENTIFICATORE */
class IdentRefExp extends IdentExp {
public IdentRefExp (String v) { super(v); }
public void accept (ExpVisitor v) throws Exception
{ v.VisitaIdentRefExp(this);}
}
//*FINE FILE*