1.1.3 Особенности языков программирования
Языки программирования занимают промежуточное место между формальными и естественными языками. С формальными языками их объединяют строгие синтаксические правила, на основе которых строятся предложения языка. От естественных языков в языки программирования перешли лексические единицы, представляющие основные ключевые слова (чаще это английские слова, но бывают и слова других языков).
Для задания языка программирования необходимо решить три основных вопроса:
определить множество допустимых символов языка;
определить множество правильных программ языка;
задать смысл каждой правильной программы.
С помощью теории формальных языков удается решить (полностью или частично) только первые два вопроса.
Первый вопрос решается легко. Алфавит языка и представляет собой множество его допустимых символов. Для языков программирования это, как правило, тот набор символов, который можно ввести с клавиатуры.
Второй вопрос в теории формальных языков решается только частично. Для всех языков программирования существуют синтаксические правила, но их недостаточно для строгого определения всех возможных синтаксических конструкций. Дополнительные ограничения накладываются семантикой языка и неформально оговариваются для каждого отдельного языка программирования. Это, например, необходимость предварительного описания переменных и функций, необходимость соответствия типов переменных и констант в выражениях, формальных и фактических параметров в описаниях и вызовах процедур и функций, и т.п.
Отсюда следует, что практически все языки программирования, строго говоря, не являются формальными языками. Поэтому во всех трансляторах, кроме синтаксического разбора и анализа предложений языка, дополнительно предусмотрен семантический анализ.
Третий вопрос вообще не относится к теории формальных языков. Для ответа на него нужно использовать другие подходы, например:
1. изложить смысл программы, написанной на языке программирования, на другом языке, более понятном тому, кому адресована программа;
2. использовать для проверки смысла некоторую «идеальную машину», которая предназначена для проверки программ, написанных на данном языке.
Любой разработчик программ так или иначе использует первый подход - это комментарии в программе, построение ее блок-схемы, разработка документации или любое другое описание алгоритма. Все эти способы ориентированы на человека, но универсального способа проверить, насколько описание в действительности соответствует программе, пока не существует. Для изложения программы на языке, понятном машине - в машинных командах - существуют трансляторы.
Второй подход используется при отладке программы; оценку результатов выполнения программы при отладке осуществляет человек.
Разработчикам компиляторов так или иначе приходится решать вопрос о смысле программ.
Во-первых, компилятору для преобразования исходной программы в последовательность машинных команд необходимо иметь представление о том, какая последовательность команд должна соответствовать той или иной части программы. Обычно такие последовательности сопоставляют базовым конструкциям входного языка - используется первый подход к изложению смысла программы.
Во-вторых, многие современные компиляторы позволяют выявить сомнительные с точки зрения смысла места в исходной программе - например, недостижимые операторы, неиспользуемые переменные, неопределенные результаты функций и т.п. Обычно компилятор указывает такие места в виде предупреждений, на которые разработчик может обращать или не обращать внимание. Для этого компилятор должен иметь представление о том, как программа будет выполняться, т.е. используется второй подход.
Но в любом случае осмысление исходной программы закладывает в компилятор его создатель, который руководствуется неформальными методами - как правило, описанием входного языка. В теории формальных языков вопрос о смысле программ не решается.
Итак, возможности трансляторов по проверке осмысленности исходной программы практически равны нулю, поэтому семантические ошибки остаются на совести авторов программ.
Выше, когда шла речь о различных способах задания языков, мы выделили как наиболее реальные второй и третий способ, а именно: задание языка с помощью генераторов и распознавателей. В качестве генераторов в общем случае могут использоваться грамматики, а для более узкого класса языков - регулярные выражения. В качестве распознавателей, как правило, применяются автоматы различных типов (в зависимости от класса языка). Рассмотрим способ задания языков с помощью грамматик.
- Введение
- Глава 1. Формальные языки и грамматики
- 1.1 Языки и цепочки символов
- 1.1.1 Цепочки символов и операции над ними
- 1.1.2 Понятие языка. Способы задания языков
- 1.1.3 Особенности языков программирования
- 1.2 Определение грамматики
- 1.2.1 Понятие грамматики и формальное определение. Форма Бэкуса-Наура
- 2.2 Другие способы задания грамматик
- 1.3 Классификация языков и грамматик
- 1.3.1 Классификация грамматик по Хомскому
- 1.3.2 Классификация языков
- 1.4 Вывод и выводимость
- 2. Принципы трансляции языков программирования
- Теория языков программирования и методы трансляции
- Лекция 25. Трансляция с языков программирования Сущность трансляции. Компиляция и интерпретация
- Классификация языков программирования
- Раздел 13. Теория языков программирования и методы трансляции
- Понятие уровня языка программирования. Понятие трансляции. Методы трансляции.
- Раздел 13. Теория языков программирования и методы трансляции
- Языки программирования и методы трансляции