Программирование >>  Формирование пользовательского контейнера 

1 ... 126 127 128 [ 129 ] 130 131 132 ... 156


лексему - число 3, и снова начинается нисходящий спуск по цепочке функций. Как и раньше, вызывается функция atomo. Значение 3 возвращается в переменной value, и считывается знак операции * (умножение). Далее происходит возврат по цепочке в функцию eval exp3(), в которой читается заключительная лексема 2. Здесь выполняется первая арифметическая операция - умножение: 2*3. Результат передается в функцию evai exp2 () и выполняется вычитание. Результат этой операции равен 4. Хотя на первый взгляд описанный процесс может показаться сложным, самостоятельный разбор еще нескольких примеров поможет лучше понять принцип действия анализатора.

Теперь подробнее рассмотрим функцию atomO. Она находит значение целочисленной константы или переменной, функции или символьной константы (она также обрабатывает постфиксную форму операций инкремента и декремента). В исходном коде могут быть представлены два вида функций: определенные пользователем и библиотечные. Если обнаружена функция, определенная пользователем, ее код выполняется интерпретатором для того, чтобы получить возвращаемое значение (как на самом деле Mini С++ добивается вызова функции, обсуждается в следующем разделе). Если же обнаружена библиотечная функция, сначала ее адрес ищется функцией internal func (), а затем выполняется обращение к ней с помощью интерфейсной функции (interface function) списка.

Как видите, интерпретатор Mini С++ знает лишь несколько библиотечных функций, но вы можете легко добавить другие функции, нужные вам (реальные интерфейсные функции содержатся в отдельном файле, который будет обсуждаться в разд. Библиотечные функции Mini С++ ). Заключительный взгляд на работу анализатора выражений: для того, чтобы правильно анализировать синтаксис языка С++, иногда требуется знать лексему, следующую за текущей. Рассмотрим следующий оператор: alpha = count();

Для ТОГО чтобы интерпретатор Mini С++ знал, что count - это функция, а не переменная, он должен прочитать count и следующую лексему. Если следующая лексема - круглая скобка, анализатор опознает count как функцию. Если же обрабатывается следующий оператор:

alpha = count * 10;

ТО за count следует знак умножения *. Поскольку это не круглая скобка, это означает, что count должна быть переменной. Без дополнительной, следующей лексемы анализатор не может сделать такой вывод. В обоих описанных случаях лексему, следующую за текущей, надо вернуть во входной поток для последующей обработки. Для этого в анализатор выражений включена функция putback (), возвращающая последнюю прочитанную лексему во входной поток.



Главаэ

Интерпретатор Mini С++

Интерпретатор - это средство выполнения программы на С++. Перед тем как перейти непосредственно к коду, было бы полезно уяснить, как вообще работает интерпретатор. Понять код интерпретатора во многих отнощениях легче, чем код анализатора выражений, потому что суть процесса интерпретации можно описать с помощью следующего алгоритма: while(есть лексемы) {

получи следующую лексему;

выполни назначенное действие;

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

Для того чтобы понять, как работает алгоритм, давайте вручную проинтерпретируем приведенный далее фрагмент кода.

int а;

а = 10 * num;

if(а < 100) { cout а:

Следуя алгоритму, прочитаем первую лексему int. Назначенное действие для этой лексемы - извлечь следующую лексему для того, чтобы выяснить имя объявляемой переменной (в данном случае, а) и затем запомнить его. Следующая лексема - точка с запятой, завершающая строку. Назначенное действие - игнорировать ее. Теперь получим следующую лексему - а. Поскольку в начале оператора нет ключевого слова, значит, это начало выражения. Назначенное действие - вычислить выражение, используя синтаксический анализатор выражений. Этот процесс поглощает все лексемы данного оператора. Далее читаем лексему if. Она сигнализирует о начале условного оператора, поэтому назначенное действие - обработать оператор if, что означает вычислить условное выражение. Если результат выражения равен true, выполняется блок кода, входящий в состав оператора if. В противном случае он пропускается.

Только что описанный процесс характерен для любой программы на языке С++. Интерпретация прекращается, когда прочитана последняя лексема или



Листинг 9.2. Интерпретатор Mini C-t-i-

#include <iostream> #include <fstreain> #include <new> #include <stack> #include <vector> #include <cstring> #include <cstdlib> #include <cctype> #incl\ide mccommon.h

using namespace std;

char *prog; текущая точка выполнения в исходном коде char *pj3uf; указывает на начало буфера програьллы

Эта структура инкапсулирует информацию,

связанную с переменными.

struct var type {

char var jiame[MAXID jEN+l]; имя tokenireps v type; тип данных

int value; значение

Этот вектор содерзкит информацию о глобальных переменных. vector<var type> global vars;

Этот вектор содержит информацию о локальных переменных и параметрах.

vector<var type> local var stack;

Эта структура инкапсулирует данные о функции, struct func type {

обнаружена синтаксическая ошибка. Давайте рассмотрим интерпретатор, учитывая базовый алгоритм. В листинге 9.2 приведен полный код интерпретатора из файла minicpp.cpp. В следующих разделах он будет обсуждаться подробно.



1 ... 126 127 128 [ 129 ] 130 131 132 ... 156

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика