пользователей: 30398
предметов: 12406
вопросов: 234839
Конспект-online
РЕГИСТРАЦИЯ ЭКСКУРСИЯ

Уровни интерпретации информации: синтаксис, семантика, прагматика

Различные стороны определения языка

Для создания, проверки и преобразования программ, построения систем программирования, а также для многих других нужд нам необходимо если не определение, то хотя бы описание алгоритмического языка. При этом требуются точные описания как текстов, так и их интерпретации. Рассмотрим существующие варианты.

  1. Сама программа-транслятор считается описанием языка. Тут сразу точно описаны и тексты (правильная программа — та, на которой транслятор не выдает ошибки), и их интерпретация (интерпретация программы — то, как исполняется ее текст после перевода транслятором).

    Именно так пытались поступать на заре программирования, когда, скажем, легендарный язык FORTRAN создавался одновременно с первым транслятором с данного языка.

  2. Определением языка считается формальная лингвистическая система (грамматика). Впервые этот подход был последовательно применен в Алголе. Встречавшиеся вам при изучении языков синтаксические диаграммы являются непосредственными потомками того, что было сделано в Алголе.
  3. Определением языка считается соответствие между структурными единицами текста и правилами интерпретации. Этот вариант был полностью реализован при определении языка Алгол 68.

Первый вариант — совершенно неудовлетворительный путь, поскольку всякое изменение в программе-трансляторе может полностью изменить смысл некоторых конструкций языка со всеми вытекающими отсюда последствиями.

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

Третий вариант работает только вместе со вторым, поскольку структурные единицы должны соединиться в синтаксически правильную систему. Он раскрывает еще одну сторону языка.

Таким образом, мы видим, что каждый язык имеет три стороны: синтаксис (второй вариант), семантика (третий вариант), прагматика (первый вариант).

Синтаксис алгоритмического языка — совокупность правил, позволяющая:

  1. формально проверить текст программы (выделив множество синтаксически правильных программ);
  2. разбить эти программы на составляющие конструкции и в конце концов на лексемы.

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

Под внешним окружением понимаются характеристики машины, на которой исполняется программа (точность представления данных, объем памяти, другие программы, которые можно использовать при выполнении данной, и т. д.), и потоки входных данных, поступающие в программу в ходе ее исполнения.

Прагматика алгоритмического языка — то, что связывает программу с ее конкретной реализацией. При этом, в частности, происходит следующее.

  1. Все определения становятся явными (изгоняются такие понятия, как "не определено", "определяется реализацией" и т. п.).
  2. Появляются дополнительные конструкции, описатели и др., обусловленные реализацией. Они обязательно учитывают:
    • особенности вычислительной машины и среды вычислений;
    • особенности принятой схемы реализации языка;
    • обеспечение эффективности вычислений;
    • ориентацию на специфику пользователей.

Прагматика иногда предписывается стандартом языка, иногда нет. Это зависит от того, для каких целей предназначены язык и его реализация.

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

Синтаксис

Синтаксис — самая простая и самая разработанная часть описания алгоритмического языка.

Грамматика определяется системой синтаксических правил (чаще всего в описаниях языков называемых просто правилами). На уровне грамматики определяются понятия, последовательное раскрытие которых, называемое выводом, в конце концов дает их представление в виде последовательностей символов. Символы называются также терминальными понятиями, а все остальные понятия нетерминальными. Понятия бывают смысловые, т. е. языковые конструкции, для которых определено то или иное действие абстрактного вычислителя, и вспомогательные, нужные лишь для построения текста, но самостоятельного смысла не имеющие. Минимальные смысловые понятия соответствуют лексемам. Некоторые понятия вводятся лишь для того, чтобы сделать текст читаемым для человека. Минимальные из них (они подобны знакам пунктуации) естественно считать вспомогательными лексемами.

Но даже задача полного описания синтаксиса достаточно сложна и требует выделения подзадач.

Синтаксис принято разделять на две части:

  • контекстно-свободную грамматику (КС-грамматику) языка;
  • правила задания контекстных зависимостей (например, соответствия между описаниями и именами).

Понятие контекстно-свободной грамматики стало первым строгим понятием в описаниях практических алгоритмических языков. За понятием КС-грамматики при внешней его простоте стоит достаточно серьезная теория. Эта грамматика представляется во многих формах (синтаксические диаграммы, металингвистические формулы Бэкуса-Наура либо расширенные металингвистические формулы) и, как правило, сопровождает систематизированное изложение конкретного языка. Каждое такое конкретное представление КС-грамматики достаточно просто, и может быть изучено по любому учебнику программирования.

Содержательно можно охарактеризовать КС-грамматику языка как ту часть его синтаксиса, которая игнорирует вопросы, связанные с зависимостью интерпретации лексем от описаний имен в программе.

Контекстные зависимости сужают множество правильных программ. Например, правило "все идентификаторы должны иметь описания в программе" указывает на то, что программа с неописанными именами не принадлежит данному языку (хотя она и допустима с точки зрения контекстно-свободного синтаксиса).

Неоднократные попытки формально описывать контекстные зависимости при определении языков показали, что эта задача гораздо более сложная, чем задание контекстно-свободного синтаксиса. Вдобавок ко всему, даже такие естественные правила, как только что представленное, при формальном описании становятся громоздкими и весьма трудными для понимания человека. По этой причине в руководствах редко прибегают к формализации описаний контекстных зависимостей (одним из немногих исключений является Алгол 68).

Пример 4.2.1. Требование о том, что каждое имя должно быть описано (в частности, в языках Pascal и C), конкретизируется в следующей форме.

  • Для каждого имени должно быть описание, в котором оно встречается.
  • Это описание должно стоять либо в данном, либо в охватывающем его блоке и предшествовать в тексте программы использованию данного имени.
  • Два описания одного и того же имени в одном и том же блоке не считаются ошибкой лишь в том случае, если первое из них является предварительным упоминанием, а второе — полноценным описанием.
  • Если есть несколько описаний одного и того же имени в разных блоках, действующим считается то из них, которое стоит в самом внутреннем блоке.
  • Если действующее описание определяет имя как глобальное, то оно не должно противоречить никакому другому глобальному описанию того же имени, встречающемуся в других блоках программы.

Такая совокупность требований достаточна для того, чтобы человек мог проверить по тексту программы, как в данном месте понимается данное имя.

В практических описаниях языков и в курсах программирования обычно довольствуются неформальным, но достаточно точным описанием контекстных зависимостей. Приведем пример такого описания.

Семантика

Мы определили семантику как соответствие между синтаксически правильными программами и действиями абстрактного исполнителя. Но остается вопрос, как задавать это соответствие. Семантика чаще всего определяется индукцией (рекурсией) по синтаксическим определениям.

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

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

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

Реализованный язык всегда является прагматическим компромиссом между абстрактной моделью вычислений и возможностями ее воплощения.

Прагматика

До сих пор речь шла об определении языка его абстрактным вычислителем. Прагматика задает конкретизацию абстрактного вычислителя для данной вычислительной системы. Большая часть прагматики размазана по тексту документации о реализации языка (эту часть прагматики программист варьировать не может). Например, прагматическим является замечание, что тип Longint в системе Visual C++ определяется как 32-разрядное двоичное число с фиксированной точкой, занимающее слово памяти.

Та часть прагматики, которую может варьировать программист, требует отдельного синтаксического оформления. В языке Pascal есть так называемые прагматические комментарии, например, 


21.01.2014; 12:06
хиты: 120
рейтинг:0
Точные науки
информатика
для добавления комментариев необходимо авторизироваться.
  Copyright © 2013-2024. All Rights Reserved. помощь