А.В. Ахо, М.С. Лам, Р. Сети, Дж. Д. Ульман - Компиляторы - принципы, технологии и инструментарий (1114947), страница 15
Текст из файла (страница 15)
1.13, а, укажите значения, присваиваемые переменным ю, х, у и г. 1.б. Азы языков программирования Упражнение 1.6.2. Для кода с блочной структурой на языке программирования С, приведенного на рис. 1.13, б, укажите значения, присваиваемые переменным щ, х, д и г. 1пт. н, 1п~ 1 хр ур г; 3; 1пс 3 = 4г з. = 5; (1с + 3' 1 + х= 1 ( 1пс.
х = з. ( 1пт. + 8з + у ) г = 1+ б) Код к упражнению 1.6.2 а=1+31 а) Код к упражнению 1.6.1 Ряс. 1.!3. Код с блочной структурой Упражнение 1.6.3. Для кода с блочной структурой, приведенного на рис. 1.!4, в предположении обычных статических правил областей видимости, укажите для каждого из двенадцати объявлений его область видимости. ( 1псн, х, у, г; /*БлокВ1*/ 1пт. х, /* Блок В2 */ 1пе.
и, х; /* Блок ВЗ */ ( 1пТ и, х; /* Блок В4 */ ( 1пт. у, г; /* Блок В5 */ ) Рнс. 1.14. Код с блочной структурой к упражнению 1.6.3 Упражнение 1.6.4. Что будет выведено следующим фрагментом кода на языке программирования С? ()с(ей1пе а (х+1) 1пт; х = 2; 1пс н, х, у г; 1пс 1 = 4; 1пт. ( 1пС. 3 = 7; 1=6; + 6; 7г 3.
+ 72 Глава 1. Введение в компиляцию чоз.с1 Ь() ( х = а; рк1пгх(нЪг)М", х); ) чозс) с() ( зп~ х = 1; ркзпсй(нЪс)~п"), а; ) чоЫ ваап() ( Ь()г с(); 1.7 Резюме к главе 1 + Языковые процессоры. Интегрированная среда разработки программного обеспечения включает много различных видов языковых процессоров, таких как компиляторы, интерпретаторы, ассемблеры, компоновщики, загрузчики, отладчики, профайлеры. + Фазы компилятора. Работа компилятора состоит из последовательности фаз, каждая из которых преобразует исходную программу из одного промежуточного представления в другое.
+ Машинные и ассемблерные языки. Машинные языки представляют собой языки программирования первого поколения; за ними следуют языки ассемблера. Программирование на этих языках требует большого количества времени и чревато возникновением ошибок. + Моделирование в разработке компиляторов. Проектирование компиляторов является одной из тех областей, в которых теория оказывает особо сильное влияние на практику. Модели, применяемые в этой области, включают автоматы, грамматики, регулярные выражения, деревья и многое другое. + Оптимизация кода.
Хотя код и не может быть "оптимизирован" в истинном понимании этого слова, наука о повышении эффективности кода очень важна (и очень сложна). Она представляет собой существенную часть изучения компиляции. + Высокоуровневые языки программирования. С течением времени языки программирования берут на себя все большую часть задач, ранее решавшихся программистом, таких как управление памятью, проверка согласованности типов и параллельное выполнение кода. + Компиляторы и архитектура вычислительных систем.
Технологии компиляции оказывают влияние на архитектуру компьютеров, так же как на них, в свою очередь, влияют достижения в области архитектуры вычислительных систем. Многие современные новшества в архитекгуре зависят от способностей компиляторов эффективно использовать аппаратные возможности. 73 !.8. Список литературы к главе 1 + Производительность и безопасность программного обеспечения. Те же методы, которые позволяют компилятору оптимизировать код, могут использоваться для решения ряда задач анализа программ, от поиска распространенных ошибок в программах до определения, насколько программы подвержены тому или иному из множества вариантов вторжения, разработанных "хакерами'*.
+ Правила областей видимости. Область видимости объявления х представляет собой контекст, в котором использование х ссылается на это объявление. Язык, использующий статическую, или лексическую область видимости, в состоянии определить область видимости объявления на основе только исходного текста программы. В противном случае язык использует динамические области видимости.
+ Среды. Связь имен с местоположениями в памяти и затем со значениями может быть описана в терминах сред, которые отображают имена на соответствующие им положения в памяти, и состояний, которые отображают местоположения на их значения. + Блочная структура. Языки, которые допускают наличие вложенных блоков, называются имеющими блочную структуру. Имя х во вложенном блоке В находится в области видимости объявления .0 переменной х в охватывающем блоке, если не имеется другого объявления х в промежуточном блоке.
+ Передача параметров. Параметры передаются от вызываюшей процедуры к вызываемой по значению или по ссылке. При передаче больших объектов по значению передаваемые значения в действительности представляют собой ссылки на объекты, что в результате приводит к фактической передаче по ссылке. + Псевдонимы. Когда параметры передаются по ссылке, два формальных параметра могут ссылаться на один и тот же объект. Такая возможность позволяет изменять одну переменную путем изменения другой переменной.
1.8 Список литературы к главе 1 Информацию о разработке языков программирования, которые были созданы и использовались до 19б7 года, включая Роигап, А!8о1, 1лзр и 81пш!а, можно найти в !7). Языки, созданные до 1982 года, включая С, С++, Рааса! и 8шайгайг, описаны в ~1!. Набор компиляторов 61~ЛЗ (бЬП.1 Согпр!1ег Со)!есйоп — йсс) — популярный источник компиляторов с открытым кодом для С, С++, Еопгап, 1ача и других 74 Глава 1. Введение в компиляцию языков программирования [2~. В [3] описывается РЬоещх — набор инструментов для создания компиляторов, предоставляющий интегрированные средства для построения фаз анализа программ, генерации и оптимизации кода.
Дополнительную информацию о концепциях языков программирования можно найти в [5 и 61; сведения об архитектуре компьютеров и ее влиянии на компиляцию содержатся в [41. 1. Вег81п, Т.3. апд К. Сг. Сг1Ьаоп, Н1яГогу о/Рго8гаттшдйаидиа8ея, АСМ Ргевв, Ыеч г'огас, 1996. 2. ЬППр://асс.дпц.оку/. 3. Ьсср://гевеахсЬ.гп1сковогс.соаз/рЬоепйх/с1ейап1с.аврх. 4. Неппеаву, 1 Ь. апд Р. А.
Ранегвоп, Сотригег Ог8апааг/оп аль Оея18п: ТЬе Нап1и аге/Бо/Ьиаге 1лгет~асе, Могйап-Кацбпапп, Кап ггапс1асо, СА, 2004. 5. ЯсоГГ, М. 1., Рго8гатт/и8 йаи8ип8е Ргп8таГ/сх, зесоиг/ ейГ/ол, МогбапКацйпапп, Кап ггапс[всо, СА, 2006. 6. ЯеГЬ1, К., Рго8гаттш8 1ал8иа8езг Сопсеро. аиг1 СоияГгисГя, Адйаоп-%ев!еу, 1996. 7. %ехе1ЫаГ, К. Ь, Нигогу о/ Ргораттш8 йапдиадея, Асаг1епис Ргевз, Хеяк Уотс, 1981. ГЛАВА 2 Простой синтаксически управляемый транслятор Данная глава представляет собой введение в методы компиляции, рассматриваемые в главах 3 — 6 данной книги. Эти методы проиллюстрированы в ней на примере создания работающей программы на языке программирования )ача, которая транслирует типичные инструкции языка программирования в трехадресный код.
В этой главе основной упор сделан на начальную стадию компиляции, в частности на лексический анализ, синтаксический анализ и генерацию промежуточного кода. В главах 7 и 8 рассматривается генерация машинных команд из трехадресного кода. Мы начнем с создания синтаксически управляемого транслятора, который отображает инфиксные арифметические выражения в постфиксные. Затем мы расширим этот транслятор так, чтобы он мог отображать код, приведенный на рис. 2.1, в трехадресный код показанного на рис. 2.2 вида.
Работающий транслятор на языке программирования 3ача приведен в приложении А. Использовать 1ача удобно, но не необходимо. В действительности идеи этой главы предшествовали созданию как самого 3ача, так и С. 1пс 1; 1пс Зг й1оас[100) а; 11оас ч; й1оас х; мЬ11е ( схпе ) с(о 1 = 1+1; иЬ11е ( а[1) < ч ); бо З = З-1г иЬ11е ( а[2) > ч ); 1~ ( 1 >= Э ) Ьгеа)с.
х = а[1)' а[1) = а[2)г а[э) = хг Рис. 2.1. Фрагмент транслируемого кода 76 Глава 2. Простой синтаксически управляемый транслятор 1; 3. = з. + 1 2; с1=а 3: Нг1< тг досо 1 1 4: 3 = 3 5; Г2=а 6: хй12 > 7 хйРа1ве 8 досо 24 9: х=а [ 1рл сЗ=а 11: а [ х ] 12: а [3 ] 13; досо 1 14: 3 ч досо 4 >= 3 досо 9 Рис. 2.2. Упрощеииый промежуточный код для фрагмента программы, представленною иа рис.
2. ! 2.1 Введение Фаза анализа компилятора разбивает исходную программу иа составные части и производит ее внутреннее представление, называющееся промежуточным кодом. Фаза синтеза транслирует промежуточный код в целевую программу. Анализ организован вокруг "синтаксиса" компилируемого языка.
Синтаксис языка программирования описывает корректный вид его программ, в то время как семантика языка определяет смысл написанной иа ием программы, т.е. что именио делает каждая программа при выполнении. Для определения синтаксиса в разделе 2.2 будет представлена широко используемая запись, именуемая контекстно- свободной грамматикой или ВНЕ (Вас]спз — Мацг Ропп — форма Бэкуса-Наура). На сегодня описание семантики языка — гораздо более сложная задача, чем описание синтаксиса; для ее решения необходимо использовать неформальные описания и примеры. Кроме определения синтаксиса языка, контекстно-свободная грамматика используется при трансляции программ.
В разделе 2.3 будет рассмотрена грамматически управляемая технология компиляции, известная также как синтаксически управляемая трансляция (зуп!ахмйгес!ес1 !гапз!айоп). Синтаксический авализ будет рассматриваться в разделе 2.4. 77 2.1. Введение Остальная часть главы представляет собой краткий обзор модели начальной стадии компилятора, показанной на рнс. 2.3. Мы начнем с синтаксичесюго анализатора. Для простоты будет рассматриваться синтаксически управляемая трансляция инфиксных выражений в постфиксный вид, запись, в которой операторы следуют за их операндами.
Например, постфиксной формой выражения 9 — 5+ 2 является 95 — 2+ . Трансляция в постфиксную форму достаточно богата для иллюстрации синтаксического анализа и достаточно проста, чтобы полностью привести транслятор в разделе 2.5. Простой транслятор обрабатывает выражения наподобие 9 — 5+ 2, состоящие из цифр, разделенных знаками "плюс" и "минус". Одна из причин, по юторой мы начинаем с таких простых выражений, состоит в том, что синтаксический анализатор может работать непосредственно с отдельными символами, представляющими операторы и операнды.