Сложение и вычитание
Пусть дано выражение, в котором кроме чисел разрешены только знаки «плюс» и «минус»
Рассмотрим на этом примере работу функции evaluate_expression().
В данном случае схема алгоритма довольно тривиальна:
1. возьмем первую лексему; она обязательно будет числом. Запишем это число в current_result.
2. Возьмем следующую лексему. Формально, выражение из единственного числа является корректным, поэтому уже в этот момент текущая лексема может получить тип LT_END. На случай, если в выражении все-таки что-то осталось организуем цикл:
3. Цикл: пока текущая лексема не является LT_END
3.1. Поскольку мы попали в цикл, то после числа стоит не конец строки, а какой -то знак.
3.2. Если текущая лексема LT_PLUS, то
Взять следующую лексему. Это обязательно будет число, его значение попадет в переменную current_lexem_value
current_result = current_result + current_lexem_value
3.2. Если текущая лексема LT_MINUS, то действия аналогичны предыдущему варианту:
Взять следующую лексему. Это обязательно будет число, его значение будет храниться в переменной current_lexem_value
current_result = current_result – current_lexem_value
4. Как только строка закончена, вернуть значение current_result.
Пример функции на языке C.
int evaluate_expression() {
void calc_plus() {
// в эту функцию мы попадем, только если текущая лексема - это знак "плюс"
// при корректных исходных данных логично ожидать после знака "плюс" некоторое число
// получим число и обработаем его
get_next_lexem();
// здесь можно вставить проверку того, что за плюсом действительно идет число
current_result = current_result + current_lexem_value;
get_next_lexem();
}
int void_minus() {
get_next_lexem();
// здесь можно вставить проверку того, что за минусом действительно идет число
current_result = current_result - current_lexem_value;
get_next_lexem();
}
int current_result = 0;
get_next_lexem();
// если бы мы не верили в корректность исходных данных,
// здесь можно было бы поставить проверку на то,
// начинается ли выражение с числа или нет
// if (current_lexem_type != LT_NUMBER) {обработка ошибки}
// так же, можно сразу отсечь случай пустого выражения на входе
// if (current_lexem_type == LT_END) {обработка еще одной ошибки}
current_result = current_lexem_value;
get_next_lexem();
// берем лексему, следующую за числом
// если за числом сразу следует конец строки, то в цикл мы не попадем
while (current_lexem_type != LT_END) {
// раз мы попали в цикл - ожидаем, что
// выражение продолжится корректно, то есть
// если после первого числа что-то есть, то это обязательно
// знак операции, а потом еще и число
// но если в задаче это явно не сказано, то
// if ((current_lexem_type != LT_PLUS) && (current_lexem_type != LT_MINUS)) {обработка ошибки}
if (current_lexem_type == LT_PLUS) {
calc_plus();
}
else {
calc_minus();
}
}
// После того, как мы разобрали всю строку – вернем результат
return (current_result);
}
Функции calc_plus() и calc_minus() возможно, выглядят пока слишком простыми, чтобы оформить их отдельными функциями, но позже за знаками "плюс" и "минус" будут следовать не только числа, но и выражения в скобках, или выражения, состоящие из произведений (например: 5+9*6*(3+1) ). В этом случае функциям обработки "плюса" или "минуса" придется уже значительно потрудиться.