Архив3 / Kursach_po_SPO / Курсач по СПО / Курсач / Описание языка
.doc
2 Описание языка
Основные символы языка Pascal - буквы, цифры и специальные символы. Они составляют его алфавит. Pascal включает следующий набор основных символов:
-
26 латинских строчных и 26 латинских прописных букв:
A B C D E F G H | 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 | j k l m n o p q r s t u v w x y z
-
10 цифр:
0 1 2 3 4 5 6 7 8 9
-
знаки операций:
+ - * / = <> < > <= >= := @
-
ограничители:
. , ' ( ) [ ] (. .) { } (* *) .. : ;
-
спецификаторы:
^ # $
С помощью перечисленных символов образуются величины, выражения и операторы, которые составляют элементы языка. При построении элементов языка используются элементарные конструкции, которые включают в себя имена, числа и строки.
Имена (идентификаторы) называют элементы языка - константы, метки, типы, переменные, процедуры, функции, модули, объекты. Имя - это последовательность букв и цифр, начинающаяся с буквы. В именах может использоваться символ ‘_’ подчеркивание. Имя может содержать произвольное количество символов, но значащими являются 63 символа. Пробелы и специальные символы алфавита не могут входить в идентификатор.
Примеры правильных идентификаторов:
a |
MyProgramIsBestProgram |
external |
ALPHA |
date_27_sep_39 |
_beta |
Примеры неправильных идентификаторов:
1 Program // начинается цифрой
block#l // содержит специальный символ
My Prog // содержит пробел
mod // зарезервированное слово
В языке поддерживаются служебные слова: var, begin, end, or, and, not.Не разрешается в языке использовать в качестве имен служебные слова и стандартные имена, которыми названы стандартные константы, типы, процедуры, функции и файлы.
Для улучшения наглядности программы в нее могут вставляться пробелы. По крайней мере один пробел требуется вставить между двумя последовательными именами, числами или служебными и стандартными именами. Пробелы нельзя использовать внутри имен и чисел. Также поддерживаются условные операторы( if, then, else) и операторы присваивания(:=) .Тип переменной и тип выражения должны совпадать кроме случая, когда выражение относится к целому типу, а переменная -к действительному. При этом происходит преобразование значения выражения к действительному типу.
Комментарий - это строка (или несколько строк) из произвольных символов, заключенная в фигурные скобки: { комментарий }.Внутри самого комментария символы } встречаться не должны. Во время компилирования программы комментарии игнорируются. Следовательно, их можно добавлять в любом месте программы. Можно даже разорвать оператор вставкой комментария. Кроме того, все, что находится после ключевого слова end., завершающего текст программы, компилятор тоже воспринимает как комментарий.
Грамматика языка:
<прог>::= var <спис_опис>; begin <спис_опер><y> end
<спис_опис>::=<опис> | <спис_опис>; <опис>
<опис>::= <спис_перем>:integer
<спис_перем>::= id | <спис_перем>, id
<спис_опер>::= <опер> | <спис_опер>;<опер>
<опер>::= <опер_присваив> | <усл_опер>
<опер_присваив>::= id:= <выраж>
<выраж>::= id | lit
<усл_опер>::= if <слож_лог_выр> then <спис_опер2> | if <слож_лог_выр> then <спис_опер2> else <спис_опер2>
<спис_опер2>::= <опер> | begin <спис_опер><y>end
<y>::= ε | ;
Грамматика содержит левую рекурсию, а значит не является LL(k) ни для какого k. Устраним левую рекурсию:
<спис_опер>::= <опер> | <спис_опер>; <опер>
<спис_опер>::= <опер> | <опер> <спис_опер>'
<спис_опер>'::= ; <опер> | ; <опер> <спис_опер>'
<спис_перем>::= id | <спис_перем>, id
<спис_перем>::= id | id <спис_перем>'
<спис_перем>'::= , id | , id <спис_перем>'
<спис_опис>::= <опис> | <спис_опис> ; <опис>
<спис_опис>::= <опис> | <опис> <спис_опис>'
Найдём необходимое правило и выполним левую факторизацию:
<спис_опис>::= <опис> | <опис> <спис_опис>'
<спис_опис>::= <опис> <Х1>
<Х1>::= ε | <спис_опис>'
<спис_опис>'::= ; <опис> | ; <опис> <спис_опис>'
<спис_опис>'::= ; <опис><Х1>
<Х1>::= ε | <спис_опис>'
<спис_перем>::= id | id <спис_перем>'
<спис_перем>::= id <X2>
<X2>::= ε | <спис_перем>'
<спис_перем>'::= , id | , id <спис_перем>'
<спис_перем>'::= , id <X2>
<X2>::= ε | <спис_перем>'
<спис_опер>::= <опер> | <опер> <спис_опер>'
<спис_опер>::= <опер><X3>
<X3>::= ε | <спис_опер>'
<спис_опер>'::= ; <опер> | ; <опер> <спис_опер>'
<спис_опер>'::= ; <опер> <X3>
<X3>::= ε | <спис_опер>'
<усл_опер>::= if <слож_лог_выр> then <спис_опер2> | if <слож_лог_выр> then <спис_опер2> else <спис_опер2>
<усл_опер>::= if <слож_лог_выр> then <спис_опер2><X4>
<X4>::= ε | else <спис_опер2>
Докажем, что полученная после преобразования грамматики является LL(k) и определим k:
<прог>::= var <спис_опис>; begin <спис_опер><y> end |
var |
|
<спис_опис>::=<опис><X1> |
integer |
|
<опис>::= <спис_перем>:integer |
integer |
|
<спис_опис>'::= ; <опис><Х1> |
; |
|
<Х1>::= ε <Х1>::= <спис_опис>' |
; ; |
begin id |
<спис_опер>::= <опер><X3> |
id, i f |
|
<спис_опер>'::= ; <опер> <X3> |
; |
|
<опер>::= <опер_присваив> <опер>::=<усл_опер> |
id if |
|
<X3>::= ε <X3>::= <спис_опер>' |
; end ; |
end if id |
<спис_перем>::= id <X2> |
id |
|
<спис_перем>'::= , id <X2> |
, |
|
<X2>::= ε <X2>::= <спис_перем>' |
: ; |
|
<опер_присваив>::= id:= <выраж> |
id |
|
<выраж>::= id <выраж>::= l it |
id
|
|
|
|
|
<усл_опер>::= if <слож_лог_выр> then <спис_опер2><X4> |
if |
|
<X4>::= ε <X4>::= else <спис_опер2> |
; end else |
|
<спис_опер2>::= <опер> <спис_опер2>::= begin <спис_опер><y>end |
id if begin |
|
<y>::= ε <y>::= ; |
end ; |
|
Доказали, что грамматика принадлежит к LL (2). На базе этой грамматики может быть построен нисходящий линейный анализатор.