|
Программирование >> Формирование пользовательского контейнера
Трансляция цикла foreach Трансляция цикла foreach - наиболее сложная задача. Эту обработку выполняет функция foreacho, приведенная далее. Транслирует цикл foreach. id foreach О { string token; string vamame; jldent. После выхода из цикла обработки пробелов переменной tracklndent присваивается значение false. Таким образом, только начальные пробелы в строке сохраняются в переменной indent. Если переменная ch содержит не пробел, поверяются другие возможные варианты. Если очередная лексема - идентификатор или ключевое слово, то она начинается с буквы или знака подчеркивания и читается следующим циклом функции gettokenO. В противном случае, если ch содержит цифру, считывается число. Если же переменная ch - не пробел, не буква, не знак подчеркивания и не цифра, то проверяются 5 специальных вариантов. Первый - последовательность \ . Как уже упоминалось, транслятор не обрабатывает текст, заключенный в кавычки. Когда он обнаруживает открывающие кавычки, то просто копирует весь текст между ними и закрывающими кавычками. Однако нужно уметь отличать включенные в текст кавычки (embedded quote) от опфывающих и закрывающих. Для этого последовательность \ должна обрабатываться как пара. Подобная ситуация возникает, если символьная константа содержит кавычки. Символы комментариев также должны обрабатываться как символьные пары, поэтому функция gettokenO проверяет , /* и */. Иногда во время трансляции необходимо избавиться от пробелов, присутствующих в экспериментальном операторе и не имеющих отношения к создаваемому коду на языке С++. Приведенная далее функиия skipspaces () делает это. Она просто читает и отбрасывает пробелы, void SkipspacesO { char ch; do { ch = fin.getO ; } while(isspace(ch)); fin.putback(ch); string arrayname; char forvamametS] = i ; static char counter[2] = a ; Создает управляоцую переменную цикла для генерируемого цикла for. strcat (forvamame, counter); countertO]++; В файле может быть только 26 циклов foreach, так как число генерируемых управляющих переменных цикла ограничено диапазоном от ia до iz. При желании это можно изменить, if(counter[0] > z) throw SyntaxExc( Too many foreach loops. ); fout int forvajmame <,< = 0;\n ; Записывает начало генерируемого цикла for. fout indent for( ; skipspaces(); Считывает ( gettoken(token); if(tokentO] != () throw SyntaxExc( ( expected in foreach. ); skipspaces(); Получает тип переменной цикла foreach. gettoken(token); fout token ; skipspaces(); Читает и сохраняет имя переменной цикла foreach. gettoken(token); varname = token; skipspaces(); Читает in gettoken(token); if(token != in ) throw SyntaxExc( in eзфected in foreach. ); skipspaces(); Читает имя массива. , gettoken(token); arrayname = token; fout vamame = arrayname [0];\n ; Конструирует результирующую строку. fout indent + forvamame < ( (sizeof token )/ (sizeof token [0]));\n ; fout indent + forvamame ++. vamame = arrayname [ forvamame ]) ; SkipspacesO ; Считьшает ) gettoken(token); if(token[0] != ) ) throw SyntaxExc( ) expected in foreach. ); Транслятор преобразует цикл foreach в эквивалентный ему цикл for. Эта обработка включает в себя решение двух довольно сложных задач. Для их Понимания рассмотрим следующий пример: double nums[] = { 1.1, 2.2, 3.3 ); double sum = 0.0; *>reach{double v in nums) sxan += v;
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |