Опубликован: 19.08.2004 | Уровень: для всех | Доступ: платный | ВУЗ: Национальный исследовательский ядерный университет «МИФИ»
Лекция 5:

Семантика основных конструкций языка программирования C#

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

Ide ={I|I - идентификатор};
Com ={C|C - команда};
Exp ={E|E - выражение}.

Совокупность всех возможных идентификаторов языка C# организуем в домен Ide, команд - в домен Com, и, наконец, выражений - в домен Exp.

Далее, сформулируем вычислительную модель на основе состояний программы языка C#, для наглядности систематизировав ее в виде следующей таблицы:

Таблица 16.1. Вычислительная модель на основе состояний программы языка C#
Параметр Домен Соотношение
Состояние State (s) State = Memory
Память Memory (m) Memory = Ide -> [Value + (unbound)]
Значение Value (v) Value = Int + Bool

Заметим, что состояние программы в произвольный момент времени определяется состоянием "памяти" абстрактной машины той или иной формы. При этом под памятью понимается отображение из домена идентификаторов в домен значений (т.е. аналог связывания переменной со значением в ламбда-исчислении). Для корректной обработки исключительных ситуаций, возникающих в случае свободных переменных, вводится дополнительный элемент unbound. Домен значений представляет собой дизъюнктную сумму доменов, содержащих существующие в языке C# типы Int и Bool.

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

Приведем семантические предложения для выражений языка программирования C#:

E : Exp -> [State -> 
	[[Value ( State] + {error}]];

E[E]s = (v,s'),

если

v - значение E в s,

s' - состояние после означивания ;

E[E]s = error,

если возникает ошибка несоответствия типов.

Из приведенных соотношений следует, что вычисление значения выражения языка программирования C# приводит к такому изменению состояния, что происходит связывание переменной со значением, либо (в случае невозможности связывания по причине несоответствия типов переменной и значения ) вырабатывается ошибка. При этом состояние программы изменяется с s на s'.

Приведем семантическое предложение для команд языка программирования C#:

С:Com->[State->[State+{error}]].

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

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

E[0]s=(0,s);
E[1]s=(1,s);

Как видно из приведенных соотношений, денотатами констант целочисленного типа являются значения этих констант (в форме упорядоченных пар вида " значение "-" состояние "), причем смены состояния программы не происходит. Рассмотрим семантические предложения для денотатов констант логического типа языка C#:

E[true]s=(true,s);
E[false]s=(false,s);

Как видно из приведенных соотношений, денотатами констант логического типа являются значения этих констант (в форме упорядоченных пар вида " значение "-" состояние "), причем смены состояния программы не происходит. Рассмотрим семантическое предложение для денотатов идентификаторов языка C#:

E[I]s=(m,I=unbound) error, -> (m,I,s).

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

Рассмотрим семантические предложения для денотатов выражений языка C#:

E[!E]s = (E [E] s=(v, s')) 
    (isBool -> (not v, s'), error), 
        error; 
E [E1=E2] s = (E [E1]s = (v1, s1)) -> 
    (E [E2] s1 = (v2, s2)) -> 
    (v1 = v2, s2), error), error;
E [E1+E2] s = (E [E1] s=(v1, s1)) -> 
    (E [E2] s1 = (v2, s2)) -> 
(IsNum v1 and IsNum v2 -> v1 + v2, s2),
    error),error),error.

Проанализируем полученные соотношения.

Денотатом отрицания выражения является отрицание его значения ; причем состояние программы изменяется. В случае несоответствия типов или небулевости выражения генерируется сообщение об ошибке.

Денотатом присваивания является присвоенное значение в новом состоянии. В случае несоответствия типов генерируется сообщение об ошибке.

Денотатом сложения является значение суммы в новом состоянии. В случае несоответствия типов генерируется сообщение об ошибке.

В качестве упражнения предлагается самостоятельно разработать семантические предложения для денотатов команд языка программирования C#.

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

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

Более того, сходство семантики рассмотренных нами конструкций ( команд и выражений ) языков программирования SMalL и C# весьма прозрачно и очевидно. Для иллюстрации справедливости этого утверждения достаточно сопоставить результаты исследования семантики рассматриваемых языков программирования.

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

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

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

Для более подробного самостоятельного ознакомления с тематикой лекции рекомендуется следующий список источников: [ 24, 35, 39, 42, 45, 53, 69, 73].