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

1 ... 52 53 54 [ 55 ] 56 57 58 ... 156


экспериментов. Не составляет труда встроить в транслятор расширение язы-а потом испытать его. В следующих разделах дается подробное описание jgiicfloft части транслятора, реализующей предложенные ранее расширения.

Глобальные объявления

Код транслятора начинается с объявления следующих глобальных переменных и класса:

Строка-заполнитель для отступов. String indent =

Входной и выходной файловые потоки, if stream fin; of stream fout;

Класс-исключение для синтаксических ошибок, class SyntaxExc {

string what; public :

SyntaxExc (char *e) { what = string (e); }

string geterrorO { return what; )

Текущая последовательность пробелов, предназначенная для формирования отступов, хранится в переменной indent. Эта строка применяется для вставки отступов определенного размера при замене экспериментальной конструкции несколькими строками кода.

Поток входного файла хранится в переменной fin, поток выходного файла содержится в переменной fout. При старте программы имена файлов, указанные в командной строке, связываются с переменными fin и fout. Синтаксические ошибки, возникающие во время трансляции проверяемой

конструкции, создают объект-исключение типа SyntaxExc. Класс SyntaxExc

содержит только строку, описывающую возникшую ошибку, но при желании вы можете добавить в него необходимую обработку.

Функция mainO

функции main о - две обязанности. Во-первых, она открывает входной и выходной файлы, заданные в командной строке. Код, предназначенный для ого, хорошо знаком всем программистам на языке С++. Во-вторых, в ней



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

try {

Главный цикл трансляции, while(gettoken(token)) [

Пропускает комментарии . if(token == ) ( do {

fout token; gettoken(token); } while(token.find(\n) == string::npos); fout token;

Пропускает комментарии /*. else if (token ==/* ) { do {

fout token; gettoken(token); } vdiile(token != */ ); fout token;

Пропускает строку в кавычках, else if(token == \ ) { do {

fout token; gettoken(token); } vdiile(token != N ) ; fout token;

else if (token == foreach ) foreachO ; ,

else if(token == cases ) cases(); else if(token == repeat ) repeat();



рмренме С++ 171l

else if (token == vintil ) until(); else if (token == typeof ) typeof(); else fout token;

) catch (SyntaxExc exc) { cout exc.geterror() endl; return 1;

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

Если обнаруживается синтаксическая ощибка в процессе трансляции проверяемого ключевого слова, кодом, выполняющим трансляцию, генерируется объект-исключение типа SyntaxExc и передается вызываемому в функции main о обработчику исключений catch, который просто отображает ошибку на экране. Вы можете усовершенствовать сообщение об ошибке, включив в него номер ошибочной строки или другую интересующую вас информацию.

Функции gettokenO и skipspacesO

Для того чтобы транслятор мог преобразовать экспериментальное ключевое слово в эквивалентный код на языке С++, он должен знать о том, что такое слово обнаружено. Для этого входной файл следует разбить на лексемы. В данном случае термин лексема употребляется в самом широком смысле этого слова и означает просто фрагмент текста. Транслятору не нужен тщательный лексический разбор. Он просто должен уметь узнавать идентификаторы (включая ключевые слова), числа и пробелы. Все остальные символы можно обрабатывать как одиночные. Далее приведена функция gettokenO. 1 Получает следующую лексему из входного потока. *о1 gettoken(string &tok) {

char ch;

char ch2;



1 ... 52 53 54 [ 55 ] 56 57 58 ... 156

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