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

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

| 9/3-0 00+56)

Для синтаксического анализа следует выполнить следующие действия.

1. Получить первый терм 9/3.

2. Получить каждый фактор и поделить целые числа. Результат равен 3.

3. Получить второй фактор, (100+56). В этой точке начинается рекурсивный анализ второго подвыражения.

4. Получить все факторы и сложить их. Результат: 156.

5. Вернуться из рекурсивного вызова и вычесть 156 из 3. Ответ: —153.

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

В оставшейся части главы мы рассмотрим три программы синтаксического анализа выражений. Первая программа анализирует и вычисляет выражения типа double, состоящие исключительно из констант. Затем мы рассмотрим синтаксический анализатор, позволяющий применять переменны^. И в заключение третья версия анализатора будет реализована в виде шаблонного класса, который можно применять для синтаксического анализа выражений любого типа.

lJ Класс parser

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

class parser {

char *exp_ptr; // Ссылается на выражение,

char token[80]; // Хранит текущую лексему,

char tok_type; // Хранит тип лексемы.

void eval_exp2(double kresult); void eval_exp3(double kresult); void eval_exp4(double kresult); void eval_exp5(double &result); void eval_exp6(double &result); void atom(double kresult); void get_token(); void serror(int error); int isdelim(char c) ; public; parser();

double eval_exp(char *exp);

}

Класс parser содержит три закрытые переменные-члены. Вычисляемое выражение содержится в обычной строке, на которую ссылается указатель exp_prt. Таким образом, анализатор вычисляет выражения, содержащиеся в стандартных ASCII-строках. Например, анализатор способен вычислить следующие выражения:

|"10-5"

"2*3.3/3.1416*3.3"

Если анализ начинается с выражения, указатель exp_ptr должен ссылаться на первый символ строки. В ходе работы анализатор считывает оставшуюся часть строки, пока не обнаружит ее конец.

Предназначение остальных переменных-членов, token и tok_type. описано в следующем разделе.

Отправной точкой анализа является функция eval_exp(), которой следует передать указатель на анализируемое выражение. Функции eval_exp2 О — eval_exp6 () вместе с функцией atom О образуют основу рекурсивного нисходящего анализа. Они реализуют порождающие правила, описанные выше. В последующих версиях анализатора к ним будет добавлена функция eval_expl ().

Функция serror() предназначена для обработки синтаксических ошибок, содержащихся в выражении. Функции get_token() и isdellm() используются для разбора выражения на составные части.