Progettazione delle classi di nodo derivate da albero della sintassi

0

Diciamo che ho una classe Node astratta e una classe% co_de derivata da BinaryOperation e tre classi Node , IntegerConstant e RealConstant derivate anche da CharacterConstant .

Il design generale per la classe Node sarebbe simile a questo:

public class BinaryOperation : Node
{
    public Node Operand1 { get; private set; }
    public Node Operand2 { get; private set; }
    //...
}

Ho anche metodi di analisi per quelle classi, ognuna delle quali restituisce un determinato tipo. Quindi BinaryOperation è di tipo IsIntegerConstant() e così via.

Ora, quando analizzo un operando in espressione, posso facilmente controllare il tipo in questo modo:

Node operand1 = IsIntegerConstant() ??
                IsRealConstant() ??
                IsCharacterConstant();

Tuttavia C # non lo consente . Perché il compilatore non può determinare il tipo di espressione in IntegerConstant assegnazione. Cosa dovrei fare? Devo fare in modo che tutti i metodi di analisi restituiscano il tipo operand1 o il cast di ciascun metodo in Node . O forse creare membri di classe Node separati per ciascun tipo di operando?

    
posta 107MP 29.08.2017 - 21:48
fonte

1 risposta

2

What should I do? Should I make all of the parsing methods return type Node or cast each method to Node.

Suggerirei di aggiungere, per usare qui nel tuo esempio, un wrapper di analisi dell'operando più generico che restituisce Node la cui implementazione determina internamente il tipo dell'operando che forse usa tale cascata.

Or maybe create separate BinaryOperation class members for each of the operand types?

No, non farlo! Mi sembra un'esplosione di classe. Avresti bisogno di una sottoclasse per ogni sottoclasse di operandi a sinistra X una sottoclasse per ogni sottoclasse di operando a destra - una matrice intera di classi, per quello che posso vedere solo come valore da nulla a zero.

Che cosa fai se tutto ciò che include l'ultima IsCharacterConstant() fallisce? Sembra che operand1 diventi nullo in quel caso, ignorando l'input dell'analisi, piuttosto che ottenere qualche errore utile. Potresti provare:

Node operand1 = IsIntegerConstant() ??
                IsRealConstant() ??
                IsCharacterConstant() ??
                ReportError("... this operator must have a constant left operand ...");

dove ReportError ha dichiarato il tipo di ritorno del nodo, soddisfacendo in tal modo l'algoritmo di inferenza del C #.

Non ho familiarità con questa tecnica di analisi; sembra molto specifico, stai pensando che supporterà le tue esigenze a lungo termine? Non supportate le parentesi o le operazioni binarie nidificate?

Chiedo perché la questione della uguaglianza dell'inferenza di tipo diventa discutibile se è comunque necessario un metodo di analisi più generale, poiché un metodo più generale potrebbe analizzare un operando a Node , rendendo questo collegamento a cascata non così ampiamente visibile attraverso il codice base , se non lo elimini.

    
risposta data 29.08.2017 - 23:23
fonte

Leggi altre domande sui tag