Анимация
JavaScript
|
Главная Библионтека помощью компилятора Kidsgrove. В ИБМ также создали несколько компиляторов ПЛ/I для машин серии 370. Цели проектирования компилятора часто зависят от той среды, в которой он должен использоваться. Если он предназначается в основном для студентов, которые редко пропускают свои программы после удовлетворительного завершения фазы их разработки, эффективность машинного кода будет, иметь меньшее значение, чем скорость компиляции и возможности обнаружения ошибок. В производственной сфере степень важности этих свойств может быть обратной. В учебной среде пакетный компилятор, который остается в основной памяти, пака ряд программ компилируется и прогоняется, позволяет эффективно применять имеющуюся аппаратуру. В построении компилятора большую роль играет решение о числе проходов, которое ему придется выполнять. Каждое прочитывание исходного текста или его версии компилятором считается проходом. Однопроходные компиляторы привлекательны из-за их простоты. Однако не все языки позволяют, выполнять однопроходную компиляцию. Со структурной точки зрения отдельные фазы компиляции могут быть выполнены аккуратнее и проще в разные проходы. Чтобы обеспечить возможность однопроходной компиляции, некоторые разработчики реализуют только какое-либо подмножество языка, настаивая, например, на том, чтобы идентификаторы описывались до их употребления в исходных программах. Создание многопроходного компилятора обычно связано с проектированием промежуточных языков для версий исходного текста, существующих между проходами. Строятся также таблицы какого-либо прохода, которые могут понадобиться для просмотра в последующем проходе или проходах. Поэтому организация многопроходного компилятора выглядит усложненной по сравнению с организацией однопроходного компилятора, хотя отдельные проходы могут быть относительно простыми. Они позволяют разделить задание между рядом исполнителей или групп и не требуют сложных взаимосвязей между ними. Наконец, следует отметить, что не все компиляторы имеют фиксированное число проходов. В некоторых из них число проходов, необходимых для выполнения программы, зависит от того, все ли идентификаторы были описаны до их употребления и т. д., или от степени оптимизации, затребованной программистом. Мы продолжим обсуждение этой темы в гл. 7. Создатель компилятора должен выбрать язык, на котором он будет писать свой компилятор. Все в большей степени для этого применяются языки высокого уровня, универсальные языки, такие как Алгол 68, Паскаль или ПЛ/1, либо так называемые языки программного обеспечения, например BCPL или ПЛ/360. Следует упомянуть и об идее создания компилятора для какого-либо языка на самом языке. В этом случае разработчик должен мыслить только в терминах одного языка, а компилятор можно использовать для самокомпиляции, что само по себе является хорошей проверкой. Кроме того, это - путь для создания переносимого компилятора. Упражнения 1. Приведите какие-нибудь другие типичные конструкции языков высокого уровня и укажите, какого типа команды в машинном коде будут генерироваться при их трансляции. 2. Компилятор транслирует Паскаль в машинный код ICL 1.900, а написан на Алголе 68. Какое еще программное обеспечение потребуется для того, чтобы пропускать программы Паскаля на ЭВМ ICL 1900? 3. Некоторые компиляторы генерируют код для проверки индексов массивов во время прогона, чтобы убедиться в том, что они находятся в объявленных границах массива. Рассмотрите аргументы за и против реализации таких проверок:. а) в процессе разработки программы; б) в процессе рабочих прогонов. 4. Требуется разработать компилятор Фортрана за относительно короткое время. Как вы думаете, какие из шести целей проектирования> перечисленных в разд. 1.3, будет труднее всего осуществить? 5. Какие из следующих средств языка высокого уровня, по вашему мнению, окажутся полезными для разработчика компилятора: а) массивы? б) арифметические действия с вещественными числами? в) процедуры? 6. Приведите доводы в пользу применения в учебной среде интерпретатора, а не компилятора. 7. Какие вероятные проблемы вы видите в методе KDF 9, предлагающем разные компиляторы для этапов трансляции и прогона рабочей программы? 8. Некоторые языки позволяют программисту присваивать относительный приоритет обозначениям операций. Как может это сказаться на дереве разбора конкретной программы? 9. Каковы, по вашему мнению, основные цели проектирования компилятора для языка, на котором реализуется программное обеспечение? 10. Какое средство вы ожидаете найти в компиляторе, предназначенном для такого диалогового языка, как Бейсик? Глава 2. ОПРЕДЕЛЕНИЕ ЯЗЫКА Прежде чем приступить к созданию компилятора, необходимо (или по меньшей мере крайне желательно) иметь четкое и однозначное определение исходного языка. К сожалению, хотя и существуют хорошо разработанные методы спецификации некоторых аспектов языков программирования, полные и ясные определения реализуемых языков часто отсутствуют. Более того, формальное определение языка не обязательно используется создателем компилятора. В настоящей главе мы знакомим читателя с несколькими методами определения языков программирования. Подробнее эта тема освещена в [44]. Мы также рассматриваем здесь проблему разбора - как выяснить, принадлежит ли какая-либо последовательность символов конкретному языку или нет. 2.1. СИНТАКСИС И СЕМАНТИКА Можно представить себе язык состоящим из ряда строк (последовательностей символов). В описании языка определяется, какие строки принадлежат этому языку (синтаксис языка), и значение этих строк (семантика языка). Синтаксис для конечного языка (т.е. состоящего только из конечного числа строк) можно специфицировать, задав список строк. Например, язык может содержать строки аЬс xyz Строки, принадлежащие языку, обычно называются предложениями. Большинство представляющих для нас интерес языков включает бесконечное число предложений, так что их синтаксис нельзя определить путем перечисления этих предложений. К примеру, предложениями языка могут быть «все строки, состоящие только из нулей и единиц». Так, !01 ПОР 11001 может принадлежать языку, и в этом случае цитируемая фраза представляется достаточным определением языка. Однако русский язык не очень годится для спецификации синтаксиса более сложных языков, поэтому, как правило, применяется более формальный метод определения синтаксиса языков программирования, о чем мы узнаем позже. Семантика задает значение всем предложениям языка. Например, является предложением Алгола 68, и исходя из семантики Этого языка можно вывести значение данной программы в терминах описания идентификатора, считывания значения для него, вычисления и печати выражения. Семантика языка, как и синтаксис, обычно описывается довольно формально. Однако методы определения семантики не так хорошо разработаны, как методы определения синтаксиса, и нужны дальнейшие исследования в этой области, чтобы получить полностью удовлетворительное формальное определение языков программирования. Развитие указанного направления может позволить создавать компиляторы автоматически на основе формального определения семантики и синтаксиса языка. В следующем разделе мы рассмотрим задачу спецификации синтаксиса языка. 0 1 2 3 4 [ 5 ] 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |