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

5.3 Подменщик — Name

5.3 Подменщик — Name

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

Присвоение имеет следующий синтаксис:

 

stmt : sum

     | LET VAR = sum

 

LET является примером ключевого слова. При построении подменщика мы все ещё можем решить, какой идентификатор будет представлять LET: scan() извлекает идентификатор из строки ввода и передаёт его в screen(), которая просматривает таблицу символов и возвращает подходящее значение для token и, по крайней мере для переменной, узел в symbol.

Подменщик отбрасывает LET, но устанавливает данную переменную в качестве листового узла в дереве. Для других символов, таких как имя математической функции, чтобы получить новый узел нашего дерева, мы можем захотеть применить new() к тому символу, который возвращает подменщик. Таким образом записи нашей таблицы символов должны иметь по большей части одинаковые функции с динамической компоновкой, так же как и узлы нашего дерева.

Для ключевого слова структура Name должна содержать входную строку и значение маркера. Мы хотим в дальнейшем наследоваться от Name; поэтому определяем эту структуру в файле представления Name.r:

 

struct Name {          /* базовая структура */

    const void * type; /* для динамической компоновки */

    const char * name; /* может быть выделена динамическая память */

    int token;

};

 

Наши символы никогда не умирают: не имеет значения, являются ли их имена постоянными строками для заранее определённых ключевых слов или динамически сохранёнными строкам для определённых пользователем переменных — мы не будем их утилизировать.

Прежде чем мы сможем найти символ, надо встроить его в таблицу символов. Это не может быть сделано с помощью вызова new(Name, ...), потому что мы хотим поддерживать более сложные символы, чем Name, и собираемся скрыть от них реализацию таблицы символов. Вместо этого мы предоставляем функцию install(), которая принимает объект Name и вставляет его в таблицу символов. Вот файл интерфейса символьной таблицы Name.h:

 

extern void * symbol;    /* -> последний Name, найденный screen() */

 

void install (const void * symbol);

int screen (const char * name);

 

Распознаватель должен вставить ключевые слова, такие как LET, в таблицу символов, прежде чем они смогут быть найдены подменщиком. Эти ключевые слова могут быть определены в постоянной таблице структур — это не имеет никакого значения для install().  Для инициализации распознавания используется следующая функция:

 

#include "Name.h"

#include "Name.r"

 

static void initNames (void) {

    static const struct Name names [] = {

        { 0, "let", LET },

        0 };

    const struct Name * np;

    for (np = names; np -> name; ++ np)

        install(np);

}

 

Обратите внимание, что names[], таблица ключевых слов, не должна быть отсортирована. Чтобы определить names[] используем представление Name, то есть подключаем Name.r. Так как ключевое слово LET отбрасывается, мы не предоставляем динамически скомпонованных методов.

 

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