Stai lavorando con ciò che potremmo chiamare un Abstract Syntax Tree .
Lo scopo dell'albero è catturare un'espressione. Esistono altri modi per catturare espressioni, come il testo. Un modulo di testo è una serializzazione . In alcune serializzazioni di espressioni (ad es. infix ), dobbiamo usare la parentesi - () per sovrascrivere la precedenza degli operatori ; tuttavia, in un AST, la precedenza dell'operatore è esplicita nella forma dell'albero, quindi nessuna parentesi è necessaria.
Catturiamo le espressioni come alberi per una serie di motivi. Nella tecnologia del compilatore, le espressioni sono spesso rappresentate come alberi in qualche punto del processo di traduzione (ad esempio parse output). Il compito del compilatore è di tradurre l'espressione in un modulo (di solito di livello inferiore, come codice byte o codice macchina) per l'esecuzione successiva (o ulteriore traduzione per l'esecuzione successiva).
Tale albero potrebbe anche essere valutato invece di tradotto; questo potrebbe accadere, per esempio, in un interprete. In un interprete, in genere, la valutazione di un albero di espressione del genere si verifica dopo la costruzione dell'albero; questo perché l'interprete può scegliere di analizzare l'espressione (albero) prima della valutazione, e / o, perché l'interprete vuole essere in grado di valutare l'espressione più di una volta - ogni volta con valori potenzialmente diversi per le variabili, quindi la stessa espressione può produrre un risultato finale diverso se le variabili vengono aggiornate.
Nel tuo caso in quanto non ci sono variabili (solo costanti), non c'è (ovvio) vantaggio nel ritardare l'esecuzione - quindi potrebbe essere tentato di prendere in considerazione l'esecuzione come parte della costruzione. Ciò implicherebbe avere un risultato o un valore per tutte le entità prima della costruzione, e quindi potresti fornire, nella classe base astratta, un costruttore che riceve il valore e un campo che contiene il valore; tuttavia, come si nota, ciò richiede che anche CompoundExpression
e AdditionExpression
vengano costruiti in termini di valori, e questo sarebbe un compito diverso.
Secondo il testo dei tuoi requisiti, (1) devi fornire un metodo calculate()
per la valutazione (post-costruzione) dell'espressione, e (2) devi fornire un costruttore per AdditionExpression
che prende il due% diExpression
se nessun valore !!
Il tuo compito è supportare la costruzione di alberi per una valutazione successiva, non per costruire un albero e contemporaneamente calcolare il suo valore finale. Quindi, separa questi concetti nella tua mente: la costruzione dell'albero dalla valutazione dell'albero. La valutazione verrà effettuata dopo la costruzione.
If I were to forgo a constructor in Expression then I can't really override equals in Expression because I need to be able to make comparison based on some field.
Per ripetermi, stai confondendo la costruzione con la valutazione. Nel modello di tali requisiti, la costruzione avviene prima e la valutazione viene posticipata fino al completamento della costruzione.
L'override di equals(...)
verrà eseguito solo nell'ambiente post-costruzione. Nessuno chiamerà equals
durante la costruzione dell'albero, eh?
Quindi, nel tuo equals
override puoi presumere che gli alberi siano completamente costruiti! Alberi completamente costruiti supportano l'interfaccia fornita dalla classe astratta Expression
- possono essere valutati per ottenere il loro valore!