|
Программирование >> Формирование пользовательского контейнера
Примечание я писал об анализе выражений в течение многих лет. Для более глубокого изучения этого процесса применительно к языку С++ отсылаю вас к своей книге С++: The Complete Reference . изд. McGraw-Hill/Osborne. Код синтаксического анализатора выражений Полный код анализатора выражений для интерпретатора Mini С++ приведен в листинге 9.1. Его нужно поместить в файл parser.cpp. Функционирование синтаксического анализатора описано в последующих разделах. Листинг 9.1. Рекурсивно-нисходящий анализатор для целочисленных i #include <iostreain> #include <cstring> #include <cstdlib> #include <cc:type> #include mccoitimon.h using namespace std; Cm. разд. Другие книги автора в предисловии. - Пер. претатору Mini С++. Поскольку в С++ выражения определены шире, чем в других языках программирования, существенный объем кода программы на языке С++ выполняется анализатором выражений. Существует несколько разных способов разработки анализатора выражений для языка С++. Многие коммерческие компиляторы используют таблично-управляемый синтаксический анализатор (table-driven parser), который создается программой-генератором анализатора (pai-ser-generator program). Несмотря на то, что таблично-управляемые синтаксические анализаторы, как правило, быстрее других вариантов, их трудно создавать самостоятельно. Интерпретатор Mini С++ использует рекурсивно-нисходящий синтаксический анализатор (recursive-descent parser), который действует в соответствии с логикой порождающих правил, описанных в предьшущем разделе. Рекурсивно-нисходящий анализатор представляет собой по существу коллекцию взаимно рекурсивных функций, которые обрабатывают выражение. Если синтаксический анализатор применяется в компиляторе, он генерирует надлежащий объектный код, соответствующий исходному коду профаммы. В интерпретаторе анализатор вычисляет заданное выражение. В этом разделе разрабатывается синтаксический анализатор интерпретатора Mini С++. Таблица поиска ключевых слов. Ключевые слова должны быть набраны строчными буквами, struct commands { char command[20]; token ireps tok; > conutable[] = { if . IF, else , ELSE, for , FOR. do , DO, while , WHILE, char , CHAR, int , INT, return , RETURN, switch , SWITCH, break , BREAK, case , CASE, cout , COUT, cin , CIN, , END помечает конец-таблицы Эта структура связывает имя библиотечной функции с указателем на эту функцию, struct intem fiinc type { char *f name; имя функции int (*р) О; указатель на функцию } intem func[] = { getchar , calletchar, putchar , call putchar, . abs , call abs, rand , call rand, ,0 нуль-завершение перечня Точка входа в анализатор, void eval exp(int bvalue) { get token(); if(!*token) { throw InterpExc(NO EXP); if(*token == ;) { value =0; пустое вьфажение return; eval eзфO (value); putbackO; возвращает последнюю прочитанную лексему во входной поток Обрабатывает вьфажение присваивания. void eval eзфO(int &value) tenp содержит имя var, получающей присваивание, char tenplMAX ID LEN+l]; tok types tenp tok; if(tokentype == IDENTIFIER) { if(is var(token)) { если переменная, то не присваивание ли? strcpy(tenp, token); tenp tok = token type; get token(); if(*token == = ) { присваивание get token(); eval eзфO(value); получает значение для присваивания assign var(tenp, value); присваивает значение return; else { не присваивание putbackO; возвращает исходную лексему во входной поток strcpy(token, tenp);
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |