
Probabilmente l'analisi delle espressioni aritmetiche consiste nello stamparle con un numero minimo di parentesi. Di solito non è un'operazione univoca, dipende spesso da chi è responsabile dell'inserimento delle parentesi. Oltre al nome dell'operatore usato per l'output in notazione postfissa, dobbiamo aggiungere due numeri alla struct Type:
struct Type { const char * name; /* node’s name */ char rank, rpar; void * (* new) (va_list ap); void (* exec) (const void * tree, int rank, int par); void (* delete) (void * tree); };
.rank gestisce la precedenza fra gli operatori, a partire da 1 per l'addizione. .rpar è impostato per operatori come la sottrazione, la quale richiede che l'operatore destro venga incluso fra parentesi se usa un operatore di pari livello di precedenza. Come esempio consideriamo
$ infix 1 + (2 — 3) 1 + 2 — 3 1 — (2 — 3) 1 — (2 — 3)
Ciò dimostra che abbiamo proceduto ad effettuare la seguente inizializzazione.
static struct Type _Add = {"+", 1, 0, mkBin, doBin, freeBin}; static struct Type _Sub = {"—", 1, 1, mkBin, doBin, freeBin};
La parte più complessa risiede nel nodo binario per decidere se deve essere attorniato da parentesi. Ad Un nodo binario come un'addizione viene data la precedenza del suo superiore ed è necessario un flag che indica se le parentesi sono indispensabili quando vi è uguale precedenza. doBin() decide se usare le parentesi
static void doBin (const void * tree, int rank, int par) { const struct Type * type = * (struct Type **) tree; par = type —> rank < rank || (par && type —> rank == rank); if (par) putchar(’(’);
Se il nostro nodo avesse minor precedenza che il suo superiore, o se chiedessimo di forzare l'uso di parentesi in caso di pari precedenza, stamperemmo le parentesi. In ogni caso, se la nostra descrizione ha impostato .rpar, ecco quello che va codificato:
exec(((struct Bin *) tree) —> left, type —> rank, 0); printf(" %s ", type —> name); exec(((struct Bin *) tree) —> right, type —> rank, type —> rpar); if (par) putchar(’)’); }
Le routine di stampa rimanenti sono significativamente più semplici da scrivere.
Sommario
Tre diversi processori mostrano i vantaggi insiti nell'information hiding. Il dynamic linkage ci ha aiutato a dividere i problemi in molte funzioni molto semplici. I programmi risultati si possono facilmente estendere - provate ad esempio aggiungere confronti e un operatore come ? in C.
