Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Лекция 12. Заполнение таблицы команд




Заполнение таблицы команд

 

Эта таблица заполняется расширенными функциями body(), stat(), expr(), term(), fact(). Заполнение осуществляется вызовом специально предназначенной для этого функцией gen()/.

Предварительно нужно в программе интерпретатора добавить следующие глобальные переменные:

int cgv=0, clv=0; //количество глобальных и количество локальных переменных

int tc=0; //счетчик количества команд, занесенных в TCD

int out=1 //если out=1, то переменная глобальная. Если out=0, то- локальная

 

Программа занесения команд в таблицу команд

 

int gen(int co, int op)

{

if (tc>=300)

{

puts(“Переполнение TCD”);

exit(1);

}

TCD[tc].cod=co;

TCD[tc].opd=op;

return tc + +;

}

Следует обратить внимание на return tc + +. Возвращается адрес в TCD, куда будет заноситься следующая команда.

 

 

Расширенная функция body()

 

int body()

{

int st; //Адрес точки входа в функцию

exam(BEGINL);

clv=0;//Обнулить количество локальных переменных.

while(lex = = INTL|| lex = = CONSTL)

if (lex = = CONSTL)

dconst();

else

dvarb();// Возвращает значение clv

st = gen(INI, clv); //Адрес команды в TCD является точкой входа в функцию

stml();

exam(ENDL);

gen(OPR, 10); //Генерация команды «останов»

return st;//Возвращает точку входа в функцию.

}

По сравнению с нерасширенной функцией body() имеет место определение точки входа в функцию и вызов функции gen() для занесения в TCD определенных команд.

 

Расширенная функция stat()

 

void stat()

{

int t1, t2;

odc*p;

switch(lex)

{

case IDEN: p= findob((char*)lval); get();

exam(‘=’); expr();

if(p→what = =1);

{

printf(“%s- константа. Нельзя присваивать \n”,p→name);

exit(1)

}

gen (p->what == 2? STE: STI, p->val); break;

case READL:

get(); p = findob ((char *)lval); gen (OPR, 1);

if (p->what == 1)

{

printf ("%s константа\n", p->name);

exit(1);

}

gen (p->what == 2? STE: STI, p->val);

exam (IDEN); break;

case IFL:

get(); expr(); exam (THENL);

t1 = gen (JMC, 0); stml(); exam (ENDL);

TCD[t1].opd = tc; break;

case WHILEL:

get(); t1 = tc; expr();

exam (DOL); t2 = gen (JMC, 0); stml();

gen (JMP, t1); TCD[t2].opd = tc;

exam (ENDL); break;

case PRITL:

get(); expr(); gen (OPR, 2); break;

case RETRL:

get(); expr(); gen (OPR, 9); break;

default:

printf(“Недопустимая лексема lex=%i в строке nst=%i \n”, lex, nst);

}

return;

}

 

 

По case IDEN вначале происходит поиск объекта в TOB по имени (char*) lval. Напомним, что lval - значение лексемы. Для константы это число, а для переменных – адрес в таблице идентификаторов TNM. Используется явное преобразование типа int lval на указатель (char*,) поскольку для функции findob(char*name) параметром является именно указатель char*. Эта функция возвращает указатель odc*p. Если р→what равен 1, то это означает, что найденный объект – константа, а значит присваивать нельзя. Программа по еxit(1) прекращает работу. Если р→what равен 2, то объект является глобальной переменной. Тогда генерируется команда занесения глобальной переменной gen (STЕ, p->val). Иначе заносится локальная переменная

gen (STI, p->val). Напомним, что p->val определяет смещение обьекта в стеке. Например, в рассмотренной выше программе смещение для локальной переменной c равно 1. Соответственно команда присваивания числа из вершины стека переменной c имеет вид gen (STI, 1).

По case READL также ищется объект в ТОВ, и в таблицу команд TCD записывается команда

OPR 1 занесения из файла stdin, связанного с клавиатурой, в вершину стека. Далее - всё подобно рассмотренному выше.

По case IFL после получения «свежей» лексемы (get()) и вызова expr() проверяется наличие служебного слова thenl. Затем в t1 заносится значение счетчика tc команд в TCD, соответствующего команде gen (JMC,0)- условной передачи управления команде под номером 0 в TCD. Затем по stml() заносится в TCD последовательность команд. Естественно, что при этом изменяется значение tc. Затем реальное значение tc заносится вместо нуля в качестве операнда в команду, находящуюся под номером t1 в TCD

TCD[t1].opd=tc.

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

lb:<e>{JMC l}<s>{JMP lb} l.

Присваивание t1=tc соответствует получению метки lb <e>.

t2=gen(JMC,0) - запоминание номера команды JMC0 в TCD. После выполнения последовательности команд <s>, чему соответствует stml(), выполняется (JMP,t1)- безусловная передача на команду, по которой будет получено новое значение <e> в вершину стека. Как и в случае case IFL, присваивание TCD[t2].opd=tc позволяет заменить условную передачу (JMC,0) на (JMC,tc).

 




Поделиться с друзьями:


Дата добавления: 2015-06-27; Просмотров: 324; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.011 сек.