С для профессиональных программистов



         

Синтаксический анализатор выражений - часть 4


if (!tok) token_type = VARIABLE;

else token_type = COMMAND; /* это команда */

return token_type;

/* Возврат лексемы во входной поток */

void putback()

char *t;

t = token;

for(; *t; t++) prog--;

/* Поиск соответствия внутреннего формата для

текущей лексемы в таблице лексем.

*/

look_up(s)

char *s;

register int i,j;

char *p;

/* преобразование к нижнему регистру */

p = s;

while(*p) *p = tolower(*p); p++;

/* просматривается, если лексема обнаружена в

таблице */

for(i=0; *table[i].command; i++)

if(!strcmp(table[i].command, s)) return table[i].tok; return 0; /* нераспознанная команда */

/* Возвращает "истину", если "c" разделитель */

isdelim(c)

char c;

if(strchr(" ;,+-<>/*%^=()",c) || c==9 || c=='\r' || c==0)

return 1;

return 0;

/* Возвращает 1, если "с" пробел или табуляция */

iswhite(c)

char c;

if(c==' ' || c=='\t') return 1;

else return 0;

 

Анализатор поддерживает следующие операторы: "+", "-", "*", "/", "%", целочисленный показатель степени (^) и унарный минус. Все эти операции могут использоваться в сочетании с круглыми скобками. Вы, вероятно, заметили, что в программе имеются функции шести уровней, которые работают точно также как функция primitive(), вращающая значение числа. Помимо этих функций, реализующих арифметические операции, в состав программы включены функции arith() и unary(), а также get_token().

При вычислении выражения prog указывает на начало строки, содержащей выражение, и вызывает get_exp() с адресом переменной, в которую вы хотите поместить результат.

Обратите особое внимание на функцию serror(), которая используется для выдачи сообщений об ошибках. При обнаружении синтаксической ошибки serror() вызывается с номером этой ошибки в качестве аргумента. Ошибка с кодом 0, которой соответствует сообщение "синтаксическая ошибка", выдается в том случае, когда тип ошибки нельзя определить более конкретно. В других случаях ошибка уточняется. Заметьте, что serror() заканчивается вызовом функции longjmp().

Функция logjmp() выполняет нелокальный переход, возвращаясь в точку, определенную с помощью функции setjmp(). Функция setjmp() включена в исходный текст интерпретатора. Первый аргумент функции logjmp() является буфером среды, инициированной с помощью setjmp(). Второй аргумент - это значение, которое определяется при передаче управления из setjmp() обратно в точку ее вызова. Как это делается вы, увидите позже.

Использование ljgjmp() упрощает обработку ошибок, так как программы-анализаторы не должны аварийно завершаться при обнаружении ошибки. Если ваш компилятор Си не поддерживает функции setjmp() и logjmp(), то каждая функция при обнаружении ошибок должна выполнять возврат в точку возникновения ошибки самостоятельно.




Содержание  Назад  Вперед