Читать «Полный справочник по С++» онлайн - страница 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() используются для разбора выражения на составные части.