Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
TP_Book_Nizhyn.doc
Скачиваний:
94
Добавлен:
03.12.2018
Размер:
3.4 Mб
Скачать

1.2 Формальний опис синтаксису мови sipl

Для опису синтаксису мов зазвичай використовують БНФ (Форми Бекуса-Наура). Програми (або їх частини) виводяться із метазмінних (нетерміналів), які записуються у кутових дужках. Метазмінні задають синтаксичні класи. В процесі виводу метазмінні замінюються на праві частини правил, що задають ці метазмінні. Праві частини для однієї метазмінної розділяються знаком альтернативи « | ». Процес породження припиняється, якщо всі метазмінні замінено на термінальні символи.

Синтаксис мови SIPL можна задати за допомогою наступної БНФ:

Таблиця 1.2

Ліва частина правила –

метазмінна

(дефінієндум)

Права частина правила

(дефінієнс)

Ім’я

правила

<програма> ::=

begin <оператор> end

NP1

<оператор> ::=

<змінна>:=<вираз> |

<оператор> ; <оператор>|

if <умова> then <оператор> else <оператор> |

while <умова> do <оператор> |

begin <оператор> end |

skip

NS1

NS2

NS3

NS4

NS5

NS6

<вираз> ::=

<число> | <змінна> | <вираз> + <вираз> | <вираз><вираз> | <вираз> * <вираз> | <вираз> ÷ <вираз> | (<вираз>)

NA1

NA7

<умова> ::=

true | false | <вираз> < <вираз> |

<вираз><вираз> | <вираз> = <вираз> | <вираз><вираз> | <вираз> > <вираз> | <вираз><вираз> | <умова><умова> | <умова><умова> |  <умова> | (<умова>)

NB1

NB12

<змінна> ::=

M | N | . . .

NV1–…

<число> ::=

. . . –1 | 0 | 1 | 2 | 3 | . . .

NN1–…

Наведена БНФ задає мову SIPL як набір речень (слів), які виводяться з метазмінної <програма>. Точне визначення виводу буде подано пізніше, зараз тільки відмітимо, що вивід можна подати у вигляді дерева.

Щоб переконатись у синтаксичній правильності програми треба побудувати її вивід. Зокрема, для нашої програми GCD маємо наступне дерево виводу.

Малюнок 1.1. Дерево синтаксичного виводу програми gcd

Побудоване дерево синтаксичного виводу дозволяє стверджувати синтаксичну правильність програми GCD. Дійсно, якщо записати зліва направо послідовність усіх термінальних символів, то отримаємо програму GCD, що говорить про її вивідність у БНФ мови SIPL, тобто про її синтаксичну правильність.

Аналізуючи далі наведену БНФ можна відзначити, що вона досить просто описує основні конструкції мови SIPL. Але зворотною стороної цієї простоти є неодзначність цієї БНФ. Наприклад, вираз X+Y*Z має два різних дерева виводу, що ведуть до різних семантик (малюнок 1.2). Тому неоднозначність БНФ значно ускладнює семантичний аналіз програм.

Малюнок 1.2. Дерева синтаксичного виводу виразу X+Y*Z

Однозначності побудови дерева синтаксичного виводу можна досягти введенням пріоритетів операцій та правил асоціативності для операцій одного пріоритету. Слід відзначити, що в математиці при описі пріоритетів, як правило, не розрізняють синтаксичний і семантичний аспекти, тому часто говорять, що пріоритети задають порядок виконання операцій (семантичний аспект), замість того, щоб говорити про порядок структурного аналізу виразу (синтаксичний аспект). Такий розгляд об’єкту, коли не виокремлюються його різні аспекти та складові, часто називають синкретичним. У випадку мови SIPL однозначність аналізу може порушуватись при формуванні операндів операцій (синтаксичних конструкторів) різного типу. Будемо виокремлювати три типи операцій:

  • арифметичні (бінарні операції +, –, *, ) ,

  • бульові (бінарні операції порівняння <, , =, , , >, бінарні операції диз’юнкції  та кон’юнкції  та унарна операція заперечення ),

  • операторні (присвоєння, оператори послідовного виконання « _;_ », умовний оператор if_then_else_ та оператор циклу while_do_).

Тут символ підкреслення позначає операнд (або параметр) оператора. Перші дві групи операцій є традиційними, як і їх пріоритети. Третя група потребує певного пояснення. Справа в тому, що наприклад, синтаксична конструкція виду if b then S1 else S2; S3 може аналізуватись по-різному. Одне трактування може відносити до умовного оператора (його else-частини) послідовність операторів S2; S3, інше трактування – тільки один оператор S2. Різні трактування будуть задавати різну семантику. Те саме стосується і конструкцій виду while b do S1; S2 та S1; S2; S3. На семантику також впливає порядок застосування операцій одного типу. Так, вираз a1a2a3 можна аналізувати зліва-направо (лівоасоціативно), що можна подати як (a1a2)–a3, так і справа-наліво (правоасоціативно), що можна подати як a1–(a2a3) (=(a1a2)+a3). Щоб подолати неоднозначність синтаксичного аналізу будемо вважати, що всі бінарні операції лівоасоціативні (обчислюються зліва-направо) та що пріоритет операцій наступний (у порядку зменшення):

  1. множення * та ділення ,

  2. додавання + та віднімання –,

  3. операції порівняння <, , =, , , >,

  4. заперечення ,

  5. кон’юнкція ,

  6. диз’юнкція ,

  7. умовний оператор if_then_else_ та оператор циклу while_do_,

  8. послідовне виконання « ; » .

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

Є і друга можливість досягти однозначності БНФ мови SIPL – ввести нові метасимволи та нові правила їх визначення. Пропонуємо читачам зробити це самостійно.

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

Таблиця 1.3

Метазмінна

Синтаксична категорія

Нова метазмінна

<програма>

Prog

P

<оператор>

Stm

S

<вираз>

Aexp

a

<умова>

Bexp

b

<змінна>

Var

x

<число>

Num

n

В наведених позначеннях БНФ мови SIPL набуває наступного вигляду:

Таблиця 1.4

Ліва частина правила –

метазмінна

Права частина правила

Ім’я

правила

P::=

begin S end

P1

S::=

x:=a | S1 ; S2| if b then S1 else S2 | while b do S | begin S end | skip

S1S6

a::=

n | x | a1 + a2 | a1a2 | a1 * a2 | a1 ÷ a2 | (a)

A1A7

b::=

true | false | a1<a2 | a1a2 | a1= a2 | a1a2 | a1>a2 | a1a2 | b1b2 | b1b2 | b | (b)

B1B12

x::=

M | N | . . .

NV1–…

n::=

. . . –1 | 0 | 1 | 2 | 3 | . . .

NN1–…

Надалі будемо користуватися введеними позначеннями для запису структури програм та їх складових.

Дотепер ми користувались інтуїтивним розумінням БНФ. Разом з тим слід розуміти, що можуть існувати різні уточнення БНФ (про це буде мова в розділі з синтактики). Зараз приймемо, що БНФ дозволяє прописати індуктивне визначення синтаксичних категорій. Дійсно, наведена БНФ визначає шість синтаксичних категорій (класів): Num, Var, Aexp, Bexp, Stm, Prog. Вони можуть бути задані наступним індуктивним визначенням.

1. База індукції:

  • Num={…, -1, 0, 1, 2, 3, …},

  • Var={X, Y, …},

  • якщо nNum, то nAexp,

  • якщо xVar, то xAexp,

  • true, false належать Bexp,

  • skip належить Stm.

2. Крок індукції:

  • якщо a, a1, a2Aexp, то записи (вирази)

  • a1 + a2,

  • a1a2,

  • a1 * a2,

  • a1 ÷ a2,

  • (a)

належать Aexp,

  • якщо a1, a2Aexp, b , b1, b2Bexp, то записи (умови)

  • a1<a2,

  • a1a2,

  • a1=a2,

  • a1a2,

  • a1>a2,

  • a1a2,

  • b1b2,

  • b1b2,

  • b,

  • (b)

належать Bexp,

  • якщо xVar, aAexp, bBexp, S, S1, S2Stm, то записи (оператори)

  • x:=a,

  • S1 ; S2,

  • if b then S1 else S2,

  • while b do S,

  • begin S end

належать Stm,

  • якщо SStm, то запис begin S end належить Prog.

На підставі такого індуктивного визначення може бути задане визначення синтаксичних категорій за допомогою рекурентних співвідношень. Пропонуємо читачам зробити це самостійно.

Таким чином, можна стверджувати, що наведеними визначеннями синтаксис мови SIPL задато точно (формально).

Перейдемо тепер до визначення семантики мови SIPL.