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

Для более удобного выполнения семантических проверок и генерации объектного кода используется ещё одна промежуточная форма представления программы — последовательность пентад. Пентада представляет собой машинную команду, состоящую из пяти полей: наименования метки перехода, наименования кода операции, наименования двух операндов и наименования результата. Удобство использования пентад для семантического анализа состоит в том, что наименования всех необходимых для выполнения проверок объектов программы локализованы в пределах одной пентады. Последовательность пентад текущего блока формируется после получения постфиксной записи этого блока. Рассмотрим подробно алгоритм формирования последовательности пентад:

  1. Создание переменной для хранения текущей метки и сброс её значения. Запуск цикла для прохождения по словам постфиксной записи данного блока. Установка первого слова в качестве текущего.
  2. Текущее слово заносится в стек и производится анализ его назначения.
  3. Если текущее слово – «let», происходит формирование пентады для операции присваивания. В пентаду помещается текущая метка, знак операции («let»), операнды (первый операнд берётся из стека, в качестве второго операнда используется значение «null», так как второй операнд при этой операции не используется), наименование результата также извлекается из стека. Происходит сброс значения текущей метки.
  4. Если текущее слово является знаком операции, происходит формирование пентады для текущей операции. В пентаду помещается текущая метка, знак операции (извлекается из стека), операнды (извлекаются из стека). После этого происходит формирование идентификатора для промежуточного результата вычислений. Имя идентификатора получается в результате конкатенации строки «tmpValue» и следующего номера идентификатора в таблице. Созданный идентификатор помещается в соответствующую таблицу, а также в пентаду в качестве результата. Происходит сброс значения текущей метки.
  5. Если текущее слово является меткой, а также является предпоследним или следующим слово тоже является метка, то происходит формирование пентады для пустой метки. Все поля метки кроме её наименования заполняются значениями «null».
  6. Если текущим слово является метка, и предыдущее условие не выполнилось, то наименование данной метки сохраняется в переменной для хранения текущей метки и происходит переход к следующему шагу цикла.
  7. Если текущим словом является служебное слово «JmpF», то происходит формирование пентады для перехода по лжи. В пентаду помещаются: текущая метка, код операции («JmpF»), операнды (извлекаются из стека), в качестве результата заносится значение «null». Происходит сброс значения текущей метки.
  8. Если текущим словом является служебное слово «Jmp», то происходит формирование пентады для перехода по истине. В пентаду помещаются: текущая метка, код операции («Jmp»), первый операнд (извлекается из стека), в качестве второго операнда и результата заносятся значения «null». Происходит сброс значения текущей метки.
  9. Переход к следующему шагу цикла.
  10. После окончания цикла, сформированная последовательность пентад заносится в вектор для хранения последовательности пентад всей программы с индексом, соответствующим индексу текущего блока.
  11. Происходит очистка вектора для хранения последовательности пентад текущего блока и вектор для хранения знаков операций, используемых в текущем блоке. Завершение процедуры.

Для выполнения алгоритма определяются следующие объекты:

final Vector VectPentadTotal = new Vector(); //вектор для хранения последовательности пентад всей

          //программы

final Vector VectPentadBlock = new Vector(); //вектор для хранения последовательности пентад

           //программного кода текущего блока

final Vector VectPentadString = new Vector(); //вектор для хранения последовательности пентад

            //текущего выражения