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

Я. П. – искусственный язык, разработанный человеком для облегчения процесса решения задачи с помощью ЭВМ. Этот язык позволяет либо описание алгоритма решения задачи – тогда он называется процедурно-ориентированным , либо постановку задачи в математической форме – проблемно-ориентированный.

Языки:

1. Универсальные (задачи из любой предметной области)

2. Специализированные (в узкой области)

Уровень Я.П.

1. Низкий (ассемблер, символьные ср-ва)

2. Высокий

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

По способу трансляции:

1. Компилятор

2. Интерпритатор

3. Генератор

Алфавит – фиксированный набор символов, из которых должен составляться текст.

Синтаксис – система правил, определяемых допустимые конструкции из символов алфавита. Его стараются описать формально.

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

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

Синтаксис = метаязык + синтаксические диаграммы

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

Набор символов метаязыка:

< > - угловые скобки (заключают языковые конструкции)

{ } – фигурные скобки (заключенные в них понятия встречаются нуль или более раз)

– квадратные скобки (заключенное понятие может быть опущено)

Вертикальная черта (альтернатива, «или», | ), ::=, =.

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

Из символов алфавита строятся смысловые языковые конструкции. Простейшими из них являются слова языка .

Лексема – слово языка, последовательность символов, не содержащая пробелов.

Виды лексем:

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

2. Ключевые слова – служебные идентификаторы, зафиксированные в ЯП; используются для образования законченных смысловых конструкций языка, их называют предложениями языка.

3. Оператор – описание, определение, нужное для передачи информации транслятору. Оператор используется для описания действий, является единицей действия.

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



Объекты программы.

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

Выделяют следующие:

1. Константы - неизменяемые величины.

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

2. Переменные

Одним из основных понятий языка Си является объект - именованная область памяти. Частный случай объекта – переменная. Отличительная особенность переменной состоит в возможности связывать с её именем различные значения, совокупность которых определяется типом переменной. При задании значения переменной в соответствующую ей область памяти помещается код этого значения. Доступ к значению переменной наиболее естественно обеспечивает её имя, а доступ к участку памяти возможен только по его адресу. Каждая переменная перед её использованием в программе должна быть определена, т.е. для переменной должна быть выделена память. Размер участка памяти, выделяемой для переменной, и интерпретация содержимого зависят от типа, указанного в определении переменной. Определены целочисленные типы: char – целый длиной не менее 8 бит, short int – короткий целый, int - целый, long – длинный целый. Каждый из целочисленных типов может быть определен либо как знаковый signed либо как беззнаковый unsigned. Стандартом языка введены следующие вещественные типы: float – одинарной точности, double – удвоенной точности, long double – максимальной точности.

3. Функции.



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

Общий вид определения объекта

Тип имя [инициализатор];

Объекты класса static по умолчанию получают значение 0, кл. extern - не получают.

Объект определяется только один раз . По определению устанавливаются атрибуты объекта, выделяется память для него, имя объекта, связанное с адресом области памяти. Если есть инициализатор, то еще и начальное значение.

Понятие типа данных

Тип данного – это совокупность информации о значении величины, которая позволяет использовать эту величину при решении задачи на компьютере.

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

Переменные можно инициализировать в месте их описаний.

Система типов - это особая система, по которой организуются данные, используемые прикладными решениями. Система типов позволяет представить информацию реального мира в терминах, "понятных" для Я.П.

Понятие простого типа.

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

Значение неделимо ни на какие части

Операции над всем значением в целом.

Делятся на:

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

Доопределяемые программистом - Программист сам определяет множество допустимых значений

Простыми скалярными типами, предопределенными в Си (их называют базовыми типами), являются:

– целые типы: char, int, long int;

– плавающие типы: float, double, long double.

Целый тип char используется еще и для представления значений символов (символьного типа). Целые типы имеют две формы – знаковую (signed) и беззнаковую (un-signed). В сокращенном виде signed может быть опущено.

Состоит из:

множество допустимых значений

множество допустимых операций

размер оперативной памяти, выделяемой для хранения (char - 1б, int - 2б, long - 4б)

внутреннее представление значения (целое положительное число - двоичным значением, отрицательное - двоичным дополнением и т.п.)

структура значения

Сложные типы

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

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

Сложный тип строится по следующим правилам .

1. Элемент сложной структуры может иметь как простую, так и сложную структуры. Таким образом, значения сложных типов в общем случае имеют иерархическую структуру, на самом нижнем уровне ко-торой элементы только простого типа (при этом уровень вложенности может ограничиваться или нет).

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

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

4. Обращение (доступ) к элементам структуры может быть: – непосредственное (прямое) – вычисляемое (по индексу или месту в структуре) или не вычисляемое (по имени элемента); – последовательное – характерное для структур переменного раз-мера. Вид обращения определяется способом объединения компонентов в единую структуру.

5. Значение структуры может храниться либо в оперативной (внутренняя структура), либо во внешней памяти

Массивы, строки

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

Задание переменной регулярного типа (массива) имеет вид

<спецификация типа> <идентификатор> [<константное выражение>]

Здесь квадратные скобки являются терминальными символами.

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

Идентификатор – это имя переменной типа массив.

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

Многомерный массив – это массив, элементы которого типа массив. Задание многомерного массива:

<спецификация типа> <идентификатор> []…

Здесь K1 , K2,...,Kn – константные выражения. Причем K1 задает раз-мер массива по первому измерению, K2 – по второму измерению, а Kn – по n-му измерению. Например, описание x задает массив x, состоящий из k1 элементов. Каждый элемент x имеет тип массив, состоящий из k2 элементов. Иначе можно сказать, что x – это двумерный массив (матрица), где k1 – размер по первому измерению, т.е. количество строк в двумерном массиве – матрице; k2 – размер по второму измерению, т.е. количество столбцов в матрице. Таким образом, двумерный массив рассматривается как одномерный массив, каждый элемент которого также одномерный массив. Элементы матрицы хранятся в памяти ЭВМ по строкам.

Для обращения к элементам массива необходимо указать имя массива и место (индекс) элемента в структуре: имя массива [<индекс>] или имя массива [<индекс1>][<индекс2>]…[<индекс n>] соответственно для одномерного и n-мерного массивов. Индекс задается выражением, значение которого должно быть целого типа и определяет номер компонента. Значение индекса принадлежит диапазону от нуля до размера массива, уменьшенного на единицу.

Обратиться к элементу массива можно еще одним способом – используя для этого указатель. Указатель – это переменная, значением которой является адрес другой переменной, т.е. номер (адрес) единицы памяти, которая выделена для переменной. Указатель может ссылаться только на объекты заданного типа. Имя массива является константой-указателем на первый элемент массива.

Строки. Значением «строкового» типа является последовательность символов (слово «строковый» заключено в кавычки, так как в Си явно такой тип не определен и, говоря о строковом типе, мы имеем в виду тип данных, обладающий свойствами строкового типа). «Строковый» тип (или просто строка) в Си рассматривается как подмножество типа массив. Строка задается одномерным массивом, элементы которого есть символы, последний символ массива – „\0‟. Эта «нуль-литера» является признаком конца строки. Литера „\0‟, так же как и другие символы, входит в строку. Размер строки (количество символов) определяется решаемой задачей и ограничивается доступным объемом памяти.

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

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

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

Текст можно представить:

Двумерным массивом - матрицей, строка которой это слово текста, оканчивающееся символом конца строки-‘\0’. Количество столбцов равно максимальной длине слова плюс один (символ ‘\0’). Количество строк равно максимальному числу слов в тексте. Обращение к строке матрицы это обращение к слову. Чтобы создать такую структуру, надо читать текст посимвольно, помещая каждое очередное слово в новую строку матрицы и добавляя к слову символ ‘\0’.

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

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

9. Неоднородные типы (структура)

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

Программист сам описывает неоднородный (структурный) тип, задавая его «внутреннее строение»: количество элементов, их тип и имена. Описание неоднородного типа:

struct <имя структурного типа>

{ <определения элементов> };

Здесь struct – служебное слово – спецификатор структурного типа, <имя структурного типа> – идентификатор типа, произвольно выбираемый программистом (<имя структурного типа> может быть опущено), <определения элементов> – совокупность одного или более описаний объектов, каждый из которых определяет тип элемента, вводимого структурного типа.

Определение объекта (например, переменной) именованного структурного типа имеет вид struct <имя структурного типа> < список структур>;

или <имя структурного типа> < список структур> ; где < список структур> – список выбранных программистом имен структур.

Определять переменные структурного типа можно одновременно с описанием типа. Определение объекта неименованного структурного типа имеет вид:

{ <определения элементов> } < список структур>;

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

При определении структура может быть инициализирована . При определении объекта структурного типа ему выделяется память в таком количестве, чтобы могли разместиться данные всех элементов. Размер памяти в байтах, выделенный для структуры можно получить с помощью операции sizeof, например sizeof (struct point). Для обращения к элементам структуры используется уточненное имя (первичное выражение) вида <имя структуры> . <имя элемента структуры> Здесь точка означает операцию доступа к элементу структуры, у нее самый высокий приоритет. Уточненные имена элементов структур обладают всеми правами объектов соответствующих типов. Над элементами структуры можно выполнять операции, допустимые для их типа.

Структура может быть параметром функции и возвращаемым (основным) функцией значением.

Указатель

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

спецификатор-типа [ модификатор ] * описатель.

Спецификатор-типа задает тип объекта и может быть любого основного типа, типа структуры, смеси (об этом будет сказано ниже). Задавая вместо спецификатора-типа ключевое слово void, можно своеобразным образом отсрочить спецификацию типа, на который ссылается указатель. Переменная, объявляемая как указатель на тип void, может быть использована для ссылки на объект любого типа. Однако для того, чтобы можно было выполнить арифметические и логические операции над указателями или над объектами, на которые они указывают, необходимо при выполнении каждой операции явно определить тип объектов. Такие определения типов может быть выполнено с помощью операции приведения типов.

В качестве модификаторов при объявлении указателя могут выступать ключевые слова const, near, far, huge. Ключевое слово const указывает, что указатель не может быть изменен в программе. Размер переменной объявленной как указатель, зависит от архитектуры компьютера и от используемой модели памяти, для которой будет компилироваться программа. Указатели на различные типы данных не обязательно должны иметь одинаковую длину.

Для модификации размера указателя можно использовать ключевые слова near, far, huge.

Файлы.

Файловый тип – это тип, который связывает программу с внешними устройствами ЭВМ. Значение файлового типа представляет собой произвольной длины последовательность компонент.

Размер файла (т.е. длина последовательности) никак не оговаривается при объявлении файла и ограничивается только емкостью устройств внешней памяти. Для указания конца структуры используется признак конца файла (end of file).

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

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

Открывать и закрывать потоки;

Анализировать условие достижения конца потока (конца файла) и ошибки ввода-вывода;

Получать и устанавливать указатель текущей позиции в потоке;

Управлять буферизацией потока и размером буфера.

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

При открытии файла в текстовом режиме прочитанная из потока последовательность символов преобразуется, если это необходимо из символьного представления во внутреннее представление. Например, если при форматном вводе читается числовая информация, то происходит преобразование прочитанной последовательности символов в двоичное целое или число с плавающей точкой в соответствии со спецификацией формата; при форматном выводе числовой информации происходит преобразование из внутреннего представления числа в последовательность символов, изображающих число. Последовательность символов, хранящаяся в текстовом файле, может быть разбита на строки. При записи в текстовый поток символа новой строки ‘\n’ он заменяется последовательностью символов CR (“возврат каретки”) и LR (“перевод строки”). При

чтении из текстового файла последовательность символов CR и LR преобразуется в один символ новой строки ‘\n’.

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

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

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

Этот процесс продолжается пока не исчерпана форматная строка или не достигнут конец файла или не произошла ошибка. В первом случае функция возвращает количество объектов, получивших значение при вводе, при достижении конца файла – возвращает константу EOF, в случае ошибки – значение –1.

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

от реализации языка. Вывод заканчивается, когда исчерпана форматная строка или возникла ошибка. Функция возвращает число выведенных символов, а при ошибке отрицательное число.

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

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

Алфавит. Синтаксис и семантика:

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

Строчные и прописные латинские буквы:

Символ подчеркивания: «_» Пробел: « » Арабские цифры от 0 до 9:

Перечень знаков операций:

Последовательность ограничителей:

Спецификаторы:

Служебные слова:

Элементарные конструкции языка Паскаль: имена, числа, строки . Именами (или идентификаторами) называются элементы языка - метки, константы, переменные, типы, процедуры, модули, функции, объекты. Имя (идентификатор) в среде Турбо Паскаль включает в себя цифры, буквы латинского алфавита, символ подчеркивания. Отсутствует различие между прописными и строчными буквами (PROGRAM, Program и program - означает одно и то же).

На первом месте в идентификаторе не может стоять цифра (т.е. 1program - не правильно, program3 иprogram2file - такие идентификаторы допускаются). Символ «_» может находиться в любой позиции (т.е. _program,program_, program_file - допустимые идентификаторы). Идентификатор может иметь неопределенную длину, однако только первые 63 символа в нем значимые. Служебные (зарезервированные) слова не могут выступать в качестве имен.

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

В исходном коде программы комментарии заключают или в фигурные скобки»{ … }», или в скобки вида «(* … *)». Комментарии могут занимать неопределенное число строк. В языке Паскаль числа чаще представляются в десятичной системе счисления (целые и действительные). Положительный знак числа не учитывается, поэтому может быть опущен. Целые числа представляются в форме без десятичной точки:

395 -67 7808 +126

А действительные представляются в форме с десятичной точкой:

597.2 1.79 -5.526 8.0004

При случае допускается возможность записи числа с использованием десятичного порядка (обозначается E):

3E09 = 3*10^9 -5.34E6 = -5.34*10^6 29.3E-29 = 29.3*10^(-29)

программный синтаксис комбинаторный логика

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

Формализуем основные конструкции языка программирования SML посредством форм Бэкуса-Наура или БНФ (история их создания изложена во вступительной лекции).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

<выражение> ::= <константа> | <переменная> |

(<выражение> <выражение>) |

л <переменная> . <выражение>

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

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

  • 1. константы;
  • 2. переменной;
  • 3. двух выражений, заключенных в круглые скобки, т.е. знакомой нам операции аппликации ламбда-выражений;
  • 4. символа л, за которым следует переменная, точка и выражение, т.е. знакомой нам операции абстракции.

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

Для иллюстрации перечисленных выше тезисов рассмотрим важнейшие синтаксические категории языка программирования SML.

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

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

Комментарием назовем произвольный поясняющий текст к программе, который, согласно синтаксису языка SML, положено заключать в ограничители вида "(*" и "*)".

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

<выражение> ::= <идентификатор> | <литерал> |

<выражение> <выражение> |

<выражение> <идентификатор> <выражение>

Как видно из БНФ-формализации, синтаксически корректным выражением в языке программирования SML считается:

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

Продолжим обсуждение выражений.

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

if <выражение> then <выражение>

else <выражение> |

(<выражение> ... <выражение>) |

let <описание> in <выражение> end |

  • 1. три выражения, соединенные зарезервированными словами if ("если"), then ("тогда") и else ("в противном случае"), называемые условным выражением и фактически представляющие собой предикатную функцию, которая реализует выполнение второго выражения в случае истинности первого и выполнение третьего в противном случае;
  • 2. конечную последовательность выражений, заключенную в круглые скобки (или так называемый кортеж) и применяемую для структуризации данных;
  • 3. описание и выражение, соединенные зарезервированными словами let ("положим"), in ("в") и end ("конец"), которые определяют операцию подстановки описания в выражение с учетом всевозможных вхождений в него указанного фрагмента описания;
  • 4. выражение, заключенное в круглые скобки (как мы уже знаем, в ламбда-исчислении и комбинаторной логике эту операцию можно производить без ограничений) и используемое для явного указания приоритета операции.

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

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

Приведем соответствующую формализацию в терминах БНФ.

<описание> ::=

val < идентификатор > = < выражение > |

fun < идентификатор > < идентификатор > =

< выражение > |

local < описание > in <описание> end

Синтаксически допустимыми описаниями языка программирования SML, как следует из представленной БНФ, являются:

  • 1. идентификатор и выражение, соединенные зарезервированными словами val и "=", которые обозначают связывание идентификатора (переменной, константы или другого синтаксически допустимого объекта языка программирования) с тем или иным выражением;
  • 2. три идентификатора и выражение, соединенные зарезервированными словами fun и "=", которые обозначают связывание функции (обозначенной первым идентификатором) с параметром (обозначенным вторым идентификатором) с выражением, определяющим порядок вычисления значения;
  • 3. два описания, соединенные зарезервированными словами local, in и end, которые обозначают локальное определение первого описания в контексте второго.

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

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

Приведем соответствующую формализацию в терминах БНФ.

<тип> ::= int | bool |

<тип> * ... * <тип> |

<тип> -> <тип>

Как следует из представленной БНФ, синтаксически допустимыми типами языка программирования SML являются:

  • 1. целочисленные величины, обозначаемые зарезервированным словом int;
  • 2. логические значения, обозначаемые зарезервированным словом bool;
  • 3. кортежи - упорядоченные n-ки элементов определенных типов;
  • 4. функции - упорядоченные n-ки элементов определенных типов, соединенных зарезервированными символами "->".

Рассмотрим следующий пример, иллюстрирующий приписывание типов в языке SML. Константа типа кортеж вида (0,false,1,true) имеет тип (int*bool*int*bool).

Заметим, что варианты типов (1) и (2) являются элементарными, тогда как (3) и (4) представляют собой производные типы с явно указанной (или выводимой) структурой, откуда и происходит название "структурированный тип".

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

Рассмотрим подробнее синтаксические особенности основных видов литералов.

Приведем соответствующую формализацию в терминах БНФ.

<литерал> ::= <литерал целого типа> |

<литерал строкового типа> |

<литерал вещественного типа>

Как следует из представленной БНФ, синтаксически допустимыми типами литералов в языке программирования SML являются следующие:

  • 1. целочисленные литералы, имеющие тип int и лежащие в диапазоне от -230 до +230 (последнее обстоятельство связано с особенностями машинного представления данных);
  • 2. строковые литералы, имеющие тип string и представляющие собой алфавитно-цифровые последовательности символов в коде формата ASCII;
  • 3. вещественные литералы, имеющие базовый тип real, обобщенную форму вида M x 10E, где M - мантисса в диапазоне от -1 до +1, а E - порядок в соответствующем диапазоне.

Заметим, что значение (т.е. семантика) литералов в полной мере определяется их лексическим (а, значит, и синтаксическим) представлением.

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

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

<выражение> <выражение>

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

Проиллюстрируем аппликацию функции к аргументу в языке программирования SML следующим примером.

Рассмотрим функцию succ, которая задается определением

fun succ n = n+1;

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

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

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

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

Приведем соответствующую формализацию в терминах БНФ:

if <выражение> then <выражение> else <выражение>;

Как видно из БНФ-формализации, синтаксически корректное условное выражение состоит из трех подвыражений, соединенных зарезервированными словами if, then и else, уже упоминавшихся нами в ходе лекции.

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

Заметим также, что функции сравнения встроены в язык SML и имеют вид: "=" (равно), "<" (меньше), ">" (больше), "<=" (меньше или равно), ">=" (больше или равно), "<>" (не равно). Результатом вычисления любой из этих функций является логическое значение.

Проиллюстрируем синтаксис условного выражения следующим примером на языке SML:

if n>=10 then 1 else 0;

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

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

Рассмотрим структуру синтаксически допустимых конструкций, известных под названием let-выражений.

Приведем соответствующую формализацию в терминах БНФ:

let <описание> in <выражение> end;

Как видно из БНФ-формализации, синтаксически корректное let-выражение состоит из описания и выражения, соединенных зарезервированными словами let, in и end.

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

Проиллюстрируем синтаксис let-выражений примерами из языка программирования SML.

Рассмотрим следующие let-выражения:

let val n=2 in n+1 end;

let k=9876*8765 in (k-1, k, k+1) end;

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

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

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

Приведем формализацию синтаксически допустимого представления кортежа в терминах БНФ:

(<выражение>, ..., <выражение>)

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

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

Проиллюстрируем синтаксис конструкции кортежа примерами из языка программирования SML:

Пример 1: (1, 2*1, 2*2*1)

Пример 2: (1, true, 0, false)

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

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

Рассмотрим формализации синтаксически корректных описаний переменных и функций в терминах БНФ:

<описание> ::=

val <идентификатор> = <выражение>

<описание> ::=

fun <идентификатор> <идентификатор> =

<выражение>

Первое определение представляет собой описание переменной, второе - функции. При этом оба определения имеют сходную структуру.

Проиллюстрируем формальные описания переменных и функций следующими примерами:

Пример 1. val x=2;

Пример 2. fun fact n =

if n<2 then 1

else n * fact (n - 1);

Пример 3. fun f (x,y) = x*x + y*y;

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

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

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

  • · синтаксис языков функционального программирования достаточно близок к синтаксису формальных теорий, на которых они основаны (в частности, это справедливо для ламбда-исчисления и языка SML);
  • · БНФ являются актуальной и адекватной формализацией синтаксиса языка;
  • · язык программирования SML, в отличие от ранних языков функционального программирования, имеет ряд расширенных конструкций (кортежи, let-выражения и др.).

Синтаксис (программирование)

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

Чаще всего синтаксис проверяется на ранних стадиях компиляции. В интерпретируемых языках программирования проверка синтаксиса производится или в процессе интерпретации (выполнения), или в процессе предварительной компиляции в промежуточный код. Кроме того синтаксис может проверяться непосредственно при редактировании исходных текстов программ при использовании IDE .

Синтаксис записи функции

Синтаксис записи функции - жёсткое правило, которому должна удовлетворять запись кода функции ; форма записи функции. Если синтаксис функции будет неверен, компилятор вернет ошибку и программа не будет собрана, пока ошибка не будет исправлена.

К синтаксическим ошибкам записи функции относятся (неправильная сигнатура):

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

Wikimedia Foundation . 2010 .

Смотреть что такое "Синтаксис (программирование)" в других словарях:

    Синтаксис: В Викисловаре есть статья «синтаксис» Синтаксис (греч … Википедия

    Эта статья должна быть полностью переписана. На странице обсуждения могут быть пояснения. У этого термина существуют и другие значения, см. Программи … Википедия

    Объектно ориентированное программирование на Python программирование на Python с использованием парадигмы ООП: с самого начала Python проектировался как объектно ориентированный язык программирования. Содержание 1 Введение 1.1 … Википедия

    Шаблоны (англ. template) средство языка C++, предназначенное для кодирования обобщённых алгоритмов, без привязки к некоторым параметрам (например типам данных, размерам буферов, значениям по умолчанию). В C++ возможно создание шаблонов функций и … Википедия

    У этого термина существуют и другие значения, см. Конструктор. В объектно ориентированном программировании конструктор класса (от англ. constructor, иногда сокращают ctor) специальный блок инструкций, вызываемый при создании объекта.… … Википедия

    У этого термина существуют и другие значения, см. SSI. SSI (Server Side Includes включения на стороне сервера) несложный язык для динамической «сборки» веб страниц на сервере из отдельных составных частей и выдачи клиенту полученного HTML… … Википедия

Конспект урока

Два аспекта языков
  • У языка программирования есть два аспекта:
    • Синтаксис (правила написания кода, правописание, порядок слов)
  • Некоторые языки программирования имеют похожий синтаксис
  • Некоторые языки имеют экзотический, необычный синтаксис
  • Семантику сложно увидеть, она неявная
Синтаксис и семантика
  • В современных языках хороший код означает легко понятную семантику
  • Если понять то, что делает код сложно, то код не слишком хороший
  • Синтаксис легко изучать
  • Синтаксис необходимо знать, но этого недостаточно
Выбор языка
  • Не так важно с какого языка начинать
  • Вы будете переключаться на разные языки и использовать несколько языков и технологий одновременно. Такова реальность современного программирования.
  • Мы выбрали JavaScript, потому что он простой, очень популярный и работает почти везде.
  • JavaScript обычно используется для написания веб-сайтов, мобильных приложений, программного обеспечения для серверов и многого другого.
  • Этот сайт в эту самую секунду использует JavaScript.
  • Программы, написанные на JavaScript, запущены сейчас на ваших компьютерах.

Дополнительно

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

Транскрипт урока

Мы назвали систему нажимания кнопок "языком". Рычаг, видимо, это отдельная штука, он как команда "ЗАПУСТИТЬ". Мы вводим код кнопками и ЗАПУСКАЕМ его рычагом.

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

Можно считать, что у языка есть два... компонента или две особенности: грамматика и назначение. Языки программирования похожи в этом смысле, но поскольку они намного проще, чем человеческие, грамматика у них не на первом месте, но синтаксис - порядок слов и словообразование - важен. А для назначения, для понятия "смысл" программисты используют модное слово "семантика".

Попробуем сравнить язык магического ящика Тоты с каким-нибудь современным языком программирования.

У этого ящика очень сложный синтаксис, с символами Х и О сложно работать. А вот этот современный код выглядит... хмм, как английский язык! Этот синтаксис намного легче освоить, как минимум можно догадаться, что значит каждое слово.

Набор правил, который описывает как символы и слова могут использоваться - это синтаксис.

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

Семантику или смысл увидеть сложнее, потому что он неявный. Какое назначение у этого кода? Это огненная вспышка, как мы уже поняли. Какое назначение у этого кода? Возможно, вы догадались: он выводит на печать фразу задом наперед. Смысл, конечный результат запущенного кода - это семантика.

В современных языках программирования связь между кодом и его видимым назначением можно использовать, чтобы судить о качестве кода. Если вы смотрите на код и быстро улавливаете его назначение, то это хороший код. Если при взгляде на код у вас возникает мысль "что это, чёрт возьми, такое?!", вероятно, он не слишком хороший. Это подводит нас к важной идее: код пишется для людей. Компьютерам всё равно, легко ли читается код: для них любой код легкочитаемый.

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

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

Получается... программировать легко? Если компьютеры тупые и выполняют только то, что мы им говорим, а синтаксис языка программирования - простая штука, всё вместе должно быть достаточно лёгкой задачей, так?

Эмм... нет. Если честно, то программирование - не настолько лёгкая задача. Ну, да, написать школьное сочинение легко по сравнению с "Войной и миром". А докторская диссертация по квантовой физике - это вообще другой уровень. Так что не стоит обобщать. Любая деятельность из перечисленных - варианты письменного изложения, но сравнивать их и судить о "письменном изложении" не целесообразно. Программирование может быть простым, а может быть сложным, в зависимости от того, кто и что делает.

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

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

Последний момент, который мы затронем перед погружением - это, мм, какой язык выбрать? Их так много и это может казаться критическим моментом. Момент, конечно, критический, но не потому что "нужно принять окончательное решение, которое повлияет на всю оставшуюся жизнь", а потому что мы должны понимать, что выбор языка программирования - это как выбор инструмента для ввода текста, а не человеческого языка.

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

Язык нужно выбрать достаточно хороший, достаточно простой, известный и с хорошими возможностями. В процессе профессионального роста вы БУДЕТЕ переключаться между языками, использовать сразу несколько языков и технологий одновременно и это не будет для вас проблемой, так же как переход с печатной машинки на Microsoft Word - это не проблема.

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

Ну что, давайте начнем программировать!