www.pudn.com > ANSI_C_OOP.rar > infix.c
#include#include #include #include #include "parse.h" #include "value.h" /* * infix driver */ 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); }; void * new (const void * type, ...) { va_list ap; void * result; assert(type && ((struct Type *) type) -> new); va_start(ap, type); result = ((struct Type *) type) -> new(ap); * (const struct Type **) result = type; va_end(ap); return result; } static void exec (const void * tree, int rank, int par) { assert(tree && * (struct Type **) tree && (* (struct Type **) tree) -> exec); (* (struct Type **) tree) -> exec(tree, rank, par); } void process (const void * tree) { putchar('\t'); exec(tree, (* (struct Type **) tree) -> rank, 0); putchar('\n'); } void delete (void * tree) { assert(tree && * (struct Type **) tree && (* (struct Type **) tree) -> delete); (* (struct Type **) tree) -> delete(tree); } /* * NUMBER */ struct Val { const void * type; double value; }; static void * mkVal (va_list ap) { struct Val * node = malloc(sizeof(struct Val)); assert(node); node -> value = va_arg(ap, double); return node; } static void doVal (const void * tree, int rank, int par) { printf("%g", ((struct Val *) tree) -> value); } /* * unary operators */ struct Un { const void * type; void * arg; }; static void * mkUn (va_list ap) { struct Un * node = malloc(sizeof(struct Un)); assert(node); node -> arg = va_arg(ap, void *); return node; } static void doUn (const void * tree, int rank, int par) { const struct Type * type = * (struct Type **) tree; printf("%s ", type -> name); exec(((struct Un *) tree) -> arg, type -> rank, 0); } static void freeUn (void * tree) { delete(((struct Un *) tree) -> arg); free(tree); } /* * binary operators */ struct Bin { const void * type; void * left, * right; }; static void * mkBin (va_list ap) { struct Bin * node = malloc(sizeof(struct Bin)); assert(node); node -> left = va_arg(ap, void *); node -> right = va_arg(ap, void *); return node; } 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('('); exec(((struct Bin *) tree) -> left, type -> rank, 0); printf(" %s ", type -> name); exec(((struct Bin *) tree) -> right, type -> rank, type -> rpar); if (par) putchar(')'); } static void freeBin (void * tree) { delete(((struct Bin *) tree) -> left); delete(((struct Bin *) tree) -> right); free(tree); } /* * Types */ static struct Type _Add = {"+", 1, 0, mkBin, doBin, freeBin}; static struct Type _Sub = {"-", 1, 1, mkBin, doBin, freeBin}; static struct Type _Mult = { "*", 2, 0, mkBin, doBin, freeBin }; static struct Type _Div = { "/", 2, 1, mkBin, doBin, freeBin }; static struct Type _Minus = { "-", 3, 0, mkUn, doUn, freeUn }; static struct Type _Value = { "", 4, 0, mkVal, doVal, free }; const void * Add = & _Add; const void * Sub = & _Sub; const void * Mult = & _Mult; const void * Div = & _Div; const void * Minus = & _Minus; const void * Value = & _Value;