Лабораторная работа 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;
…};


