- •Отчет по курсовой работе
- •Языки программирования и методы трансляции
- •1. Описание входного языка.
- •1.2. Формализм для описания синтаксиса.
- •1.3. Лексика языка.
- •1.3.1. Терминальные символы языка.
- •1.3.2. Лексемы и соглашения о разделителях.
- •1.3.4. Идентификаторы.
- •1.3.5. Константы.
- •1.3.6. Ключевые слова.
- •Int float bool void main goto length for if else scanf printf vector const true false
- •1.3.7. Строки.
- •1.4. Описания и типы.
- •1.4.2. Выражения.
- •1.4.3. Описания.
- •1.4.4 Правила преобразования типов.
- •1.5. Операторы.
- •4. Описание этапа синтаксического анализа
1.4.4 Правила преобразования типов.
Это перевод “низших” типов в “высшие” в интересах точности представления и непротиворечивости данных.
bool intfloat
если в операции принимают участие операнды типов разного уровня (например int и float), то выполняется преобразование к высшему из присутствующих типов (в это примере к float)
Подробнее о преобразованиях:
из bool в int или float: считаем, что true = 1, false = 0.
из int или float в bool: если число = 0 то false, иначе – true.
Операция |
Тип операнда1 |
Тип операнда2 |
Тип результата |
+ , -, * |
int |
int |
int |
+, -, * |
int |
float |
float |
+, -, * |
float |
int |
float |
+, -, * |
float |
float |
float |
/ |
int |
int |
float |
/ |
int |
float |
float |
/ |
float |
int |
float |
/ |
float |
float |
float |
Преобразование при выполнении операции присвоения.
Тип переменной |
Тип присваемого значения |
Тип переменной после выполнения оператора |
int |
int |
int |
float |
float |
float |
float |
int |
float |
vector |
vector |
vector, если вектора одинаковой размерности |
vector |
vector |
Ошибка, если вектора различной размерности |
vector |
float, int |
Ошибка |
float, int |
vector |
Ошибка |
int |
float |
int |
Преобразование типов для выполнения операции отношения.
Операнд1 |
Операнд2 |
Преобразование |
int |
int |
нет |
float |
float |
нет |
int |
float |
операнд1 float |
float |
int |
операнд2 float |
1.5. Операторы.
1.5.1. Пустой оператор.
Синтаксис :
<пустой_оператор> ::= ;
Пустой оператор не производит никаких действий, однако он необходим в некоторых языковых конструкциях (например, для реализации бесконечного цикла).
1.5.2. Оператор присваивания.
Синтаксис :
<переменная>::=<идентификатор>|<оператор_элемента_вектора>
<оператор_присваивания>::=<переменная>{'='<переменная>}'='<арифметическое_выражение>';'
Порядок выполнения оператора присваивания :
Вычисляется значение выражения в правой части, затем, справа налево, оно присваивается переменным в левой части, если тип значения и переменной совпадают. В противном случае присваивание не выполняется и пользователю выдается сообщение об ошибке.
1.5.3. Оператор перехода.
Синтаксис :
<оператор_безусловного_перехода>::='goto' <метка>';'
Оператор осуществляет безусловный переход к оператору, помеченому меткой. При отсутствии такового выдается сообщение об ошибке. Метка должна быть уникальной в пределах программы.
1.5.4. Оператор вывода.
Синтаксис :
<оператор_вывода>::='printf('<сообщение> {','<сообщение>} ');'
<сообщение>::={<строка>|<арифметическое_выражение>}
<строка>::=' " '{<символ>}' " '
<символ>::=<любой_ascii_символ>
Оператор осуществляет вывод в стандартный поток вывода, связаный обычно с экраном дисплея, значения переменной <переменная>.
1.5.5. Оператор ввода.
Синтаксис :
<оператор_ввода>::='scanf(' <идентификатор> {','<идентификатор>} ');'
Оператор ввода осуществляет чтение из стандартного потока ввода (клавиатуры) значения. В качестве идентификатора не может выступать имя константы.
1.5.6. Составной оператор.
Синтаксис :
<составной_оператор> ::= '{' {<оператор>} '}'
Операторы, входящие в состав составного оператора, выполняются в порядке их написания.
1.5.7. Условный оператор.
Синтаксис :
<условный_оператор>::='if('<логическое_выражение>')'<оператор>
['else'<оператор>]
Вначале вычисляется <логическое_выражение>. Если оно истинно, то выполняется первый <оператор> иначе второй оператор, если он присутствует.
1.5.8. Оператор цикла for.
Синтаксис :
<оператор_цикла>::='for(' [<оператор_присваивания> {','<оператор_присваивания>} ] ';' [<условное_выражение> {',<условное_выражение>' } ] ';' [<оператор_присваивания> {','<оператор_присваивания>} ] ')' <оператор>';'
Выполняется оператор <оператор>, пока истинны все условные выражения.
Полный синтаксис языка в форме Бэкуса-Наура.
<программа>::=[<глобальное_описание>] 'void main() {'<оператор> '}'
<глобальное_описание>::={<описание_константы>|<описание_переменной>}
<описание_константы>::='const' <описание_простой_константы>|'const' <описание_вектора_константы>
<описание_простой_константы>::=[<простой_тип>]<идентификация_простой_константы>{','<идентификация_простой_константы>}';'
<идентификация_простой_константы>::=<идентификатор>'='<арифметическое_выражение>
<описание_вектора_константы>::='vector'<идентификация_вектора_константы>{','
<идентификация_вектора_константы>}';'
<идентификация_вектора_константы>::=<идентификатор>'['<последовательность цифр>']={'<арифметическое_выражение>{','<арифметическое_выражение>}'}'
<описание_переменной>::=<описание_простой_переменной>|<описание_переменной_вектора>
<описание_простой_переменной>::=<простой_тип><идентификация_простой_переменной>{','<идентификация_простой_переменной>}';'
<идентификация_простой_переменной>::=<идентификатор>['='<арифметическое_выражение>]
<описание_переменной_вектора>::='vector'<идентификация_переменной_вектора>
{','<идентификация_переменной_вектора>}';'
<идентификация_переменной_вектора>::=<идентификатор>'['<целое_без_знака>']'['={'<арифметическое_выражение>{','<арифметическое_выражение>}’}’]
<простой_тип>::='int'|'float'|’bool’
<идентификатор>::=<буква> {<буква>|<цифра>}
<буква>::='_'|'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'|
|'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'
<арифметическое_выражение>::=[<знак>]<терм>|<арифметическое_выражение><знак><терм>
<терм>::=<множитель>|<терм>’*’<множитель>|<терм>’/’<множитель>
<множитель>::='('<аpифметическое_выpажение>')'|<идентификатор>|<константа>|
<оператор_длина_вектора>|<оператор_элемента_вектора>|’++’<идентификатоp>| ‘--‘<идентификатоp>|<идентификатоp>‘++’|<идентификатоp>‘--’
<знак>::='+'|'-'
<константа>::=<десятичная константа>|<вещественная константа>|<булевская константа>
<вещественная константа>::=<дробная константа>[<экспоненциальная часть>]
<дробная константа>::= [<знак>]<последовательность цифр>.[<последовательность цифр>]
<экспоненциальная часть>::=’e’[<знак>]<последовательность цифр>|’E’[<знак>]<последовательность цифр>
<последовательность цифр>::=<цифра>{<цифра>}
<десятичная константа>::=[<знак>]<последовательность цифр>
<булевская константа>::=’true’|’false’
<оператор>::=[<метка>':']<непомеченный_оператор>
<метка>::=<идентификатор>
<непомеченный_оператор>::={<оператор>}|’{‘{<оператор>}’}’|';'|<оператор_присваивания> |<условный_оператор>|<оператор_вывода>|<оператор_ввода>|<оператор_цикла>
|<оператор_безусловного_перехода>
<переменная>::=<идентификатор>|<оператор_элемента_вектора>
<оператор_присваивания>::=<переменная>{'='<переменная>}'='<арифметическое_выражение>';'
<условный_оператор>::='if('<логическое_выражение>')'<оператор>['else'<оператор>]
<оператор_вывода>::='printf('<сообщение> {','<сообщение>} ');'
<сообщение>::={<строка>|<арифметическое_выражение>}
<строка>::=' " '{<символ>}' " '
<символ>::=<любой_ascii_символ>
<оператор_ввода>::='scanf(' <идентификатор> {','<идентификатор>} ');'
<оператор_цикла>::='for(' [<оператор_присваивания> {','<оператор_присваивания>} ] ';' [<логическое_выражение> {',<логическое_выражение>' } ] ';'[<оператор_присваивания> {','<оператор_присваивания>} ] ')' <оператор>
<оператор_безусловного_перехода>::='goto' <метка>';'
<оператор_длина_вектора>::='length('< идентификатор>')'
<оператор_элемента_вектора>::=<идентификатор>'['<арифметическое_выражение>']'
<логическое_выражение>::=<логич_терм>{’||’<логич_терм>}
<логич_терм>::=<логич_терм>’&&’<логич_множитель>|<логич_множитель>
<логич_множитель>::=<идентификатор>|<арифметическое_выражение><отношение>
<арифметическое_выражение>|<арифметическое_выражение>|
’!’<логич_множитель>|’(‘<логическое_выpажение>’)’
<отношение>::='=='|'<'|'>'|'<='|'>=’
Описание этапа лексического анализа
Соотношение между токенами и лексемами для различных языковых конструкций
Токен |
Лексемы |
Языковая конструкция |
Токен |
Лексемы |
Языковая конструкция |
_ID |
str, count |
Идентификатор |
Знаки операции | ||
_NUM |
10, 1023 |
Целое без знака |
_HIGH |
-, + |
Арифметические |
_STR |
some string |
Символьная строка |
_INC |
++, -- | |
Ключевые слова |
_MID |
*, / | |||
_MAIN |
void main() |
Соответствующие ключевые слова |
_LOW |
+, - | |
_CONST |
const |
_NOT |
! |
Логические | |
_INT |
int |
_AND |
&& | ||
_FLOAT |
float |
_OR |
|| | ||
_VECTOR |
vector |
_LEN |
length |
Над векторами | |
_GOTO |
goto |
_REL |
<, <=, >=,>, !=, == |
Отношения | |
_FOR |
for |
_EQ |
= |
Присваивания | |
_IF |
if |
Специальные символы | |||
_ELSE |
else | ||||
_SCANF |
scanf |
. |
. |
Соответствующие символы | |
_PRINTF |
printf |
{ |
{ | ||
_TRUE |
true |
} |
} | ||
_FALSE |
false |
= |
= | ||
_BOOL |
bool |
( |
( | ||
|
|
) |
) | ||
|
|
[ |
[ | ||
|
|
] |
] | ||
|
|
; |
; | ||
|
|
, |
, | ||
|
|
“ |
“ | ||
|
|
_e |
e, E | ||
|
|
: |
: |
Описание типов лексем
Рассматриваемые лексическим анализатором лексемы могут относиться к одному из следующих типов:
- Идентификаторы – пользовательские имена объектов программы.
- Константы – числовые или логические значения, указанные явно.
- Ключевые слова – зарезервированные идентификаторы, имеющие строго определённый смысл.
- Знаки операций – символы, обозначающие унарные и бинарные операции.
- Специальные символы – квадратные и круглые скобки, запятые и т.д.
- Разделители – пробелы и символы новой строки. Если в тексте программы, в каком- либо месте, может стоять хотя бы один разделитель, то в этом месте может стоять сколько угодно разделителей.
Моделирование работы лексического анализатора
Например, имеем следующую программу на входе:
int a = 3;
bool b = true;
void main()
{
if (b && (a==3))
printf(“hello world”);
}
Сформированный выходной поток токенов:
_INT _ID = _NUM ; _BOOL _ID = _TRUE ; _MAIN { _IF ( _ID _AND ( _ID _REL _NUM ) ) _PRINTF ( “ _STR “ ) ; }
Сформированные таблицы идентификаторов:
Таблица переменных:
-
Смещение
Идентификатор переменной
Тип переменной
Значение переменной
1
"a"
int
3
2
“b”
bool
true
Таблицы меток и констант остались пустыми, поскольку в программе ни разу не встретилось объявлений идентификаторов этого типа.
В результате лексического анализа:
1. Производится разбор программы на отдельные лексемы.
2. Лексемы преобразуются к токенам.
3. Заполняются таблицы идентификаторов, определенных пользователем в программе.