Читать «Полный справочник по С++» онлайн - страница 449

Герберт Шилдт

*temp = '\0';

if(!*exp_ptr) return; // В конце выражения.

while(isspace(*exp_ptr)) ++exp_ptr; // Пропуск разделителя.

if(strchr("+-*/%Л=()", *exp_ptr)){ tok_type = DELIMITER;

// Переход к следующему символу.

*temp++ = *exp_ptr++;

}

else if(isalpha(*exp_ptr)) {

while(!isdelim(*exp_ptr)) *temp++ = *exp_ptr++; tok_type = VARIABLE;

)

else if(isdigit(*exp_ptr)) {

while(!isdelim(*exp_ptr)) *temp++ = *exp_ptr++; tok_type = NUMBER;

}

*temp = '\0';

}

// Если параметр с является разделителем,

// возвращает значение true, template cclass РТуре> int parser<PType>::isdelim(char с)

{

if(strchr(" +-/*%Л= ()'', с) || c==9 || c=='\r‘ || c==0)

return 1; return 0;

// Возвращает значение переменной.

template cclass PType> PType parser<PType>::find_var(char *s)

{

iff!isalpha(*s)){ serror(1); return (PType) 0;

}

return vars[toupper(*token)- 1 A' ] ;

}

Тип данных, с которыми работает синтаксический анализатор, задается классом РТуре. Применение обобщенного анализатора иллюстрируется следующей программой.

int main()

[

char expstr[80];

// Демонстрация анализатора выражений типа float. parser<double> ob;

cout « "Анализатор выражений типа float, cout « "Для окончания работы введите точку \п”; for(;;) [

cout « "Введите выражение: "; cin.getline(expstr, 79); if(*expstr=='.') break;

cout « "Ответ: " << ob.eval_exp(expstr) « "\n\n";

}

cout « endl;

// Демонстрация анализатора целочисленных выражений. parser<int> lob;

cout « "Анализатор целочисленных выражений. 11; cout « "Для окончания работы введите точку\п”; for(;;) {

cout « "Введите выражение: "; cin.getline(expstr, 79); if(*expstr=='.') break;

cout « "Ответ: " « lob.eval_exp(expstr) « "\n\n";

}

return 0;

Анализатор выражений типа float. Для окончания работы введите точку. Введите выражение: а=10.1 Ответ: 10.1

Введите выражение: Ь=3.2 Ответ: 3.2

Введите выражение: а/Ь Ответ: 3.15625

Введите выражение: .

Анализатор целочисленных выражений. Для окончания работы введите точку.

Введите выражение: а=10 Ответ: 10

Введите выражение: Ь=3 Ответ: 3

Введите выражение: а/Ь Ответ: 3

Введите выражение: .

Как видим, анализатор выражений типа float использует действительные значения, а анализатор целочисленных выражений — целые.

Некоторые задачи

Мы уже отмечали, что наш синтаксический анализатор распознает лишь небольшое количество ошибок. Читатели могут сами усовершенствовать блок синтаксического контроля. Например, можно выделять ошибочный элемент выражения другим цветом. Это позволило бы пользователю легко обнаруживать и исправлять ошибки.

Кроме того, в нынешнем виде наш калькулятор может вычислять лишь числовые значения. Однако его можно модифицировать так, чтобы он вычислял выражения, содержащие строки, пространственные координаты или комплексные числа. Например, для вычисления строковых объектов в анализатор необходимо внести следующие изменения.

1. Определить новый тип лексемы под названием string.

2. Усовершенствовать функцию get_token() так, чтобы она распознавала строки.

3. Предусмотреть вариант, в котором функция atom() обрабатывала бы строковые