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

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

Разбор выражения на составные части

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

Каждый компонент выражения называется лексемой (token). Например, выражение | A*B-(W+10)

состоит из лексем А, *, В, —, (, W, +, 10 и ). Каждая лексема представляет собой неделимую часть выражения. Как правило, для синтаксического анализа необходима функция, которая последовательно возвращала бы отдельные лексемы, из которых состоит выражение. Кроме того, эта функция должна игнорировать пробелы и знаки табуляции, а также распознавать конец выражения. Функция, которая позволяет выделить лскссмы, называется get_token(). Она является членом класса parser.

Нам необходимо знать тип лексем. В нашей программе использованы три типа лексем: variable, number и delimiter. (К типу delimiter относятся операторы и скобки.)

Функция get_token() показана ниже. Она извлекает следующую лексему из выражения, на которое ссылается указатель e»p_ptr, и заносит ее в переменную token. Тип извлеченной лексемы записывается в переменную tok_type.

// Извлекает следующую лексему, void parser::get_token()

{

register char *temp;

tok_type = 0;

temp = token;

* 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, int parser::isdelim(char с)

{

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

return 1;

return 0;

Присмотримся к этим функциям. После первых инициализаций функция get_token() проверяет, не обнаружен ли конец файла. Для этого она проверяет символ, на который ссылается указатель exp_ptr. Если его значение равно нулю, значит, достигнут конец выражения. Если в выражении остались еще не извлеченные лексемы, функция get_token() пропускает все ведущие разделители. Поскольку разделители игнорируются, указатель exp_ptr может ссылаться либо на число, либо на переменную, либо на оператор, либо па конец выражения (в этом случае он равен нулю). Если следующим символом является оператор, он возвращается в виде строки и записывается в переменную token, а в переменную tok_type записывается константа delimiter. Если следующий символ является буквой, предполагается, что лексема является переменной. Она возвращается в виде строки и записывается в переменную token, а в переменную tok_type записывается константа variable. Если следующий символ является цифрой, считывается все число. Затем оно превращается в строку и записывается в переменную token, а в переменную tok_type записывается константа number. В заключение, если следующий символ не относится пи к одному из перечисленных выше типов, считается, что функция get_token() достигла конца выражения.