|
Программирование >> Формирование пользовательского контейнера
Функция 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;
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |