The website "dmilvdv.narod.ru." is not registered with uCoz.
If you are absolutely sure your website must be here,
please contact our Support Team.
If you were searching for something on the Internet and ended up here, try again:

About uCoz web-service

Community

Legal information

3.7 Постфиксная запись

3.7 Постфиксная запись

Предыдущая  Содержание  Следующая V*D*V

До сих пор мы не решили, что на самом деле собирается делать process(). Если бы мы пожелали эмиттировать постфиксную версию выражения, то добавили бы строку символов в struct Type, чтобы показать фактический оператор, а process() организовала бы вывод в одну строку с отступами с помощью символа табуляции:

 

void process (const void * tree)

{

    putchar(’\t’);

    exec(tree);

    putchar(’\n’);

}

 

динамическую компоновку обрабатывает exec():

 

static void exec (const void * tree)

{

    assert(tree && * (struct Type **) tree

        && (* (struct Type **) tree) —> exec);

 

    (* (struct Type **) tree) —> exec(tree);

}

 

и каждый бинарный оператор эмиттируется с помощью следующей функции:

 

static void doBin (const void * tree)

{

    exec(((struct Bin *) tree) -> left);

    exec(((struct Bin *) tree) -> right);

    printf(" %s", (* (struct Type **) tree) -> name);

}

 

Всё вместе связывают описания типов:

 

static struct Type _Add = { "+", mkBin, doBin, freeBin };

static struct Type _Sub = { "-", mkBin, doBin, freeBin };

 

const void * Add = & _Add;

const void * Sub = & _Sub;

 

Должно быть просто догадаться, как реализовать числовое значение. Оно представляется в виде структуры с информационным полем типа double:

 

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)

{

    printf(" %g", ((struct Val *) tree) -> value);

}

 

Всё сделано — не надо удалять поддеревья, поэтому для удаления узла значения можно использовать непосредственно библиотечную функцию free():

 

static struct Type _Value = { "", mkVal, doVal, free };

 

const void * Value = & _Value;

 

Такой унарный оператор, как Minus (вычитание), оставим в качестве упражнения.

 

Предыдущая  Содержание  Следующая