КАТЕГОРИИ: Архитектура-(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) |
Интерпретатор ПОЛИЗа для модельного языка
Польская инверсная запись была выбрана нами в качестве языка внутреннего представления программы, в частности, потому, что записанная таким образом программа может быть легко проинтерпретирована. Идея алгоритма очень проста: просматриваем ПОЛИЗ слева направо; если встречаем операнд, то записываем его в стек; если встретили знак операции, то извлекаем из стека нужное количество операндов и выполняем операцию, результат (если он есть) заносим в стек и т.д. Итак, программа на ПОЛИЗе записана в массиве P; пусть она состоит из N элементов-лексем. Каждая лексема - это структура struct lex {int class; int value;}, возможные значения поля class: 0 - лексемы-метки (номера элементов в ПОЛИЗе) 1 - логические константы true либо false (других лексем - служебных слов в ПОЛИЗе нет) 2 - операции (других лексем-ограничителей в ПОЛИЗе нет) 3 - целые константы 4 - лексемы-идентификаторы (во время интерпретации будет использоваться значение) 5 - лексемы-идентификаторы (во время интерпретации будет использоваться адрес). Считаем, что к моменту интерпретации распределена память под константы и переменные, адреса занесены в поле address таблиц TID и TNUM, значения констант размещены в памяти. В программе-интерпретаторе будем использовать некоторые переменные и функции, введенные нами ранее.
void interpreter(void) { int *ip; int i, j, arg; for (i = 0; i<=N; i++) {curr_lex = P[i]; switch (curr_lex.class) { case 0: ipush (curr_lex.value); break; /* метку ПОЛИЗ - в стек */ case 1: if (eq ("true")) ipush (1); else ipush (0); break; /* логическое значение - в стек */ case 2: if (eq ("+")) {ipush (ipop() + ipop()); break}; /* выполнили операцию сложения, результат - в стек*/ if (eq ("-")) {arg = ipop(); ipush (ipop() - arg); break;} /* аналогично для других двухместных арифметических
if (eq ("not")) {ipush (!ipop()); break;}; if (eq ("!")) {j = ipop(); i = j-1; break;}; /* интерпретация будет продолжена с j-го элемента if (eq ("!F")) {j = ipop(); arg = ipop(); if (!arg) {i = j-1}; break;}; /* если значение arg ложно, то интерпретация будет if (eq (":=")) {arg = ipop(); ip = (int*)ipop(); *ip = arg; break;}; if (eq ("R")) {ip = (*int) ipop(); scanf("%d", ip); break;}; /* "R" - обозначение операции ввода */ if (eq ("W")) {arg = ipop(); printf ("%d", arg); break;}; /* "W" - обозначение операции вывода */ case 3: ip = TNUM [curr_lex.value].address; ipush(*ip); break; /* значение константы - в стек */ case 4: ip = TID [curr_lex.value].address; ipush(*ip); break; /* значение переменной - в стек */ case 5: ip = TID [curr_lex.value}.address; ipush((int)ip); break; /* адрес переменной - в стек */ } /* конец switch */ } /* конец for */ }
Дата добавления: 2015-06-27; Просмотров: 530; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |