Синтаксис и семантика паскаль. Синтаксис программы Понятие лексики синтаксиса и семантики языка программирования

синтаксис (языка программирования или математической теории) как форму конструкций (программы или теории) и способов их комбинирования. Более точное определение синтаксиса будет сформулировано далее в ходе лекции.

Определим понятие синтаксиса более строго.

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

Забегая вперед, заметим, что значение конструкций языка программирования описывается и исследуется семантикой (о ней речь пойдет в следующей лекции), а вопросы и ценность практической применимости - прагматикой .

Основной задачей синтаксиса является определение формы и вида допустимых языковых конструкций. Эту задачу можно решить путем перечисления описаний всех языковых конструкций. Одним из механизмов такого описания является уже упомянутая нами нотация БНФ

Мы будем рассматривать параллельно БНФ -формализации синтаксиса ламбда-исчисления и языка программирования SML . В последнем случае мы ограничимся базовым набором конструкций языка, подчеркнув такие существенные возможности, как кортежи ( tuples ) и let-выражения .

Для формирования правильного понимания роли и места синтаксиса в исследовании языков программирования рассмотрим обобщенную схему трансляции исходного текста программы (написанной, например, на языке программирования SML ) в машинный код.

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

По завершении лексического анализа выполняется так называемая процедура синтаксического разбора текста программы, которая представляет собой проверку корректности синтаксиса текста, написанного на языке программирования. Эта процедура, возможно, включает выполнение проверки корректности типизации в той или иной форме.

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

Рассмотрим синтаксис языка программирования SML в сравнении с синтаксисом ламбда-исчисления .

Для большей наглядности и сопоставимости формализаций синтаксиса обоих языков (языка формальной математической теории и языка программирования) будем использовать единую нотацию, а именно, БНФ .

Прежде всего, необходимо договориться об обозначениях.

Рассмотрим традиционные обозначения БНФ и поясним смысл каждого из них.

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

Определяющий символ "::=" отделяет определяемую конструкцию от составляющих ее ранее определенных базовых конструкций.

Определяемая конструкция записывается слева от "::=" в угловых скобках "<" и ">" .

Альтернативы (возможные варианты) конструкций перечисляются по вертикали.

Цитирование (подобно тому, как мы цитировали специальные символы, заключая их в двойные кавычки) не имеет обозначения.

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

Поясним смысл приведенных обозначений.

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

Форма Бэкуса-Наура (БНФ)

Форма Бэкуса-Наура (БНФ) была впервые применена при описании Алгола-60. БНФ совпадает по сути с нотацией КС-грамматик, отличаясь лишь обозначениями. Предусмотрены следующие метасимволы:

<> - служат для выделения нетерминалов - понятий языка. | - «или». Разделяет альтернативные правые части правил. - «есть по определению». Заменяет стрелку, используемую при записи продукций КС-грамматик.

Терминальные символы записываются как есть, никаких специальных способов их выделения не предусмотрено. Вот пример определений на БНФ, взятый из спецификации Алгола-60 - «Модифицированного сообщения»:

<простое арифметическое выражение> ::= <терм> 1 Окак операции типа сложения> <терм> | <простое арифметическое выражение> <знак операции типа сложения> <терм> <знак операции типа сложения> ::= + | -

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

Синтаксические диаграммы

Синтаксическая диаграмма - это направленный граф с одним входным ребром и одним выходным ребром и помеченными вершинами. Синтаксическая диаграмма задаёт Формальный язык. Цепочка пометок при вершинах на любом пути от входного ребра к выходному - это цепочка языка, задаваемого синтаксической диаграммой. Поэтому можно считать, что синтаксическая диаграмма - это одна из форм порождающей грамматики автоматных языков. Синтаксические диаграммы и конечные автоматы имеют тесную связь: любой автоматный язык задаётся синтаксической диаграммой и обратно, по любой синтаксической диаграмме можно построить конечный автомат(в общем случае недетерминированный), распознающий тот же язык, который задаёт диаграмма.

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

Таким образом, синтаксические диаграммы могут служить не только для порождения, но и для распознавания автоматных языков. Диаграммы стали популярны после выхода книги К. Йенсен и Н. Вирта «Паскаль». Они использованы в первой ее части - «Руководстве» - компактном учебнике языка. На рис. 3.1 показана одна из имеющихся там диаграмм.

Расширенная форма Бэкуса-Наура

Как уже говорилось, отсутствие в нотации формальных грамматик (и БНФ) средств явного задания повторений создает ряд трудностей. Во-первых, определения оказываются сложными для понимания, недостаточно наглядными из-за обилия рекурсий. Во-вторых, возникают проблемы с тем, что грамматики, дающие подходя- щие семантические деревья, оказываются леворекурсивными. При описании Модулы-2 и Оберона Н. Вирт использовал расширенную Бэкуса-Наура форму (РБНФ). Главные модификации касаются введения скобок { и} для повторений, а [ и ] - для обозначения необязательного вхождения цепочек терминалов и нетерминалов в правые части правил. Соглашения относительно обозначений терминалов и нетерминалов также изменены, что не столь принципиально. В дальнейшем мы будем пользоваться именно РБНФ. Вот как она определяется в спецификации Оберона-2: Варианты разделяются знаком |. Квадратные скобки [ и ] означают необязательность записанного внутри них выражения, а фигурные скобки { и } означают его повторение (возможно, 0 раз). Нетерминальные символы начинаются с заглавной буквы (например, Оператор). Терминальные символы или начинаются малой буквой (например, идент), или записываются целиком заглавными буквами (например, begin), или заключаются в кавычки (например, ":="). К этому следует добавить, что в роли знака «есть по определению» в РБНФ используется «=», а каждое правило заканчивается точкой. Вот так может быть определен синтаксис идентификатора (имени) с помощью РБНФ:

Имя = Буква { Буква | Цифра }.

Являясь метаязыком, РБНФ должна быть пригодна для описания языков, имеющих практический интерес. В том числе с помощью РБНФ может быть определен и синтаксис самой РБНФ:

Синтаксис = { Правило }. Правило = Имя "=" Выражение Выражение = Вариант { "I" Вариант }. Вариант - Элемент { Элемент }. Элемент = Имя | Цепочка | "{" Выражение "}" | "[" Выражение "]" | "{" Выражение "}". Цепочка = """ { символ) """ | """{ символ } """.

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

Описания синтаксиса языков семейства Си

Си (англ. C) - стандартизированный процедурный язык программирования, разработанный в начале 1970-х годов сотрудниками Bell Labs Кеном Томпсоном и Денисом Ритчи как развитие языка Би. Си был создан для использования в операционной системе UNIX. С тех пор он был портирован на многие другие операционные системы и стал одним из самых используемых языков программирования. Си ценят за его эффективность; он является самым популярным языком для создания системного программного обеспечения. Его также часто используют для создания прикладных программ. Несмотря на то, что Си не разрабатывался для новичков, он активно используется для обучения программированию. В дальнейшем синтаксис языка Си стал основой для многих других языков. Для языка Си характерны лаконичность, современный набор конструкций управления потоком выполнения, структур данных и обширный набор операций.

В знаменитой книге Б. Кернигана и Д. Ритчи описание синтаксиса языка Си дано в нотации, которая эквивалентна БНФ, но использует другие соглашения об обозначениях терминалов и нетерминалов, альтернативных правых частей правил, необязательных конструкций. Нетерминалы записываются курсивом, терминалы - прямым шрифтом. Альтернативные части правил выписываются в столбик по одному в строке или помечаются словами «one of» (один из). Необязательные части сопровождаются подстрочным индексом «opt (от optional) - необязательный; «необ» - в некоторых русских пере- водах). Левая часть правила записывается отдельной строкой с отступом влево. Вот пример определений конструкций языка Си:

Составной оператор {список описанийopt список операторовopt } список операторов оператор оператор список операторов

Как видим, из-за отсутствия явного способа выражения повторений, определе- ния изобилуют рекурсией. Аналогичная нотация с минимальными изменениями использована для описа- ния синтаксиса языков-потомков Си: Си++, Ява, Си#. Вот выдержка из стандарта ЕСМА-334 на язык Си#:

Block: {Statement-listopt} statement-list: statement statement-list statement

Специального названия эта нотация, судя по всему, не имеет. И представляется, как минимум, странной. Она неудобна не только для чтения, но и для обработки на компьютере. Ее использование при описании новых языков трудно объяснить чем-либо, кроме дурно понятой необходимости следовать традициям.

Особенности языка Си

  1. Имеет простую языковую базу, из которой вынесены в библиотеки многие существенные возможности, вроде математических функций или функций управления файлами;
  2. Имеет ориентацию на процедурное программирование, обеспечивающую удобство применения структурного стиля программирования;
  3. Имеет систему типов, предохраняющую от бессмысленных операций;
  4. Использование препроцессора для, например, определения макросов и включения файлов с исходным кодом;
  5. Имеет непосредственный доступ к памяти компьютера через использование указателей;
  6. Имеет минимальное число ключевых слов;
  7. Передача параметров в функцию по значению, а не по ссылке (при этом передача по ссылке выполняется с помощью указателей);
  8. Указатели на функции и статические переменные;
  9. Имеет области действия имён;
  10. Записи - определяемые пользователем собирательные типы данных (структуры), которыми можно манипулировать как одним целым;

Пример программы "Hello world " на Си

main() { printf("Hello, World!\n"); } #include int main() { printf("Hello, World!\n"); return 0; }

Описания синтаксиса языка Ада

Ада(Ada) - язык программирования, созданный в 1979-1980 годах в результате проекта, предпринятого Министерством обороны США с целью разработать единый язык программирования для встраиваемых систем (то есть систем управления автоматизированными комплексами, работающими в реальном времени). Имелись в виду, прежде всего, бортовые системы управления военными объектами (кораблями, самолётами, танками, ракетами, снарядами и т. п.). Перед разработчиками не стояло задачи создать универсальный язык, поэтому решения, принятые авторами Ады, нужно воспринимать в контексте особенностей выбранной предметной области. Язык назван в честь Ады Лавлэйс.Исследования, выполненные в начале и середине 1970-х годов, показали, что если Пентагон будет использовать единый язык программирования для решения всех своих задач вместо примерно 450 языков и их диалектов, то появится возможность получить огромную экономию средств (около 24 млрд долл. за период с 1983-го по 1999 год).Язык Ада основан на идеях структурного программирования и обеспечивает поддержку разработки сложных многомодульных программ, высокую степень машино-независимости и переносимости.При проектировании языка в первую очередь внимание акцентировалось на надежности и эффективности - язык создавался специально для разработки больших программных комплексов реального времени для встроенных систем, к которым предъявляются высокие требования надежности.

Особенности

Ада - это структурный, модульный, объектно-ориентированный язык программирования, содержащий высокоуровневые средства программирования параллельных процессов. Синтаксис Ады унаследован от языков типа Algol или Паскаль, но расширен, а также сделан более строгим и логичным. Ада - язык со строгой типизацией, в нём исключена работа с объектами, не имеющими типов, а автоматические преобразования типов сведены к абсолютному минимуму.

Осбенности синтаксиса

  1. Программы модульные, механизм контроля импорта-экспорта описаний между модулями включает две разные директивы: одну для подключения другого модуля (with), другую - для импорта его описаний (use). Также существует возможность переименовать модуль при импорте (rename) - этот вариант позволяет использовать для обозначения пакета более удобные программисту идентификаторы.
  2. Пакеты (один из типов модулей) могут содержать заголовок и личную часть - то, что содержится в ней, не экспортируется и другим модулям недоступно.
  3. Поддерживается механизм обобщённых (настраиваемых) модулей: пакетов, процедур и функций, позволяющих описывать обобщённые алгоритмы обработки данных без указания конкретного типа.
  4. Развитая система типов, как встроенных, так и порождаемых программистом. Есть множество способов создания новых типов, язык поддерживает два разных понятия: «подтип» и «производный тип». Переменные типа и подтипа совместимы, переменные типа и его производного типа - нет.
  5. Развитые средства обращения к процедурам и функциям: поддерживаются входные и выходные параметры, передача фактических параметров в произвольном порядке с указанием имён формальных, параметры со значениями по умолчанию.
  6. Поддерживается переопределение процедур, функций и операторов - создание нескольких вариантов процедуры, функции или оператора с одним и тем же именем, но различными сигнатурами (типами и количеством параметров).
  7. Встроенные в язык конструкции поддержки параллельного программирования: поддерживаются понятия «задача» (параллельно выполняемый фрагмент программы), «вход задачи» (средство синхронизации и коммуникации параллельно выполняющихся задач), поддерживается механизм «рандеву» (протокол взаимодействия параллельно выполняемых задач через вход одной из них), имеется оператор выбора SELECT для организации условного межпотокового взаимодействия (выбора параллельной задачи, с которой следует взаимодействовать, в зависимости от готовности к рандеву и некоторых других условий).

Контекстно-свободные грамматики языков Aда-83 и Ада-95 определены с помощью варианта БНФ, в который добавлены обозначения повторений и необязательных частей. Названия нетерминалов записываются обычным шрифтом с использованием знака подчеркивания, если название составное, а зарезервированные слова - жирным шрифтом. Поскольку ни квадратные, ни фигурные скобки в Аде не используются, как не используется и знак «|» (все это метасимволы), никакого специального обозначения для терминалов не предусмотрено. Определение синтаксиса оператора if, взятое из стандарта Ада-95, выглядит так:

If_statement::= if condition then sequence_of_statements {elsif condition then sequence_of_statements} end if;

Интересная и полезная особенность: синтаксические правила структурных конструкций представлены в виде, соответствующем их рекомендованному форматированию в программах (разделение на строки, отступы).

Для удовлетворения требованиям надёжности язык построен таким образом, чтобы как можно большее количество ошибок обнаруживалось на этапе компиляции. Кроме того, одним из требований при разработке языка была максимально лёгкая читаемость текстов программ, даже в ущерб лёгкости написания. Результатом такого подхода стал несколько «тяжеловесный» синтаксис и множество ограничений, отсутствующих в наиболее распространённых промышленных языках (С и C++) и часто воспринимаемых профессиональными программистами как избыточные, например, та же строгая типизация. Это привело к формированию представления об Аде как о сложном, малопонятном и неудобном в использовании языке.

Пример программы "Hellow world" на Аде

with Ada.Text_IO; procedure Hello is use Ada.Text_IO; begin Put_Line("Hello, world!"); end Hello;

Определение синтаксиса Кобола и ПЛ/1

Кобол (COBOL, COmmon Business Oriented Language ), язык программирования третьего поколения (первая версия в 1959), предназначенный, в первую очередь, для разработки бизнес-приложений.Разработчиком первого единого стандарта Кобола являлась Грейс Хоппер (бабушка Кобола). К 1997 году активно использовалось около 240 миллиардов строк кода на Коболе. Около 90 % финансовых транзакций в мире обрабатывается кодом на Коболе, и 75 % коммерческой обработки данных написано на Коболе. Общая стоимость используемого в настоящее время коболовского кода оценивается в 2 триллиона долларов США. До сих пор ежегодно пишутся миллиарды новых строк кода на Коболе.

Своеобразная система обозначений, являющаяся примером ранних нотаций, была применена при описании языков Кобол и ПЛ/1. Вот пример - определение формата глагола MOVE в Коболе:


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

Особенности языка Кобол

  1. Грамоздкость, многословность
  2. Хооршие, современные средства для работы со структурами данных и файлами, что обеспечило ему долгую жизнь в бизнес-приложениях(по крайней мере, в США).
  3. Обеспечивает наглядную и достаточно компактную запись алгоритмов в форме, независимой от конкретных машин, предназначенных для решения задач.
  4. Содержит большое колличество команд,которые представляют собой сложные комплексы типовых подпрограмм, обеспечивающих решение планово-экономических задач.

Пример программы "Hello world " на Коболе

IDENTIFICATION DIVISION. PROGRAM-ID. HELLO-WORLD. * ENVIRONMENT DIVISION. * DATA DIVISION. * PROCEDURE DIVISION. PARA-1. DISPLAY "Hello, world.". * EXIT PROGRAM.

ПЛ/1 -(PL/I, Programming Language I - «Язык программирования номер один») - разработанный в 1964 году язык программирования, созданный для научных, инженерных и бизнес-ориентированных вычислений. Он содержит такой широкий набор синтаксических конструкций и встроенных функций, что, вероятно, не существует ни одного компилятора, поддерживающего все возможности языка ПЛ/1. ПЛ/1 поддерживает рекурсию и структурное программирование, и его основная область применения - обработка данных

Основные свойства ПЛ/1

  1. Свободный синтаксис
  2. Ключевые слова и идентификаторы нечувствительны к регистру
  3. По умолчанию (в классических мэйнфреймовских версиях - всегда) передача параметров по ссылке
  4. Поддержка сложных структур с объединениями (в терминологии языка Паскаль - записи с вариантами)
  5. Чрезвычайно развитая система встроенных типов данных, при этом возможность неявных преобразований между большинством из них
  6. Несколько видов динамического выделения памяти
  7. Очень обобщенные операторы со многими вариантами синтаксиса
  8. Строго определённая семантика управляющих конструкций
  9. Операции с массивами
  10. Развитый механизм исключительных состояний
  11. Поддержка на уровне языка мультизадачности и асинхронного ввода-вывода
  12. Поддержка на уровне языка сложных методов доступа для ввода-вывода
  13. Очень развитый препроцессор, фактически сам являющийся подмножеством ПЛ/1

Пример программы "Hello world" на ПЛ/1

Test: procedure options(main); declare My_String char(20) varying initialize("Hello, world!"); put skip list(My_String); end Test;

Алфавит языка

Первоначальный алфавит ПЛ/1 включал 60 символов:

$ @ # A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 = + - * / () , . " % ; : ¬ & | > < _ ? пробел

Была предусмотрена возможность работы и с более ограниченным 48-символьным алфавитом, в который не входили:

@ # ; : ¬ & | > < _ ? -

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

Литература

  1. Свердлов С.З. Языки программирования и методы трансляции: Учебное пособие. - СПб.: Питер, 2007. - 638 с.: ил.

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

    Множество информации или «смыслов», характеризующее план содержания данного языка;

    Множество « текстов », т.е. последовательностей физических сигналов, которые характеризуют план выражения данного языка;

    Отображение, определенное на множестве текстов и ставящее в соответствие каждому элементу этого множества некоторые элементы множества смыслов, а также обратное отображение.

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

Элементами множества текстов являются тексты или предложения языка, подчиняющиеся строгим правилам построения.

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

Важнейшей задачей является изучение перевода с одного языка на другой как точного алгоритмического процесса. Задачей перевода с языка А на язык В является отображение множества текстов языка А в множество текстов языка В, оставляющее инвариантным смысловой образ любого текста. Перевод может быть семантическим или формальным, Для того, чтобы лучше представить себе эти два способа, введем следующие обозначения:

Т А – множество текстов языка А ,

Т В – множество текстов языка В ,

S – множество смыслов языков А и В (для простоты считаем, что смысловые множества языков совпадают),

f А – функция, отображающая Т А в S ,

f B – функция, отображающая S в Т В .

    Семантический (смысловой) перевод:

f А : Т А S f B : S Т В

Пусть имеется некоторый текст t Т А , тогда:

    f А (t ) = s S

    f B (s ) t’ Т В .

Итак, переводом текста t Т А является текст t Т В .

    Формальный перевод.

Этот способ заключается в явном задании алгоритма вычисления функции, являющейся суперпозицией функций f А и f B . Обозначим эту суперпозицию через I AB .

I AB = f B (f А (t )).

3.2. Нормальные формы Бекуса

Определение : Язык, описывающий свойства другого языка, называют метаязыком .

Так, метаязыком, описывающим русский язык, может быть тот же самый русский язык или другой разговорный язык, например английский. Описание языков программирования обычными средствами оправдано только в том случае, если оно используется лишь для изучения этих языков программистами-пользователями. В настоящее время используется ряд языков для описания синтаксиса алгоритмических языков для дальнейшей обработки и изучения математическими средствами. Это так называемые метасинтаксические языки . Разрабатываются также специальные языки для описания семантики – метасемантические языки .

Наиболее распространенным метасинтаксическим языком являются нормальные формы Бекуса (или металингвистические формулы). Основное назначение форм Бекуса заключается в представлении в сжатом и компактном виде строго формальных и однозначных правил написания основных конструкций описываемого языка программирования.

Классы объектов, которые используются в формах Бекуса:

    Цепочка основных символов языка.

    Имена конструкций описываемого языка, или так называемые металингвистические переменные . Значение металингвистических переменных – это цепочки основных символов описываемого языка.

    Металингвистическая связка :: = . Она соединяет левую и правую части формулы.

Каждый вариант представляет собой цепочку, состоящую из металингвистических переменных и основных символов. Для того, чтобы построить определяемую формулой конструкцию, нужно выбрать некоторый вариант построения из правой части формулы и, используя соответствующие формулы, подставить вместо каждой металингвистической переменной некоторые цепочки основных символов. Варианты правой части формулы разделяются металингвистической связкой |, имеющей значение «или». Металингвистическая переменная обозначается словами, заключенными в угловые скобки < >, которые поясняют смысл описываемой конструкции.

Числа определяются в языке при помощи следующих правил:

    <число>:: = <число без знака> | + <число без знака>| – <число без знака>

    <число без знака> :: = <десятичное число> | <порядок> | <десятичное число> <порядок>

    <десятичное число> :: = <целое без знака> | <правильная дробь> | <целое без знака> <правильная дробь>

    <порядок> :: = e <целое>

    <правильная дробь> ::= .<целое без знака>

    <целое> ::= <целое без знака> | + <целое без знака> | – <целое без знака>

    <целое без знака> :: = <цифра> | <целое без знака> <цифра>

    <цифра> :: = 0|1|2|3|4|5|6|7|8|9

Пример 7: Вывод по формулам числа 1.5 e -2

<число>, <число без знака>, <десятичное число> <порядок>, <целое без знака> <правильная дробь> <порядок>, <цифра> <правильная дробь> <порядок>, 1 <правильная дробь> <порядок >, 1. <целое без знака> <порядок>, 1. <цифра> <порядок>, 1. 5 <порядок>, 1. 5e<целое>, 1. 5 e- <целое без знака>, 1. 5e- <цифра> , 1. 5 e-2 .

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

У каждого языка программирования есть синтаксис и семантика. Синтаксис - это совокупность формальных правил написания про­грамм на данном языке, семантика - это смысловое значение напи­санного.

Важным элементом синтаксиса является алфавит языка, который представляет собой набор всех допустимых в языке символов.

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

Например, в Turbo Pascal используются следующие зарезервиро­ванные слова: and, asm, array, begin, case, const, constructor, destructor, div, do, downto, else, end, file, for и др.

При наборе программы эти слона отображаются на экране белым цветом, напоминая нам, что они являются ключевыми.

Идентификаторы, или имена, могут присваиваться константам, переменным, меткам, типам, объектам, процедурам, функциям, модулям, программам, полям записей, иными словами, всему тому, что может быть поименовано. Важно познакомиться с правилами оформ­ления идентификаторов. Любые ошибки в написании имен приведут к синтаксической ошибке, и программа не будет выполняться.

Типы данных - важнейшее понятие языка, поскольку все объекты языка характеризуются типами, которые в значительной степени определяют операции над ними, а также вид «компьютерного» пред­ставления соответствующих данных. В языке существует ряд стан­дартных типов данных, целый, вещественный, символьный, логический и пр. Для каждого типа есть правила их обозначения. Эти обозначения пишутся вслед за именем.

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

Любой язык программирования имеет целый ряд встроенных функ­ций, т.е. готовых программ, одно обращение к которым по их имени приводит к получению результата, например sin (х), cos(x), log(x) и т.д. Напомним, что функция sqrt (х) обеспечивает нахождение квадратно­го корня из указанного аргумента.

Алгоритм, записанный на языке программирования, называется программой.

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


Любая программа выполняется в результате ее трансляции - пере­вода записи операторов на язык компьютера. Каждый оператор в про­грамме после трансляции будет представлен набором кодов команд. Эти команды выполняются в оперативной памяти компьютера.

Все константы и переменные размещаются в своих ячейках памяти в соответствии с присвоенными им идентификаторами - именами.

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

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

Операторы языка программирования позволяют приступить к на­писанию простейших программ с использованием типовых алгорит­мических конструкций.

Математическая запись формулы, записанная по правилам языка программирования справа от знака присваивания, называется арифметическим выражением. Арифметические выражения используются повсеместно при работе с компьютером - в программах-калькуляторах, электронных таблицах, что будет рассмотрено в дальнейшем. Важную роль в записи арифметического выражения играют встроенные функции, которые сами представляют собой команды для компьютера, требующие вы­числения, а также скобки, позволяющие четко определить порядок операций в арифметическом выражении, в том числе для оформления дробного выражения с помощью деления числителя на знамена­тель.

Ранее вы познакомились с основными алгоритмическими конструк­циями: линейной, разветвляющейся и циклической. Для реализации этих конструкций используются соответствующие операторы языка программирования. Синтаксис (правила) записи операторов в различ­ных языках программирования могут несколько отличаться. В связи с этим можно использовать список правил оформления операторов языка - неотъемлемую часть ПО (системы) языка программирования, представленную в разделе «Помощь». Часто в системе языка програм­мирования автоматически воспроизводится типовой оператор при наборе первых символов оператора, а пользователю требуется его под­править. Рассмотрим основные операторы, реализующие типовые ал­горитмические конструкции.

Оператор присваивания. Этот оператор работает так: результат вычисления выражения в правой части требуется присвоить в качестве значения переменной Y. Именно потому, что данный оператор выполняет функции не толь­ко вычисления, но и присваивания, в левой его части не может быть выражения, а только имя одной переменной - ячейки памяти ком­пьютера, в которую производится запись результата вычисления.

Оператор ввода данных. Этот оператор размещает данные в опе­ративной памяти компьютера. Имена переменных, записанных в опе­раторе INPUT в произвольном порядке, получают значения, вводимые с клавиатуры в этом же порядке, т.е. первой переменной соответству­ет первое введенное значение, второй - второе и т.д. Синтаксис опе­ратора в общем виде будем называть его форматом.

Оператор вывода. Этот оператор предназначен для вывода резуль­татов или на экран монитора или на принтер.

Существуют два вида операторов (команд) перехода. Оператор безусловного перехода передает управление к другой команде всегда, вне зависимости от каких бы то ни было условий.

Оператор условного перехода передает управление только в случае истинности некоторого условия, а в противном случае - просто игно­рируется.

Смысл этого оператора состоит в том, что если условие истинно, то выполняется оператор или группа операторов, следующих за словом THEN, а если условие ложно, то выполняется оператор или группа операторов, следующих за словом ELSE (иначе). Конструкция ELSE здесь заключена в квадратные скобки. По правилам описания форматов это означает ее необязательность. В случае отсут­ствия в формате конструкции ELSE оператор выполняет также дей­ствия: если условие истинно, то выполняется оператор или группа операторов, следующих за словом THEN, а в противном случае - опе­ратор, следующий за оператором IF в программе. Если используется группа операторов, то они разделяются двоеточиями.

Для реализации циклических алгоритмических конструкций ис­пользуется оператор цикла, в языке Basic это «связка» операторов FOR и NEXT. Первый из них является начальным и главным оператором. Он открывает собой тело цикла, т. е. группу операторов, которые будут циклически выполняться фиксированное число раз.

Любой язык программирования состоит из трех частей:

● Алфавит.

● Синтаксис.

● Семантика

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

  1. Алфавит языка Си

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

1. Латинские строчные и прописные буквы: a, b, …, z и A, B, …, Z

2. Цифры: 0, 1, …, 9

3. Символ подчеркивания: _

4. Пробел (код 32)

5. Специальные символы: +, -, * и др.

6. Составные символы, воспринимаемые как один символ: <=, >= и др.

7. В комментариях и строковых константах допустимо использование кириллицы.

  1. Понятие о типе

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

● Тип определяет множество значений, которые может принимать данное.

● Тип определяет перечень операций, которые можно применять к данным.

● Каждое значение может относиться только к одному типу.

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

  1. Система типов языка Си Система типов языка Си

В соответствии с одной из систем классификации все типы языка Си делят на следующие четыре категории:

void ,

● скалярные,

● агрегатные.

Остановимся вначале кратко на каждой из четырех категорий типов.

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

Следует отметить, что void является зарезервированным словом. Оно используется для следующих целей:

● В качестве типа значения, возвращаемого функцией. Если из заголовка функции следует, что типом значения, которое она возвращает, является void , то это означает, что функция не возвращает значения. В этом случае она может использоваться подобно процедуре такого языка, как Паскаль.

● Зарезервированное слово void в языке используется для указания на то обстоятельство, что функция не имеет параметров.

В качестве примера применения типа void может служить объявление библиотечной функции clrscr(), которая не имеет возвращаемого значения и не принимает параметров:

void clrscr(void );

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

В стандарте языка С99 к скалярным типам относятся следующие виды типов:

● арифметические,

● логический,

● указатели,

● перечисления.

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

Арифметические типы составляют большую группу типов. В ней можно выделить три части:

● вещественные,

● комплексные.

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

Каждая из оставшихся разновидностей арифметических типов включает в себя достаточно большое количество отдельных типов. К числу основных (базовых) арифметических типов относят следующие типы. Для целочисленных типов базовыми типами считаются типы char иint , а для вещественных типов –float иdouble . Обращает на себя внимание тот факт, что символьный тип (типchar ) в языке Си рассматривается как разновидность целочисленного типа. Это обстоятельство можно рассматривать как проявление ослабленной типизации, которое присуще языку Си.

Базовые арифметические типы могут быть модифицированы. Для целей модификации служит ряд зарезервированных слов, к числу которых относятся:

signed (знаковый),

unsigned (беззнаковый),

long (длинный),

short (короткий).

С учетом модификаторов можно написать 17 разновидностей арифметических типов.

Основным целочисленным типом в языке Си является тип int . Это аппаратно-зависимый тип. Размер, который занимает данное, относящееся к этому типу, зависит от размера машинного слова конкретной среды программирования.

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

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

● массивы,

● структуры,