Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курсовая работа4 / Курсовик 13 вар(ТЯП).doc
Скачиваний:
11
Добавлен:
01.05.2014
Размер:
862.72 Кб
Скачать

3. Описание синтаксического анализа

­3.1 Исходная порождающая КС-грамматика

S–начальный нетерминальный символ.

S->VOID MAIN ( )Instruction

S->VOID MAIN ( )

Instruction->InstExp

Instruction -> Comp_Instr }

Instruction -> If_Instr

Instruction -> For_Instr

Instruction -> Def_Instr

Instruction -> CIN >> _ID

Instruction -> COUT << InstExp

InstExp -> Expression ;

Comp_Instr -> { Foll_Ins

Comp_Instr -> {

Foll_Ins -> Foll_Ins Instruction

Foll_Ins -> Instruction

Expression -> Log_OR = Expression

Expression -> Log_OR x= Expression

Expression -> If_Exp

If_Exp -> Log_OR ? Expression : Expression

If_Exp -> Log_OR

Log_OR -> Log_OR || Log_AND

Log_OR -> Log_AND

Log_AND -> Log_AND && Equivalence

Log_AND -> Equivalence

Equivalence -> Equivalence _EOP N_Equivalence

Equivalence -> N_Equivalence

N_Equivalence -> N_Equivalence _COP Additional

N_Equivalence -> Additional

Additional -> Additional _AOP Multip

Additional -> Multip

Multip -> Multip _MOP Unar

Multip -> Unar

Unar -> # Unar

Unar -> _INC Unar

Unar -> Postfix

Unar -> New

Unar -> Delete

Postfix -> Postfix _INC

Postfix -> First_Exp

First_Exp -> (Expression)

First_Exp -> _ID

First_Exp -> Massive [Log_OR]

Massive -> _ID

Massive -> Massive [Log_OR]

First_Exp -> _ZCONST

First_Exp -> _RCONST

Type -> INT

Type -> FLOAT

New -> NEW Type ( First_Exp )

Delete -> DELETE _ID

New -> NEW [] Type ( First_Exp )

Delete -> DELETE []_ID

If_Instr -> IF ( Expression) Instruction

If_Instr -> IF ( Expression) Instruction ELSE Instruction

For_Instr -> FOR ( Def_Instr Expression ; Expression) Instruction

Def_Instr -> SeqSpecif_Types List_InitDef ;

SeqSpecif_Types -> Specif_Types

SeqSpecif_Types -> SeqSpecif_Types Specif_Types

Specif_Types -> Type

Specif_Types -> Specif_Enum

Specif_Types -> CONST

Specif_Enum -> ENUM { }

Specif_Enum -> ENUM _ID { }

Specif_Enum -> ENUM { Specif_Enum_List }

Specif_Enum -> ENUM _ID { Specif_Enum_List }

Specif_Enum_List -> ElemEnum_List

Specif_Enum_List -> Specif_Enum_List, ElemEnum_List

ElemEnum_List -> _ID = Expression

List_InitDef -> InitDef

List_InitDef -> List_InitDef InitDef

InitDef -> Defenitor

InitDef -> Defenitor Initor

Defenitor -> Directly_Initor

Defenitor -> PTR_struct Defenitor

Initor -> = Expression

Directly_Initor -> _ID

Directly_Initor -> Directly_Initor [ ]

Directly_Initor -> Directly_Initor [ Expression ]

PTR_struct->*

PTR_struct->*CONST

3.2) Разбиение на подграмматики

Главная подграмматика:

Имя терминала/нетерминала

Описание

Токен

PRG

Программа

INS

Инструкция

EXP

Инструкция-выражение

SOE

Составная инструкция

PIN

Последовательность инструкций

P1

Вспомогательная последовательность инструкций

i_f

Переход в подграмматику if/for

ino

Переход в подграмматику объявлений

exp

Переход в подграмматику выражений

voi

Ключевое слово

VOID

mai

Ключевое слово

MAIN

cin

Ключевое слово

CIN

cou

Ключевое слово

COUT

id

Идентификатор

_ID

>>

Знак ввода

>>

<<

Знак вывода

<<

(

Символ «(»

(

)

Символ «)»

)

{

Символ «{»

{

}

Символ «}»

}

;

Символ «;»

;

Грамматика простого предшествования.

Правила :

1) PRG->voimai( )INS

2) PRG->voimai( )

3) INS->EXP

4) INS->SOE}

5) INS->i_f

6) INS->ino

7) INS->cin>>id

8) INS -> cou << EXP

9) EXP -> exp ;

10) SOE -> { P1

11) SOE -> {

12) P1 -> PIN

13) PIN -> PIN INS

14) PIN -> INS

Подграмматика выражения:

Имя терминала/нетерминала

Описание

Токен

EXP

Выражение

IFE

Условное выражение

ORE

Выражение логического ИЛИ

ANE

Выражение логического И

EQL

Выражение равенства

NEQ

Выражение отношения

ADD

Аддитивное выражение

MUL

Мультипликативное выражение

UNE

Унарное выражение

POS

Постфиксное выражение

FIR

Первичное выражение

MAS

Выражение массива

NEW

New-выражение

DEL

Delete-выражение

TYP

Спецификатор простого типа

id

Идентификатор

_ID

zco

Целочисленная константа

_ZCONST

rco

Вещественная константа

_RCONST

new

new

NEW

del

delete

DELETE

int

Тип int

INT

flt

Тип float

FLOAT

inc

Автоинкремент и автодекремент

_INC

#

Унарный знак

#

eop

Операция проверки на равенство

_EOP

cop

Операция сравнения

_COP

aop

Аддитивная операция

_AOP

mop

Мультипликативная операция

_MOP

=

Присваивание

=

x=

Сокращённое присваивание

x=

?

Символ «?»

?

:

Символ «:»

:

||

Логическое ИЛИ

_OR

&&

Логическое И

_AND

(

Символ «(»

)

)

Символ «)»

(

[

Символ «[»

[

]

Символ «]»

]

Грамматика SLR(1).

Правила :

1) EXP -> ORE = EXP

2) EXP -> ORE x= EXP

3) EXP -> IFE

4) IFE -> ORE ? EXP : EXP

5) IFE -> ORE

6) ORE -> ORE || ANE

7) ORE -> ANE

8) ANE -> ANE && EQL

9) ANE -> EQL

10) EQL -> EQL eop NEQ

11) EQL -> NEQ

12) NEQ -> NEQ cop ADD

13) NEQ -> ADD

14) ADD -> ADD aop MUL

15) ADD -> MUL

16) MUL -> MUL mop UNE

17) MUL -> UNE

18) UNE -> # UNE

19) UNE -> inc UNE

20) UNE -> POS

21) UNE -> NEW

22) UNE -> DEL

23) POS -> POS inc

24) POS -> FIR

25) FIR -> ( EXP )

26) FIR -> id

27) FIR -> MAS [ ORE ]

28) MAS -> id

29) MAS -> MAS [ ORE ]

30) FIR -> rco

31) FIR -> zco

32) TYP -> int

33) TYP -> flt

34) NEW -> new TYP ( FIR )

35) NEW -> new [ ] TYP ( FIR )

36) DEL -> del id

37) DEL -> del [ ] id

Подграмматика if/for:

Имя терминала/нетерминала

Описание

Токен

I_F

Начальный символ

INI

Инструкция выбора

INF

Инструкция итерации

if

Ключевое слово

IF

els

Ключевое слово

ELSE

for

Ключевое слово

FOR

(

Символ «(»

(

)

Символ «)»

)

;

Символ «;»

;

exp

Переход в подграмматику выражений

ins

Переход в главную подграмматику

ino

Переход в подграмматику объявлений

Грамматика SLR(1).

Правила :

1) I_F -> INI

2) I_F -> INF

3) INI -> if ( exp ) ins

4) INI -> if ( exp ) ins els ins

5) INF -> for ( ino exp ; exp ) ins

Подграмматика объявлений:

Имя терминала/нетерминала

Описание

Токен

INO

Инструкция объявления

PST

Последовательность спецификаторов типов

STY

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

SST

Спецификатор простого типа

SEN

Спецификатор перечисления

SEE

Список элементов перечисления

DEP

Определение элемента перечисления

SIO

Список инициализирующих объявителей

IDE

Инициализирующий объявитель

DEF

Объявитель

INR

Инициализатор

NDE

Непосредственно объявитель

PTR

Ptr-оператор

EXP

Константное выражение

id

Идентификатор

_ID

con

Спецификатор const

CONST

int

Тип int

INT

flt

Тип float

FLOAT

enu

Тип enum

ENUM

,

Символ «,»

,

=

Символ «=»

=

[

Символ «[»

[

]

Символ «]»

]

{

Символ «{»

{

}

Символ «}»

}

*

Символ «*»

*

exp

Переход в подграмматику выражений

Грамматика SLR(1).

Правила :

1) INO -> PST SIO ;

2) PST -> STY

3) PST -> PST STY

4) STY -> SST

5) STY -> SEN

6) STY -> con

7) SST -> int

8) SST -> flt

9) SEN -> enu { }

10) SEN -> enu id { }

11) SEN -> enu { SEE }

12) SEN -> enu id { SEE }

13) SEE -> DEP

14) SEE -> SEE , DEP

15) DEP -> id = EXP

16) SIO -> IDE

17) SIO -> SIO IDE

18) IDE -> DEF

19) IDE -> DEF INR

20) DEF -> NDE

21) DEF -> PTR DEF

22) INR -> = EXP

23) NDE -> id

24) NDE -> NDE [ ]

25) NDE -> NDE [ EXP ]

26) PTR -> *

27) PTR -> * con

28) EXP -> exp

Описание ПОЛИЗ

Синтаксис

Семантика

Операнды

Оператор

m

DEFL

Определение метки m

m

BRL

Безусловный переход на метку m

a, m

BF

Переход на метку m, если a = “Ложь”

m

RET

Возврат к метке m

a

COUT

Вывод значения “a” на экран

a

CIN

Запрос на ввод с клавиатуры значения переменнойa

a, i1…in, k

SUBS

Вычисление адреса элемента массива a; ik - индексы;

k = n+1 - число операндов

a, b

:=

Оператор присваивания a:=b

a, b

+

Аддитивная операция a+b

a, b

-

Аддитивная операция a-b

a, b

*

Мультипликативная операция a*b

a, b

/

Мультипликативная операция a/b

a, b

AND

Операция логического И: a&&b

a, b

OR

Операция логического ИЛИ: a||b

a

NOT

Операция логического отрицания: !a

a

RNAME

Операция разыменования (обращения к объекту): *a

a

-u

Операция унарный минус.

a

INC

Инкремент a+1

a

DEC

Декремент a-1

a, b

<

a<bдля целых и вещественных значений

a, b

>

a> bдля целых и вещественных значений

a, b

<=

a<=bдля целых и вещественных значений

a, b

>=

a>=bдля целых и вещественных значений

a, b

==

a==bдля целых, вещественных значений и указателей

a, b

!=

a!=bдля целых, вещественных значений и указателей

a, b

SET

Назначает тип a для переменной b

a, b

CHTP

Преобразует тип выражения a к типу b

a

NEW

Создает новый объект уже известного типа и отводит для имени «а» место в соответствующей таблице

a

DEL

Удаляет объект из соответствующей таблицы.

3.3) Описание промежуточного языка

3.4) Неформальное описание перевода

1. Перевод условного оператора IF (Полная форма)

Входная конструкция:

IF(<Выражение>) THEN<Инструкция1>ELSE<Инструкция2>

ПОЛИЗ:

<Выражение>

m1 BF <Инструкция1>

m2 BRL m1 DEFL <Инструкция2>

m2 DEFL

2. Перевод условного оператора IF (Сокращённая форма)

Входная конструкция:

IF(<Выражение>)THEN<Инструкция>

ПОЛИЗ:

<Выражение> m1 BF <Инструкция>

m1 DEFL

3. Перевод оператора цикла FOR

Входная конструкция:

FOR ( <Инструкция объявления>; <Выражение1>;<Выражение2>)<Инструкция>

ПОЛИЗ:

<Инструкция объявления>

m1 DEFL<Выражение1>m4 BF

m3 BRLm2 DEFL <Выражение2>m1 RET

m3 DEFL<Инструкция>m2 RET

m4 DEFL

4. Перевод оператора вывода COUT

Входная конструкция:

COUT <<<Выражение> ;

ПОЛИЗ:

<Выражение> COUT

5. Перевод оператора ввода CIN

Входная конструкция:

CIN >>_ID ;

ПОЛИЗ:

_ID CIN

3.5) Построение атрибутных транслирующих грамматик

Так как в данной работе грамматики принадлежат классам грамматик SLR(1) и простого предшествования, то будет использоваться восходящий метод синтаксического анализа, поэтому на атрибутную транслирующую грамматику накладывается ограничение – она должна быть постфиксной. Построим S-атрибутную транслирующую грамматику:

  • Аргументами правила вычисления значения унаследованного атрибута символа из правой части правила вывода могут быть только унаследованные атрибуты символа из левой части и произвольные атрибуты символов из правой части, расположенные левее рассматриваемого символа.

  • Аргументами правила вычисления значения синтезированного атрибута символа из левой части правила вывода являются унаследованные атрибуты этого символа или произвольные атрибуты символов из правой части.

  • Аргументами правила вычисления значения синтезированного атрибута операционного символа могут быть только унаследованные атрибуты этого символа.

  • Все атрибуты нетерминалов синтезированные.

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

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

Главная подграмматика (простого предшествования):

Операционный символ

Атрибуты

Комментарий

{CIN}p

p - введенное пользователем значение

Вывод: a CIN

a - идентификатор

{COUT}p

p - выводимое на экран значение

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

Вывод: a COUT

a - выводимое выражение

1) PRG -> void main ( ) INS

2) PRG -> void main ( )

3) INS -> EXP

4) INS -> SOE }

5) INS -> i_f

6) INS -> ino

7) INSk,_t -> cin >> idq,t {CIN}p,t1

k<-p

q<-k

_t<-t1

t<_t

8) INS -> cou << EXPq,t {COUT}p,_t

p<-q

_t<-t

9) EXP -> exp ;

10) SOE -> { P1

11) SOE -> {

12) P1 -> PIN

13) PIN -> PIN INS

14) PIN->INS

Подграмматика выражения(SLR(1)):

Здесь и далее:

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

Пример:

Пусть a=6 - тип int

10,7 a a float_T CHTP +

Таким образом, сначала а будет приведена к типу float, а затем произойдет сложение.

float_T - указывает на типfloatв таблице.

Операционный символ

Атрибуты

Комментарий

{:=}a, b, x, y, vres, tres

a - значение первого операнда

b - значение второго операнда

x - тип первого операнда

y - тип второго операнда

vres - результирующее значение

tres - тип результирующего значения

Для вычисления vres и tres вызывается функция COUNT.

Входные параметры: a,b,x,y.

Выходные параметры: vres, tres.

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

Вывод: :=

Здесь и далее:

В случае несовместимости типов выдается ошибка и трансляция останавливается.

{x=COUNT}t1, a’, b’, x’, y’, vres’, tres

t1 - № типа операции в соответствующей таблице

a’ - значение первого операнда

b’ - значение второго операнда

x’ - тип первого операнда

y’ - тип второго операнда

vres’ - результирующее значение

tres’ - тип результирующего значения

Для вычисления vres и tres вызывается функция COUNTx.

Входные параметры: t1,a’,b’,x’,y’.

Выходные параметры: vres, tres.

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

Вывод: одно из - +,-,*,/

{BRL}m

m - метка, на которую будет произведен безусловный переход.

Если данная метка отсутствует в таблице меток, то вызывается функция NewLabel,которая создает метку и заносит ее в таблицу, возвращая адрес новой записи, который впоследствии получит атрибут.

Вывод: m BRL

{BF}m,val

m - метка, на которую будет произведен переход, в случае, если val = 0.

Если данная метка отсутствует в таблице меток, то вызывается функция NewLabel,которая создает метку и заносит ее в таблицу, возвращая адрес новой записи, который впоследствии получит атрибутm.

Вывод: m BF

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

{DEFL}m

m - метка, которая объявляется.

Если данная метка отсутствует в таблице меток, то вызывается функция NewLabel,которая создает метку и заносит ее в таблицу, возвращая адрес новой записи, который впоследствии получит атрибутm.

Функция IF_V вычисляет значение условного оператора присваивания.

Входные параметры: val,v1,v2.

v1 - значение первого выражения (ветка true) - если val!=0

v2 - значение второго выражения (ветка false) - если val=0

Выходные параметры:значение.

Функция IF_T вычисляет тип значения условного оператора присваивания.

Входные параметры: val,t1,t2.

Выходные параметры: тип.

Вывод: m DEFL

{OR}a, b, x, y, val, type

a - значение первого операнда

b - значение второго операнда

x - тип первого операнда

y - тип второго операнда

val - результирующее значение

type - тип результирующего значения

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

Для вычисления val вызывается функция OR_V.

Входные параметры: a,b.

Выходные параметры: val.

Для вычисления type вызывается функция OR_T.

Входные параметры: x,y.

Выходные параметры: type.

Вывод: OR

{AND} a, b, x, y, val, type

a - значение первого операнда

b - значение второго операнда

x - тип первого операнда

y - тип второго операнда

val - результирующее значение

type - тип результирующего значения

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

Для вычисления val вызывается функция AND_V.

Входные параметры: a,b.

Выходные параметры: val.

Для вычисления type вызывается функция AND_T.

Входные параметры: x,y.

Выходные параметры: type.

Вывод: AND

{EOP} a, b, _t1, x, y, val, type

a- значение первого операнда

b- значение второго операнда

_t1 - № типа операции в соответствующей таблице

x - тип первого операнда

y- тип второго операнда

vat- результирующее значение

type- тип результирующего значения

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

Для вычисления val вызывается функция EOP_V.

Входные параметры: a,b,_t1.

Выходные параметры: val.

Для вычисления type вызывается функция EOP_T.

Входные параметры: x,y,_t1.

Выходные параметры: type.

Вывод: одно из ==, !=

{COP} a, b, _t1, x, y, val, type

a- значение первого операнда

b- значение второго операнда

_t1 - № типа операции в соответствующей таблице

x - тип первого операнда

y- тип второго операнда

vat- результирующее значение

type- тип результирующего значения

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

Для вычисления val вызывается функция COP _V.

Входные параметры: a,b,_t1.

Выходные параметры: val.

Для вычисления type вызывается функция COP _T.

Входные параметры: x,y,_t1.

Выходные параметры: type.

Вывод: одно из <, >, <=, >=

{AOP} a, b, _t1, x, y, val, type

a- значение первого операнда

b- значение второго операнда

_t1 - № типа операции в соответствующей таблице

x - тип первого операнда

y- тип второго операнда

vat- результирующее значение

type- тип результирующего значения

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

Для вычисления val вызывается функция AOP _V.

Входные параметры: a,b,_t1.

Выходные параметры: val.

Для вычисления type вызывается функция AOP _T.

Входные параметры: x,y,_t1.

Выходные параметры: type.

Вывод: одно из +,-

{MOP} a, b, _t1, x, y, val, type

a- значение первого операнда

b- значение второго операнда

_t1 - № типа операции в соответствующей таблице

x - тип первого операнда

y- тип второго операнда

vat- результирующее значение

type- тип результирующего значения

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

Для вычисления val вызывается функция MOP _V.

Входные параметры: a,b,_t1.

Выходные параметры: val.

Для вычисления type вызывается функция MOP _T.

Входные параметры: x,y,_t1.

Выходные параметры: type.

Вывод: одно из *,/

{#} a, _t1, x, val, type

а - операнд

_t1 - № типа операции в соответствующей таблице

x - тип операда

val- результирующее значение

type- тип результирующего значения

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

Для вычисления val вызывается функция UNE _V.

Входные параметры: a,_t1.

Выходные параметры: val.

Для вычисления type вызывается функция UNE _T.

Входные параметры: x,_t1.

Выходные параметры: type.

Вывод: одно из -u,+, NOT, RNAME

{INC} a, _t1, x, val, type

а - операнд

_t1 - № типа операции в соответствующей таблице

x - тип операда

val- результирующее значение

type- тип результирующего значения

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

Вызываются те же функции UNE _V и UNE _T, что и для {#}, меняются только значения _t1. Для префиксной и постфиксной ++ и -- они различны, а отсюда различны и val.

Вывод: одно из INC, DEC

{ID} v1, t1, vres, tres

v1 - значени

t1 - тип

vres - выходное знычение

tres - выходной тип

Вызывается функция IDENT,чтобы найти идентификатор в таблице.

Вывод: a - переменная

{MAS}_v1,_t1,_x,_y, vres, tres

_v1 - накопленный список индексов

_t1 - тип подмассива

_x- значение текущего индекса

_y- тип текущего индекса

vres- выходное знычение (список индексов для выборки значения)

tres- выходной тип

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

Функция MAS добавляет индекс в список, если его тип структурно совпадает с типомint.

Вывод: a, i1…in, k SUBS

массива a; ik - индексы;k = n+1 - число операндов.

{RCO} vres, tres

v1 - значени

t1 - тип

vres - выходное знычение

tres - выходной тип

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

Вывод: a - вещественная константа

{ZCO} vres, tres

v1 - значени

t1 - тип

vres - выходное знычение

tres - выходной тип

Вызывается функция ZCONST,чтобы найти целочисленную константу в таблице и передать ее значение.

Вывод: a - целочисленная константа

{NEW} x, y, z,_z, vres, tres

x - значение выражения инициализации

y - тип выражения инициализации

z - тип новой переменной

_z - создание массива

vres - выходное знычение

tres - выходной тип

Функция NEW создает новый идентификатор, закрепляя за ним адрес в таблице, и производит неявное преобразование типов при инициализации, если необходимо и возможно.

Вывод: tres a SET a NEW

{DELETE}a, _z

а - имя удаляемого из таблицы идентификатора

_z - удаление массива

Проверка типа удаляемого объекта.

Уничтожение соответствующей записи в таблице.

Вывод: a DEL

Правила :

1) EXPv’,t’ -> ORE_v,_t = EXPv,t {:=}a, b, x, y, vres, tres

a<-_v

b<-v

x<-_t

y<-t

vres<- COUNT(a,b,c,d)

tres<- COUNT(a,b,c,d)

v’<- vres

t’<- tres

2) EXPv’,t’ -> ORE_v,_t x=t EXPv,t {x=COUNT}t1, a’, b’, x’, y’, vres’, tres’ {:=} a, b, x, y, vres, tres

a, a’<-_v

b’<-v

x, x’<-_t

y’<-t

vres’<- COUNTx(t1, a’,b’,c’,d’)

tres’<- COUNTx(t1, a’,b’,c’,d’)

b<-vres’

y<-tres’

vres<- COUNT(a,b,c,d)

tres<- COUNT(a,b,c,d)

v’<- vres

t’<- tres

3) EXP_v,_t -> IFEv,t

_v<-v

_t<-t

4) IFEv,t -> IFE_2q,val, v1,t1 EXPv2,t2 {DEFL}m2

m2<-q

v<- IF_V(val,v1,v2)

t<- IF_T(val,t1,t2)

4’) IFE_1m,__val -> ORE_val ? {BF}m1,val

m1<- NewLabel

m<-m1

__val, val<-_val

4’’) IFE_2m, val, _v1,_t1 -> IFE_1p,q EXPv1,t1 : {BRL}m2 {DEFL}m1

m2<- NewLabel

m<-m2

m1<-p

val<-q

_v1<-v1

_t1<-t1

5) IFE_v,_t -> OREv,t

_v<-v

_t<-t

6) ORE_v,_t -> OREv1,t1 || ANEv2,t2 {OR}a, b, x, y, val, type

a<-v1

b<-v2

x<-t1

y<-t2

val<- OR_V(a,b)

type<- OR_T(x,y)

_v<-val

_t<-type

7) ORE_v,_t -> ANEv,t

_v<-v

_t<-t

8) ANE_v,_t -> ANE v1,t1 && EQL v2,t2 {AND} a, b, x, y, val, type

a<-v1

b<-v2

x<-t1

y<-t2

val<- AND_V(a,b)

type<- AND_T(x,y)

_v<-val

_t<-type

9) ANE_v,_t -> EQLv,t

_v<-v

_t<-t

10) EQL_v,_t -> EQL v1,t1 eopt NEQ v2,t2 {EOP} a, b, _t1, x, y, val, type

a<-v1

b<-v2

_t1<-t

x<-t1

y<-t2

val<- EOP_V(a,b,_t1)

type <- EOP_T(x,y,_t1)

_v<-val

_t<-type

11) EQL_v,_t -> NEQv,t

_v<-v

_t<-t

12) NEQ_v,_t -> NEQ v1,t1 copt ADD v2,t2 {COP} a, b, _t1, x, y, val, type

a<-v1

b<-v2

_t1<-t

x<-t1

y<-t2

val<- COP_V(a,b,_t1)

type <- COP_T(x,y,_t1)

_v<-val

_t<-type

13) NEQ_v,_t -> ADDv,t

_v<-v

_t<-t

14) ADD_v,_t -> ADD v1,t1 aopt MUL v2,t2 {AOP} a, b, _t1, x, y, val, type

a<-v1

b<-v2

_t1<-t

x<-t1

y<-t2

val<- AOP_V(a,b,_t1)

type <- AOP_T(x,y,_t1)

_v<-val

_t<-type

15) ADD_v,_t -> MULv,t

_v<-v

_t<-t

16) MUL_v,_t -> MUL v1,t1 mopt UNE v2,t2 {MOP} a, b, _t1, x, y, val, type

a<-v1

b<-v2

_t1<-t

x<-t1

y<-t2

val<- MOP_V(a,b,_t1)

type <- MOP_T(x,y,_t1)

_v<-val

_t<-type

17) MUL_v,_t -> UNEv,t

_v<-v

_t<-t

18) UNE_v,_t -> #t UNEv,t {#} a, _t1, x, val, type

a<-v

_t1<-t

x<-t1

val<- UNE_V(a,_t1)

type <- UNE_T(x,_t1)

_v<-val

_t<-type

19) UNE_v,_t -> inct UNEv,t {INC} a, _t1, x, val, type

a<-v

_t1<-t

x<-t1

val<- UNE_V(a,_t1)

type <- UNE_T(x,_t1)

_v<-val

_t<-type

20) UNE_v,_t -> POS v,t

_v<-v

_t<-t

21) UNE_v,_t -> NEW v,t

_v<-v

_t<-t

22) UNE_v,_t -> DEL v,t

_v<-v

_t<-t

23) POS_v,_t -> POS v,t inct {INC} a, _t1, x, val, type

a<-v

_t1<-t

x<-t1

val<- UNE_V(a,_t1)

type <- UNE_T(x,_t1)

_v<-val

_t<-type

24) POS_v,_t -> FIR v,t

_v<-v

_t<-t

25) FIR_v,_t -> ( EXP v,t )

_v<-v

_t<-t

26) FIR_v,_t -> id v,t {ID} v1, t1, vres, tres

v1<-v

t1<-t

vres<- IDENT(v1,t1)

tres<- IDENT(v1,t1)

_v<-vres

_t<-tres

27) FIR_v,_t -> MAS v1,t1 [ ORE v,t ] {MAS}_v1,_t1,_x,_y, vres, tres

_v1<-v1

_t1<t1

_x<-v

_y<-t

vres<- MAS(_v1,_t1,_x,_y)

tres<- MAS(_v1,_t1,_x,_y)

_v<-vres

_t<-tres

28) MAS_v,_t -> id v,t

_v<-v

_t<-t

29) MAS_v,_t -> MASv1,t1 [ ORE v,t ] {MAS}_v1,_t1,_x,_y, vres, tres

_v1<-v1

_t1<t1

_x<-v

_y<-t

vres<- MAS(_v1,_t1,_x,_y)

tres<- MAS(_v1,_t1,_x,_y)

_v<-vres

_t<-tres

30) FIR_v,_t -> rco {RCO} vres, tres

vres<- RCONST

tres<- RCONST

_v<-vres

_t<-tres

31) FIR_v,_t -> zco {ZCO} vres, tres

vres<- ZCONST

tres<- ZCONST

_v<-vres

_t<-tres

32) TYPt -> intt1

t<-t1

33) TYPt -> floatt1

t<-t1

34) NEW_v,_t -> new TYPt1 ( FIRv,t ) {NEW} x, y, z, _z, vres, tres

x<-v

y<-t

z<-t1

_z<-NIL

vres<- NEW (x,y,z, _z)

tres<- NEW (x,y,z, _z)

_v<-vres

_t<-tres

35) NEW_v,_t -> new [ ] t2 TYP t1 ( FIRv,t ) {NEW} x, y, z, _z, vres, tres

x<-v

y<-t

z<-t1

_z<t2

vres<- NEW (x,y,z, _z)

tres<- NEW (x,y,z, _z)

_v<-vres

_t<-tres

36) DEL_v,_t -> delete id v,t {DELETE}a, _z

_v<-1

_t<-int

a<-v

_z<-NIL

37) DEL_v,_t -> delete [ ] t2 id v,t {DELETE}a, _z

_v<-1

_t<-int

a<-v

_z<-t2

Подграмматика if/for (SLR(1)):

Операционный символ

Атрибуты

Комментарий

{BRL}m

m - метка, на которую будет произведен безусловный переход.

Здесь и далее: Если данная метка отсутствует в таблице меток, то вызывается функция NewLabel,которая создает метку и заносит ее в таблицу.

Вывод: m BRL

{BF}m,val

m - метка, на которую будет произведен переход, в случае, если val = 0.

Вывод: m BF

{DEFL}m

m - метка, которая объявляется.

Вывод: m DEFL

(RET}m

Возврат к метке m

Вывод: m RET

{DEL}a

а - имя удаляемого из таблицы идентификатора

Уничтожение соответствующей записи в таблице.

Вывод: a DEL

1) I_F -> INI

2) I_F -> INF

3) INI -> INI_1p ins {DEFL}m

mp

3’) INI_1p-> if ( expval ) {BF}m, v

m NewLabel

p m

vval

4) INI -> INI_2 q2 ins {DEFL}m2

m2<-q2

4’) INI_2q2 -> INI_1p ins else {BRL}m2 {DEFL}m1

m2 NewLabel

q2 m2

m1p

  1. INF -> INF_1_m2, _m4, n ins {RET}m2 {DEFL}m4 {DEL} _n

m2<-_m2

m4<-_m4

n<-_n

5’) INF_1__m2, __m4, n -> INF_2_m1, _m2, _m3, _m4, _n; exp ) {RET}m1 {DEFL}m3

m1<-_m1

m3<-_m3

n<-_n

5’’)INF_2_m1, _m2, _m3, _m4, n -> INF_3p, _n expval {BF}m4, v {BRL}m3 {DEFL}m2

_m1<-p

v<-val

m4<- NewLabel

m3<- NewLabel

m2<- NewLabel

_m2<-m2

_m3<-m3

_m4<-m4

n<-_n

5’’’)INF_3p, n -> for ( inoname {DEFL}m1

m1<- NewLabel

p<-m1

n<-name

Подграмматика объявлений (SLR(1)):

Операционный символ

Атрибуты

Комментарий

{ADDVAR}_t, _enum, _list, vres, tres

_t - список спецификаторов типа

_enum - индикатор наличия описания enum в _t

_list - список пар (значение, тип)

vres - результат - список значений

tres - результирующий тип

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

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

Вывод: tres a SET a NEW

Здесь и далее:

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

{PSTEND} list_in, list_res

list_in - новый полный список спецификаторов типа

tres - результирующий тип

Функция PSTEND вычисляет тип объявляемого значения по мере поступления спецификаторов типа.

{ADDENUM}_list, _name, tres

_list - список инициализаторов enum

_name - имя перечисления

tres - тип элементов перечисления

Функция ADDENUM вычисляет тип элементов перечисления в зависимости от вида его объявления и инициализирует их.

{ADDDEF}v, _t

v - значение инициализатора

_t - тип инициализатора

Функция ADDDEF проверяет корректность инициализации элемента перечисления.

{IDE}t1,t2, tres

t1 - тип объявителя

t2 - тип инициализирующего значения

tres - результирующий тип

Функция IDE производит преобразование типов, если появляется такая необходимость.

{DEF}_t1, _t2, tres

_t1 - наличие указателя

_t2 - объекта

tres- результирующий тип

Функция DEF производит преобразование типов для случаев с объявлением указателя, если появляется такая необходимость.

{NDE}_val, _type, _t, tres

_val - значение индекса

_type - тип индекса

_t - тип подмассива

tres- результирующий тип

Функция NDE производит преобразование типов для случаев с объявлением массива, если появляется такая необходимость. Проверяет корректность семантики объявления массива или простой переменной.

{PTR}_t, _c, type

_t - степень указателя

_c - наличие спецификатора const

type - результирующий тип

Функция PTR производит объявление спецификатора указателя, определяя его вид.

1) INOval_list, type -> PST t, enum SIOlist ; {ADDVAR}_t, _enum, _list, vres, tres

_t<-t

_enum<-enum

_list<-list

vres<- ADDVAR(_t, _enum, _list)

tres<- ADDVAR(_t, _enum, _list)

val_list<-vres

type<-tres

2) PSTt, enum -> STY_t {PSTEND} list_in, tres

list_in<-_t

tres<- PSTEND(list_in)

enum<- PSTEND(list_in)

t<-tres

3) PSTt, enum -> PST_list STYt {PSTEND} list_in, tres

list_in <-CONC(_list,t)

tres<- PSTEND(list_in)

t<-tres

enum<-NIL

4) STYt -> SST_t

t<-_t

5) STYt -> SEN_t

t<-_t

6) STYt -> constc

t<-c

7) SST_t -> intt

_t<-t

8) SST_t -> floatt

_t<-t

9) SENt -> enum { } {ADDENUM}_list, _name, tres

_list<-NIL

_name<- int

tres<- ADDENUM(_name)

t<-tres

10) SENt -> enum idname { } {ADDENUM}_list, _name, tres

_list<-NIL

_name<-name

tres<- ADDENUM(_name)

t<-tres

11) SENt -> enum { SEElist } {ADDENUM}_list, _name, tres

_list<-list

_name<-int

tres<- ADDENUM(_name)

t<-tres

12) SENt -> enum idname { SEElist } {ADDENUM}_list, _name, tres

_list<-list

_name<-name

tres<- ADDENUM(_name)

t<-tres

13) SEE list -> DEPp

list<-p

14) SEE list -> SEE_list , DEPp

list<-CONC(_list,p)

15) DEPp -> id = EXPval, t {ADDDEF}v, _t

v, p<-val

_t<-t

16) SIOlist -> IDEt,p

list<- PAIR(t,p)

17) SIOlist -> SIO_list IDEt,p

list<-CONC(_list,PAIR(t,p))

18) IDEt,p -> DEF_t {IDE} t1,t2, tres

t1<-_t

t2<-NIL

tres<-IDE(t1,t2)

t<-tres

p<-NIL

19) IDE t,p -> DEF_t INRv,t {IDE}t1,t2, tres

t1<-_t

t2<-t

tres<-IDE(t1,t2)

t<-tres

p<-v

20) DEFt -> NDE t1{DEF}_t1, _t2, tres

_t1<-NIL

_t2<-t1

tres<-DEF(_t1, _t2)

t<-tres

21) DEFt -> PTR type DEFt1 {DEF}_t1, _t2, tres

_t1<-type

_t2<-t1

tres<-DEF(_t1, _t2)

t<-tres

22) INRv,t -> = EXP val,type

v<-val

t<-type

23) NDEt1 -> id {NDE}_val, _type, _v, _t, tres

_val<-NIL

_type<-NIL

_v<-NIL

_t<-NIL

tres<- NDE(_val, _type, _v, _t)

t1<-tres

24) NDEt1 -> NDEt [ ] {NDE}_val, _type, _t, tres

_val<-NIL

_type<-NIL

_t<-t

tres<- NDE(_val, _type, _v, _t)

t1<-tres

25) NDEt1 -> NDEt [ EXP val,type ] {NDE}_val, _type, _t, tres

_val<-val

_type<-type

_t<-t

tres<- NDE(_val, _type, _v, _t)

t1<-tres

26) PTR_ type -> * t {PTR}_t, _c, type

_t<-t

_c<-NIL

type<-PTRTYPE(_t,_c)

_ type<- type

27) PTR _type -> *t constc {PTR}_t, _c, type

_t<-t

_c<-c

type<-PTRTYPE(_t,_c)

_ type<- type

28) EXPval,type -> expv,t

val<-v

type<-t

4. ДМП-преобразователь

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

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

ДМП-процессор состоит из магазина, входной ленты, выходной ленты и управляющего устройства М.

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

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

В S-атрибутном ДМП-процессоре каждый магазинный символ имеет конечное множество полей для представления атрибутов. Примем, что магазинный символ с n атрибутами представляется в магазине n + 1 полями, верхнее из которых содержит имя символа, а остальные – значения атрибутов.

В ходе разбиения исходной грамматики на подграмматики нами использовались подграмматики двух классов: простого предшествования и SLR(1).

Рассмотрим устройство ДМП-преобразователя для SLR(1) грамматик:

Управляющее устройство анализатора представляет собой таблицу, строки которой отмечены символами магазинного алфавита. Каждая строка таблицы задает две функции: функцию действия (F) и функцию переходов (G). Функция действия F, аргументом которой служит некоторый символ входной цепочки, принимает значения из множества {"ДОПУСК", "ПЕРЕНОС", "(СВЕРТКА,i)", "ОШИБКА" }. Аргументом функции переходов G является символ из полного словаря грамматики, а значениями - символ "ОШИБКА" или символ магазинного алфавита.

Тогда алгоритм работы ДМП-преобразователя имеет вид:

Вход алгоритма :

1) Анализируемая входная цепочка Z = t1 t2 ... tj ... tn , где j - номер текущего символа входной цепочки, находящегося под читающей головкой;

2) Управляющая таблица для SLR(1)-грамматики.

Выход алгоритма :

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

Описание алгоритма :

1. j:=0.

2. j:=j+1. Если j > n , то выдать сообщение об ошибке и перейти к

п.5.

3. Определить очередной символ входной цепочки :

u = tj , тогда u = tj+1 ... tn - остаток входной цепочки.

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

а) F(u) = ПЕРЕНОС. Определить функцию переходов G(tj) из строки управляющей таблицы, отмеченной символом T из верхушки магазина. Если G(tj) = T1 и T1 принадлежит множеству { Vp U {┴} }, то записать T1 в магазин и перейти к п.2. Если G(tj) = ОШИБКА, то выдать сигнал об ошибке и перейти к п.5.

Атрибуты переносимого входного символа помещаются в соответствующие поля вталкиваемого при переносы магазинного символа. При вталкивании символа в магазин атрибуты заполняются и не изменяются до выталкивания этого символа из магазина.

б) F(u) = (СВЕРТКА,i) и A -> a - правило вывода с номером i грамматики. Удалить из верхней части магазина столько символов, сколько содержится в правой части i-го правила, в результате чего в верхушке магазина окажется символ T1, принадлежащий множеству { Vp U {┴} }. Определить символ T2 = G(A) , записать его в магазин и перейти к п.3.

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

в) F(u) = ОШИБКА. Выдать сообщение об ошибке и перейти к п.5.

г) F(u) = ДОПУСК. .Успешное завершение работы процессора, получена цепочка на промежуточном языке

5. Завершение работы.

Рассмотрим устройство ДМП-преобразователя для грамматик простого предшествования:

Пусть G = < T, N, S, R > – КС-грамматика, правила которой занумерованы натуральными числами 1, 2, ... , р. Алгоритмом разбора типа “перенос- свертка” для грамматики G называется пара функций A = (f, g), где f - функция переноса, a g - функция свертки.

Функции f и g зависят от цепочки, находящейся в верхушке магазина, и необработанной части входной цепочки. Эти функ­ции определяются следующим образом:

  • f отображает множество V*( T {})* в множество {ПЕРЕНОС, СВЕРТКА, ДОПУСК, ОШИБКА} ;

  • g отображает множество V*( T {})* в множество{1, 2, ... , р, ОШИБКА} при условии, что если и g(, w)=i, то правая часть i-го правила А является суффиксом цепочки .

Для КС-грамматики G = < T, N, S, R > отношения простого предшествования < и определя­ются на (V { })(V { }), где маркер дна магазина, следующим образом:

  1. X Y, если в R есть правило A XY.

б) X <Y, если в R есть правило A XB и B + Y;

в) <Y для всех Y, для которых S + Y;

Отношение определяется на (V { })(T { }), так как непосредственно справа от правовыводимой цепочки может стоять только терминал.

a) X a, если в R есть правило A BY и B + X и Y  a;

б) X для всех, для которых S + X.

В правовыводимой цепочке w, где = X1X2Xn, = Y1Y2Ym , w=ax и основа, между символами цепочки выполняются следующие отношения (фигурные скобки { } означают, что выполняется одно из отношений, за­писанных в них):

X1 { < } X2 { < } … { < } Xn < Y1 Y2 Ym ax

Тогда алгоритм работы ДМП-преобразователя имеет вид:

Вход:

Грамматика простого предшествования G = < T, N, S, R >, в которой правила вывода занумерованы натуральными чис­лами 1, 2, ... , р.

Выход:

Алгоритм A = (f, g) типа “перенос – свертка” для грамматики G.

  1. Функция переноса f зависит только от верхнего символа магазина и самого левого необработанного символа входной це­почки. Поэтому f определяется на множестве (V { })(T { }) ( за исключением правила с), которое имеет приоритет над правила­ми а) и b), когда Х = S и a = ):

    1. f(X, а) = ПЕРЕНОС, если Х < а или Х а ;

    2. f(X, а) = СВЕРТКА, если Х •> а ;

    3. f(S, ) = ДОПУСК;

    4. f(X, а) = ОШИБКА в остальных случаях.

2) Функция свертки g зависит от верхней части магазинной цепочки, включающей основу и еще один символ ниже нее. Необ­работанная часть входной цепочки на g не влияет, поэтому g задается только на (V { })*:

    1. g(Xk+1XkXk-1X1, ) = i, если Xk+1 <Xk, Xj+1 Xj для k>j1 и

A ХkХk-1 ... Х1 правило вывода с номером i. Заметим, что функция g определяется только тогда, когда Х1 > a текущий входной символ;

b) g(, ) = ОШИБКА в остальных случаях.

Организация взаимодействия n ДМП-процессоров:

Вызывающий ДМП-процессор.

В основе этого процессора лежит грамматика, которая среди своих терминальных символов содержит специальный терминальный символ (в тексте выделен жирным шрифтом), по которому происходит вызов другого ДМП-процессора. Когда этот символ находится наверху магазина, данный процессор должен выполнить переход к вызываемому процессору.

Вызываемый ДМП-процессор.

Каждый процессор должен работать со своим магазином. В программной реализации ДПМ-процессора это может быть новый объект соответствующего класса или, если используется один физический магазин, то в него вталкивается символ «дно магазина» и анализ начинается так, как если бы магазин был пуст. После завершения анализа верх магазина должен быть приведен к виду, пригодному для продолжения работы вызывающего процессора.

Для подграмматики определен некоторый набор символов, по которым возможен «ДОПУСК», то есть корректное завершение работы процессора. Этими символами являются те символы, которые отмечают столбцы, на пересечении которых со строками стоит ДОПУСК в таблицах функций действий.