Лабораторная работа 4: рекурсивный спуск. 
АВТ-918 Бородин, Кузьмин.  Задание: 

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

Чтение структур происходит справа на лево.

1)



2)

Функция, возвращающая указатель на функцию, возвращающая t.

3)

Массив указателей на t.

4)

Указатель на массив.

class list//класс, предназначенный для хранения семантических структур, представляет из себя двунаправленный спискел элементов типов, индефикаторов, структур и адресной арифметики.

{

friend syntax;

int type;//тип структуры, которому принадлежит элемент

char c;//символ, определяющий элемент в структуре

list *left;//следующий элемент, опред. структуру

list* down;//указатель, указывающий на след. семантическую структуру, или на отдельную структуру(является частью текущей)

public:

~list()

{

if(left)delete left;

if(down)delete down;

}

list(char f, int dd)

{

left=NULL;

down=NULL;

c=f;

type=dd;

}

void out(int level)//функция вывода семантических структур на экран

{

printf("%c",c);

if(left)left->out(level+1);

else printf("\n");

if(down)

{

list*pp=down;

while(pp)

{

for(int i=0;i<level;i++)printf(" ");

printf("%c",pp->c);

if(pp->left)pp->left->out(level+1);

pp=pp->down;

}

}

}

};

class syntax{//базовый класс синтаксического анализатора был изменен путем добавления нового элемента типа *List, и все его функции-правила возвращают элементы семантических структур.

НЕ нашли? Не то? Что вы ищете?

public:

list *GG;

void Z(){//основная программа

case '#':

GG=U();//возвращение основной структуры

if(in[si]!='#') throw("illegal terminal");

}

list* U(){//перечисление операторов

switch(in[si]){

case '#':return NULL;//возвращение семантических структур

break;

case 'u':

list *n;

n=D();//определение семантической структуры

n->down=U();//определение след. Семантической структуры

return n;

break;

}}

list* D(){//выбор типа определения(тип или переменная)

List*n;

case 's':

return V(3);//передача на верхний уровень структуры

break;

case 't':

return V(2);//--//--

break;

case 'u':

n=new list('u',1);//структуры type define

n->left=V(1);

return n;

}}

list* V(int dd){//определения переменной

case 's':

if(in[si]!='s') throw("illegal terminal");

si++;

n=new list('s',dd);//определение структуры

if(in[si]!='i') throw("illegal terminal");

si++;

n->left=new list('i',dd);//определение идентификатора структуры

if(in[si]!='{') throw("illegal terminal");

si++;

o=n;

n->left->down=W();//определение составляющих типа struct

if(in[si]!='}') throw("illegal terminal");

si++;

n->down=Y(dd);//определение след. структуры

if(in[si]!=';') throw("illegal terminal");

si++;

return o;

break;

case 't':

if(in[si]!='t') throw("illegal terminal");

si++;

n=new list('t',dd);

n->left=X(dd);//определение переменной

n->down=L(dd);//определение след. Семантической структуры

}

list* W(){//перечисление переменных в структуре

case 't':

n=V(2);//определение переменной

o=n;

while(n->down)n=n->down;

n->down=W();//определение след. пременной

return o;

break;

}

list* X(int dd){//указательная арифметика

case '(':

n=B(dd);//определение в семантической структуре факта указания

if(n)

{

y=n;

while(y->left)

{

y=y->left;

}

p=A(dd);//определение операторных скобок и идентификатора

y->left=C(dd);//опред. Функц. Скобок и []

while(y->left)

{

y=y->left;

}

y->left=p;

return n;

}

Else//случай отсутствия указателя

{

p=A(dd);

y=o=C(dd);

if(!y)

{

return p;

}

while(y->left)

{

y=y->left;

}

y->left=p;

return o;

}

}

list* B(int dd){//поиск указателя

case '*':

if(in[si]!='*') throw("illegal terminal");

si++;

n=new list('*',dd);

n->left=B(dd);//добавление факта указателя

return n;

break;

}

list* A(int dd){//операторные скобки и идентификатор

case 'i':

if(in[si]!='i') throw("illegal terminal");

si++;

return new list('i',dd);//нахождение идентификатора

break;

case '(':

if(in[si]!='(') throw("illegal terminal");

si++;

l=X(dd);//след. Элемент семант. стрктуры

if(in[si]!=')') throw("illegal terminal");

si++;

return l;

break;

}

list* C(int dd){//функциональные скобки и []

case '(':

return F(dd);//определение составляющих функции

break;

case '[':

case ',':

case ';':

case ')':

return N(dd);//определение массива

break;

}

list* N(int dd){// []

case '[':

if(in[si]!='[') throw("illegal terminal");

si++;

n= new list('[',dd);

if(in[si]!=']') throw("illegal terminal");

n->left=new list(']',dd);//добавление в структуру факта массива

si++;

n->left->left=N(dd);//поиск след. Факта массива

return n;

break;

case ',':

case ';':

case ')':

return NULL;

break;

}

list* F(int dd){//функциональные скобки

case '(':

if(in[si]!='(') throw("illegal terminal");

si++;

n=new list('(',4);//определение функции

n->down=K(4);//определение составляющих функции

if(in[si]!=')') throw("illegal terminal");

si++;

return n;

break;

}

list* K(int dd){//передаваемые элементы

case 't':

if(in[si]!='t') throw("illegal terminal");

si++;

n=new list('t',dd);//определение типов, передаваемых эл.

n->left=X(dd);//--//--

n->down=P(dd);//след. Передаваемый эл.

return n;

break;

case ')':

return NULL;

break;

}

list* P(int dd){//перечисление передаваемых элементов

case ',':

if(in[si]!=',') throw("illegal terminal");

si++;

if(in[si]!='t') throw("illegal terminal");

si++;

n=new list('t',dd);//определение типовпередаваемых эл.

n->left=X(dd);//--//--

n->down=P(dd);//след. Передаваемый эл.

return n;

break;

case ')':

return NULL;

break;

}

list* L(int dd){//перечисление указательной арифметики

case ',':

if(in[si]!=',') throw("illegal terminal");

si++;

n=new list('t',dd);//тип переменной

n->left= X(dd);//указательная арифметика

o=n;

n->down=L(dd);//след. Переменная с общим типом

return o;

break;

case ';':

return NULL;

break;

}

list* Y(int dd){//перечисление после структуры

case ';':

return NULL;

break;

case '*':

case 'i':

case '(':

n= X(dd);//переменная после структуры

n->down=L(dd);

return n;

break;

…};