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

1 ... 135 136 137 [ 138 ] 139 140 141 ... 156


Функция main о начинается с выделения памяти для профаммы, которая будет интерпретироваться. Обратите внимание, максимальный размер интерпретируемой профаммы задается константой prog size. Это значение, равное 10 ООО, задается произвольно, и вы можете увеличить его, если захотите. Далее профамма зафужается с помощью функции load program(). После зафузки программы функция main () выполняет фи основных действия.

1. Вызывает функцию prescanO для предварительного просмотра профаммы интерпретатором.

2. Подготавливает интерпретатор для вызова функции main о профаммы, определяя ее местоположение в исходном коде.

3. Выполняет функцию callo, которая начинает выполнение профаммы со стартовой точки функции main о.

Функция main () также обрабатывает все исключения типа InterpExc, генерируемые интерпретатором Mini С++, включая исключительные ситуации, созданные синтаксическим анализатором выражений.

В следующих разделах подробно рассматриваются ключевые компоненты интерпретатора.

Предварительный просмотр в интерпретаторе

Прежде чем интерпретатор начнет выполнение профаммы, следует решить две важные организационные задачи.

□ Должны быть найдены и инициализированы все глобальные переменные.

□ Должно быть определено местоположение каждой функции в профамме. Эти задачи выполняются в интерпретаторе процедурой предварительного просмотра. В Mini С++ весь выполняемый код сосредоточен внутри функций, поэтому интерпретатору незачем выходить за пределы функций. Но объявления глобальных переменных находятся вне функций. Следовательно, необходимо обработать эти объявления с помощью предварительного просмотра профаммы. У интерпретатора нет другого (эффективного) способа узнать о них.

Для увеличения скорости выполнения важно (хотя в этом нет технической необходимости) знать местоположение каждой функции, определенной в профамме, чтобы обеспечить их существенно более быстрый вызов. Если этот шаг не выполняется, для каждого вызова функции потребуется длительный последовательный поиск в исходном коде профаммы.

Обнаружение точек входа для всех функций служит и другой цели. Как вы знаете, выполнение профаммы на С++ начинается не с первоа строки кода, а с запуска функции mainO. Более того, не требуется, чтобы описание этой функции было первым в программе. Следовательно, необходимо найти



местоположение функции main () в исходном коде для того, чтобы выполнение программы могло начаты;я с этой точки (помните также о том, что объявления глобальных переменных могут предшествовать функции mainO, поэтому даже если она описана в исходном коде первой, это вовсе необязательно означает, что с первой строки кода). Поскольку процедура предварительного просмотра находит точки входа для всех функций, она определяет

и точку входа для функции main ().

функция, выполняющая предварительный просмотр программы, называется prescan (). Далее приведен ее код.

Находит местоположение всех функций в программе и запоминает глобсшьные переменные, void presccinO {

char *р, *tp; char tenp[MAX ID LEN+l]; token ireps datatype; func type ft;

Если brace равна 0, текущая позиция в коде находится за пределами любой функции, int brace = 0;

р = prog;

do {

Обходит код тела функции, while(brace) { get token();

if(tok == END) throw InterpExc(UNBAL BRACES); if(*token == { ) brace++; if(*token == }) brace-;

tp = prog; сохраняет текущую позицию get token();

Проверяет, не тип ли глобальной переменной или возвращаемого значения функции. if(tok==CHAR II tok==INT) {



datatype = tok; сохраняет тип данных get token();

if(token type == IDENTIFIER) { strcpy(tenp, token); get token();

if(*token != () { должна &лть глобальная переменная prog = tp; возвращается к началу объявления decl global ();

}

else if(*token == () ( должна &лть функция

Проверяет, не определена ли уже функция, for(unsigned i=0; i < func table.size(); i++) if (! strcnp(func table[i], func pame, tenp)) throw InterpExc (DUP FONC) ;

ft.loc = prog; ft.ret type = datatype; s trcpy(ft.func name, tenp); func table.push back(ft);

do {

get token(); } while(*token != ));

Теперь следующей лексемой должна &ать открывающая

фигурная скобка тела функции.

else putback();

else {

if(*token == {) brace++; ifCtoken == }) brace-;

} while(tok != END);

if (brace) throw InterpExc (UNBAL BRACES); prog = p;



1 ... 135 136 137 [ 138 ] 139 140 141 ... 156

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