L'AST è un ponte tra la sintassi concreta e il modello semantico della tua lingua. Non deve conformarsi esattamente alla sintassi. In particolare, è generalmente OK se l'AST potrebbe teoricamente rappresentare strutture che non possono essere renderizzate nella sintassi. (In particolare, il linguaggio di markup di ReStructured Text è definito in termini di un modello di oggetto documento che è sostanzialmente più espressivo della sintassi effettiva.)
Pertanto, è possibile introdurre un nodo AST di istruzione-espressione, anche se la sintassi limita questa espressione a essere una chiamata. Questo è sensato se le chiamate di istruzioni e le chiamate di espressioni non devono essere trattate in modo diverso nella tua lingua.
Un esempio in cui le istruzioni e le espressioni devono essere trattate in modo diverso è una definizione di funzione in JavaScript. Approssimativamente, l'istruzione function foo() {}
dichiara una variabile foo
che contiene un oggetto funzione. La stessa definizione in un'espressione non introdurrà una variabile nell'ambito di inclusione e valuterà tale oggetto funzione.
Potrebbe quindi essere ragionevole rappresentarlo utilizzando diversi tipi, ad es. FunctionExpression
contro FunctionStatement
. Questo non deve comportare un'eccessiva duplicazione! Per esempio. la variante dell'istruzione potrebbe contenere un oggetto FunctionExpression
. In alternativa, l'istruzione della funzione potrebbe essere immediatamente desugared in AST a qualcosa come Assign(Var("foo"), Function(...))
in cui il nodo Function
AST deve solo modellare la variante di espressione.
Quindi nel tuo caso, l'introduzione di un nodo AST CallStatement
che contiene solo il nodo AST di espressione Call
potrebbe essere un approccio praticabile.
Nota che la sicurezza del tipo è relativa, comunque. Utilizzando l'ereditarietà per modellare i nodi AST, il sistema dei tipi consente nuovi tipi di nodi AST arbitrari purché conformi ad alcune interfacce. Per esempio. sarebbe possibile creare un sottotipo di espressione che funge da adattatore per qualsiasi dichiarazione, anche se ciò sembra avere poco senso nel modello. Se hai bisogno di garanzie più severe, dovrai evitare l'ereditarietà aperta e usare una lingua con tipi di tipi di somma più limitati.