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

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

int slot;

char ttok .type ;

char temp_token[80]

if(tok_type==VARIABLE) {

// Сохраняем старую лексему, strcpy(temp_token, token); ttok_type = tok_type;

// Вычисляем индекс переменной, slot = toupper(*token) - 'A';

get_token() ;

if(*token != '=') { putback(); // Возвращаем текущую лексему.

// Восстанавливаем старую лексему -// присваивание не выполняется, strcpy(token, temp_token); tok_type = ttok_type;

}

else {

get_token(); // Извлекаем следующую часть выражения exp. eval_exp2 (result) ,-vars[slot] = result; return;

}

eval_exp2 (result) ,-

}

// Складываем или вычитаем два терма.

template cclass РТуре> void parsercPType>::eval_exp2(РТуре bresult)

{

register char op;

PType temp;

eval_exp3(result) ;

while((op = *token) == '+■ || op == '-') {

get_token(); eval_exp3(temp); switch(op) { case 1 -':

result = result - temp; break; case '+■:

result = result + temp; break;

}

// Умножение и деление двух факторов.

template cclass РТуре> void parsercPType>::eval_exp3(РТуре kresult)

{

register char op;

PType temp;

eval_exp4(result) ;

while((op = *token) == '*' || op == '/' || op == '%') {

get_token(); eval_exp4(temp); switch(op) { case '*':

result = result * temp; break; case '/':

result = result / temp,-break; case '%':

result = (int) result % (int) temp;

break;

}

}

}

// Возведение в степень.

template <class РТуре> void parser<PType>::eval_exp4(РТуре &result) {

PType temp, ex; register int t;

eval_exp5(result) ; if(*token== ,л,( {

get_token() ,-eval_exp4(temp); ex = result; if(temp==0.0) {

result = (PType) 1; return;

}

for(t=(int)temp-1; t>0; —t) result = result * ex;

}

// Выполнение унарных операций + или -

template cclass PType> void parsercPType>::eval_exp5(PType &result) {

register char op; op = 0;

if((tok_type == DELIMITER) && *token=='+' || *token == '-') {

op = *token; get_token();

}

eval_exp6(result); if(op=='-') result = -result;

// Вычисляет выражение, содержащеее скобки.

template cclass PType> void parsercPType>::eval_exp6(PType &result) {

if((*token == ' ( 1 ) ) {

get_token(); eval_exp2(result); if(*token != ')') serror(1); get_token();

}

else atom(result);

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

template cclass РТуре> void parsercPType>::atom(PType &result) {

switch(tok_type) ( case VARIABLE:

result = find_var(token) ,-

get_token() ; return; case NUMBER:

result = (PType) atof(token); get_token(); return; default: serror(0);

// Возвращает лексему во входной поток.

template cclass РТуре> void parser<PType>::putback()

{

char * t; t = token;

fort; *t; t++) exp_ptr--;

}

// Выводит сообщение о синтаксической ошибке.

template cclass РТуре> void parser<PType>::serror(int error)

{

static char *e[] = {

"Синтаксическая ошибка",

"Нарушен баланс скобок",

"Выражение пусто"

};

cout « е[error] « endl;

}

// Извлекает следующую лексему.

template cclass РТуре> void parsercPType>::get_token()

{

register char *temp;

tok_type = 0; temp = token;