Программная реализация абстрактного автомата для транслятора языка высокого уровня
Исследование теории формальных языков. Характеристика объектно-атрибутной архитектуры для реализации абстрактного автомата и транслятора языка. Особенность создания архитектуры автомата. Разработка виртуальных устройств и их программная реализация.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 04.12.2019 |
Размер файла | 880,6 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
- обеспечивает функциональность абстрактного конечного МП-автомата,
- производит анализы языка высокого уровня (лексический и синтаксический),
- в компиляторе реализована таблица идентификаторов переменных.
Таким образом, можно сделать вывод, что данная работа полностью соответствует техническому заданию.
Областью применения предмета ВКР является создание компиляторов/интерпретаторов на базе парадигмы dataflow. В дальнейшем, эту работу можно продолжить, расширив данный программный модуль до полноценного компилятора/интерпретатора, то есть можно добавить в него фазы семантического анализа, оптимизации, генерации кода и другие. Это потребует как программной реализации ФУ новых типов, так и реализации на ОА-языке полноценной программы трансляции на целевой язык.
Список литературы
1. Ахо, Альфред В., Лам, Моника С, Сети, Рави, Ульман, Джеффри Д. Компиляторы: принципы, технологии и инструментарий, 2-е изд. Пер. с англ. М.: 000 «ИД. Вильямс», 2008. -- 1184 с.
2. Шалыто А.А. Парадигма автоматного программирования // Научно-технический вестник информационных технологий, механики и оптики. 2008. № 53. С. 3-23.
3. Серебряков В. А., Галочкин М. П., Гончар Д. Р., Фуругян М. Г. Теория и реализация языков программирования -- М.: МЗ-Пресс, 2006 г., 2-е изд. -- ISBN 5-94073-094-9
4. Б. К. Мартыненко. Языки и трансляции. Учебное пособие, Изд. СПбГУ, СПб, 2008
5. Салибекян С.М., Реализация автоматной парадигмы вычислений на объектно-атрибутном базисе // Прикладная информатика. 2017. Т. 12. № 2 (68). С. 103-115
6. Салибекян С.М., Шибаев Р.В. Управляющий автомат и dataflow парадигмы вычислительного процесса - необычный симбиоз // Системный администратор. 2017. № 6 (175). С. 84-87.
7. Салибекян С. М., Панфилов П. Б. Вопросы автоматно-сетевого моделирования вычислительных систем с управлением потоком данных // Информационные технологии и вычислительные системы. 2015. № 1. С. 3-9.
8. Опалева Э.А., Самойленко В.П. Языки программирования и методы трансляции. - СПб.: БХВ-Петербург, 2005. - 480с.,
9. Modern Compiler Design, by Dick Grune, Kees van Reeuwijk, Henri E. Bal, Ceriel J. H. Jacobs, Koen Langendoen, 2nd ed,, ISBN 978 1461 446989, Springer (2012)
10. Руководство по Bison на русском языке
11. А.П. Стасенко Обзор потоковых языков программирования. // Проблемы интеллектуализации и качества систем информатики. Сб. статей под редакцией доктора физ.-мат. наук, профессора, чл.-корр. РАЕН В.Н. Касьянова. Серия "Конструирование и оптимизация программ". Новосибирск, 2006
12. Data flow computing: theory and practice / edited by John A. Sharp. Ablex Publishing Corp. Norwood, NJ, USA,1992. - 569 с.
13. Салибекян С.М., Панфилов П.Б. Объектно-атрибутная архитектура - новый подход к созданию объектных систем // Информационные технологии. 2012, №2 стр. 8-14
14. Gul A. Agha. ACTORS: A Model of Concurrent Computation in Distributed Systems. Series in Articial Intelligence. The MIT Press, Cambridge, Massachusetts, 1986
15. Johan Eker and Jeorn W. JanneckAn introduction to the Caltrop actor language. Department of Electrical Engineering and Computer Sciences, University of California at Berkeley, Berkeley, CA 94720-1770, USA
16. Салибекян С.М., Панфилов П.Б. Анализ языка с помощью объектно-атрибутного подхода к организации вычислений // Программная инженерия. №1, 2013 - стр. 9-16
17. Дэвид Р. Мюссер, Жилмер Дж. Дердж, Атул Сейни. C++ и STL: справочное руководство = STL Tutorial and Reference Guide: C++ Programming with the Standard Template. -- 2-е издание. -- М.: «Вильямс», 2010. -- С. 432.
18. Бьёрн Страуструп. Программирование: принципы и практика использования C++, исправленное издание = Programming: Principles and Practice Using C++. -- М.: Вильямс, 2011. -- С. 1248.
19. Герберт Шилдт. Полный справочник по C++ = C++: The Complete Reference. -- 4-е изд. -- М.: Вильямс, 2011. -- С. 800.
20. Салибекян С.М., Панфилов П.Б. "Среда создания и запуска объектно-атрибутных образов" Св. о гос. рег. программ для ЭВМ № 2011617079 от 12 сентября 2011 г. РОСПАТЕНТ. 2011.
21. Салибекян С.М., Панфилов П.Б., Орлов И.А. "Среда программирования и имитационного моделирования объектно-атрибутной суперкомпьютерной системы с управлением потоком данных". Свидетельство о гос. рег. программы для ЭВМ № 2012616155 от 5 июля 2012 г. РОСПАТЕНТ, 2012.
Приложения
Приложение А
Таблица милликоманд ФУ List
Контекст (Mnemo) |
Значение |
|
FindOr |
Поиск ИЛИ |
|
FindOrLastLine |
Поиск ИЛИ в последней строке |
|
FindAnd |
Поиск И |
|
FindAndLastLine |
Поиск И в последней строке |
|
FindXor |
Поиск XOR |
|
FindXorLastLine |
Поиск XOR в последней строке |
|
FindAndSource |
Поиск И в источнике |
|
FindAndSourceLastLine |
Поиск И в источнике в последней строке |
|
LineOutMk |
Выдать МК с найденной линией |
|
LastLineOut |
Выдать ссылку на последнюю линию списка |
|
LastLinePop |
Выдать ссылку на последнюю линию списка и удалить из списка |
|
LastLineDel |
Выдать ссылку на последнюю линию списка и удалить из ИК |
|
LastLineOutMK |
Выдать ссылку на последнюю линию списка |
|
LastLinePopMK |
Выдать ссылку на последнюю линию списка и удалить из списка |
|
LastLineDelMK |
Выдать ссылку на последнюю линию списка и удалить из ИК |
|
LineAdd |
Добавить строку |
|
LineCopyAdd |
Добавить копию строки |
|
LineCopyTreeAdd |
Добавить копию ОА-графа |
|
LineExcludeMk |
Исключить линию списка |
|
LineDelMk |
Выдать МК со ссылкой на ИК и удалить ИК |
|
LineIpCut |
Удалить последние ИП из текущей линии (в нагрузке количество удаляемых ИП, по умолчанию 1) |
|
LineVarIpCut |
Удалить последние ИП вместе с переменными из текущей линии (в нагрузке количество удаляемых ИП, по умолчанию 1) |
|
LastAttach |
Конкатенация ИК к последней линии списка |
|
LastCopyAttach |
Конкатенация копии ИК к последней линии списка |
|
LineAttach |
Конкатенация ИК к текущей линии списка |
|
LineCopyAttach |
Конкатенация копии ИК к текущей линии списка |
|
LastLoadSet |
Добавить ссылку в указатель последний ИК последней строки |
|
LineLoadSet |
Добавить ссылку в указатель текущей ИК текущей строки |
|
LastLoadCopySet |
Добавить ссылку на копию ИК в указатель последний ИК последней строки |
|
LineLoadCopySet |
Добавить ссылку на копию ИК в указатель текущей ИК текущей строки |
|
LastAtrSet |
Установить атрибут последний ИК последней строки |
|
LineAtrSet |
Установить атрибут последний ИК текущей строки |
|
Set |
Установить указатель на список |
|
Out |
Выдать ссылку на список |
|
OutMk |
Выдать МК со ссылкой на список |
|
MultiLineModeSet |
Установить режим многострочного поиска |
|
MkModeSet |
Режим выполнения всех МК в ИК-шаблоне (МК-ой считается любой атрибут, индекс которого больше 0). При пустой нагрузке режим устанавливается |
|
SuccessProgSet |
Установить указатель на программу, выполняемую при удачном поиска в линии списка |
|
SuccessAfterProgSet |
Установить указатель на программу, выполняемую при удачном поиска в линии списка после обработки программ линии |
|
FailProgSet |
Установить указатель на программу, выполняемую в случае неудачного поиска в линии списка |
|
FailAfterProgSet |
Установить указатель на программу, выполняемую в случае неудачного поиска в линии списка после обработки программ линии |
|
FailAllProgSet |
Установить указатель на программу, выполняемую в случае неудачного поиска во всем списке |
|
ProgAtrSet |
Установить атрибут программы |
|
BackOut |
Выдать входной объект для поиска |
|
BackOutMk |
Выдать МК со входным объектом для поиска |
|
CopyBackOutMk |
Выдать МК с копией входного объекта для поиска |
|
LoadCopyBackOutMk |
Выдать МК с копией нагрузки входного объекта для поиска |
|
ProgAtrSet |
Установить атрибут программы |
|
RezOut |
Выдача результата сравнения |
|
RezOutMk |
Выдача МК с результатом сравнения |
|
MkAtrAdd |
Добавить МК |
|
MkAtrClear |
Очистить список МК |
|
LineToLast |
Установить текущую строку на последнюю строку |
|
LinePush |
Положить текущую линию в стек |
|
LineLastPush |
Положить последнюю линию в стек |
|
LinePop |
Взять текущую линию из стека |
Приложение Б
Код компилятора для создания индексного файла
CapsManager.IndexVectCreate=20000
CapsManager.IpIcIdOutMk=MainBus.IpIcIdSet
CapsManager.IpIcIdOutMk=VariableManager.IpIcIdSet
CapsManager.IpIcIdOutMk=ListSyntez.IpIcIdSet
MainBus.ModeSet=1
\\ -------------------------------------- \\
MainBus.FUTypeCorrectSet=-96 // Корректировка номера типа ФУ для переноса на новую ОА-платформу
NewFU={Mnemo="Console" FUType=FUConsNew}
NewFU={Mnemo="Lex" FUType=FULexNew}
NewFU={Mnemo="GenStr" FUType=FUStrGenNew}
NewFU={Mnemo="Stack" FUType=FUListNew Hint="Стек"}
NewFU={Mnemo="MnemoTable" FUType=FUListNew Hint="Таблица индентификаторов переменных"}
NewFU={Mnemo="Start" FUType=FUListNew Hint="Стартовое состояние автомата"}
NewFU={Mnemo="AfterMnemo" FUType=FUListNew Hint="Состояние после чтения атребута"}
NewFU={Mnemo="AfterAtrMnemo" FUType=FUListNew Hint="Состояние после чтения мнемоники"}
NewFU={Mnemo="AfterVar" FUType=FUListNew Hint="Состояние после чтения переменной"}
NewFU={Mnemo="AfterLoad" FUType=FUListNew Hint="Состояние после чтения нагрузки ИП"}
NewFU={Mnemo="AfterMnemoEqv" FUType=FUListNew Hint="Состояние после чтения мнемоники"}
NewFU={Mnemo="AfterFU" FUType=FUListNew Hint="Состояние после чтения мнемоники ФУ"}
NewFU={Mnemo="MKWait" FUType=FUListNew Hint="Состояние ожидания мнемоники МК"}
NewFU={Mnemo="AfterAtr" FUType=FUListNew Hint="Состояние после мнемоники МК"}
NewFU={Mnemo="MkLoadWait" FUType=FUListNew Hint="Состояние ожидания нагрузки МК"}
MainBus.PartialResetSet \\ Запомнить число созданных ФУ
MainBus.ModeSet=2
ProgAtr*-10
MnemoAtr * -1
SeperatAtr*-2
IntAtr*-3
DoubleAtr*-4
BoolAtr*-5
StrAtr*-6
IcAtr*-7
FUAtr*-8
MKAtr*-9
IntVar*-13
DoubleVar*-14
BoolVar*-15
StrVar*-16
IcVar*-17
Lex.StopProgSet={GenStr.Stop}
Lex.UnicAtrSet=MnemoAtr
Lex.UnicMkSet=MnemoTable.FindOr
Lex.ReceiverMkSet=Start.FindOr
MnemoTable.MkModeSet
MnemoTable.FailAllProgSet={Console.LnOut="Mnemo not found"
Lex.LastLexemaOutMk=MnemoTable.LineCopyAdd MnemoTable.LineLastPush
Lex.LastLexemaToReceiver}// Добавить описание мнемоники в таблицу
MnemoTable.Set=
>{MnemoAtr="FU" Lex.LexemaReplaceToReceiver={FUAtr=1}}
>{MnemoAtr="MK" Lex.LexemaReplaceToReceiver={MKAtr=1}}
Start.Set=
>{IntAtr ProgAtr Lex.ReceiverMkSet=AfterVar.FindOr}
>{IntVar DoubleVar BoolVar StrVar ProgAtr Lex.ReceiverMkSet=AfterVar.FindOr
MnemoTable.LinePush MnemoTable.LineIpCut MnemoTable.OutMk=Console.LnOut}
>{MnemoAtr ProgAtr Lex.ReceiverMkSet=AfterMnemo.FindOr}
>{FUAtr ProgAtr Lex.ReceiverMkSet=AfterFU.FindOr}
>{0 Console.LnOut="Error" Lex.Stop}
AfterVar.Set=
>{SeperatAtr="=" ProgAtr Lex.ReceiverMkSet=AfterMnemoEqv.FindOr}
>{0 ProgAtr Console.LnOut="'=' is not found!" Lex.Stop Lex.LastLexemaOutMk=Console.LnOut}
AfterFU.Set=
>{SeperatAtr="." ProgAtr Lex.ReceiverMkSet=MKWait.FindOr Console.LnOut="MkWait"}
>{0 Console.LnOut="'.' is not found" Lex.Stop}
MKWait.Set=
>{MKAtr ProgAtr Lex.ReceiverMkSet=AfterAtr.FindOr}
>{0 ProgAtr Console.LnOut="MK is not found" Lex.Stop}
AfterAtr.Set=
>{SeperatAtr="#" ProgAtr Lex.ReceiverMkSet=MkLoadWait.FindOr}
>{0 ProgAtr Console.LnOut="MK without load" Lex.LastLexemaOutMk=Start.FindOr}
MkLoadWait.Set=
>{IntAtr DoubleAtr BoolAtr StrAtr IntVar DoubleVar BoolVar StrVar IcVar
ProgAtr Lex.ReceiverMkSet=AfterLoad.FindOr}
>{SeperatAtr="{" ProgAtr MnemoTable.LineCopyAdd={SeperatAtr="{"} Lex.ReceiverMkSet=Start.FindOr}
>{0 ProgAtr Console.LnOut="Const or var is not found" Lex.Stop}
AfterMnemo.Set=
>{SeperatAtr="=" ProgAtr Console.LnOut="AfterMneno" Lex.ReceiverMkSet=AfterMnemoEqv.FindOr}
>{SeperatAtr="*" ProgAtr Console.LnOut="AfterMneno" Lex.ReceiverMkSet=AfterAtrMnemo.FindOr}
>{SeperatAtr="{" ProgAtr Stack.LineCopyAdd={Atr="{"} MnemoTable.LastCopyAttach={IcVar}
Lex.ReceiverMkSet=Start.FindOr}
>{0 Console.LnOut="'=' is not found" Lex.Stop}
AfterAtrMnemo.Set=
>{ConstInt Lex.LastLexemaAtrSet=MKAtr Lex.LastLexemaOutMk=MnemoTable.LineCopyAdd Lex.ReceiverMkSet=Start.FindOr}
>{0 Console.LnOut="Integer constant is expected" Lex.Stop}
AfterMnemoEqv.Set=
>{IntVar DoubleVar BoolVar StrVar}
>{IntAtr ProgAtr Lex.LastLexemaAtrSet=IntVar}
>{DoubleAtr ProgAtr Lex.LastLexemaAtrSet=DoubleVar}
>{BoolAtr ProgAtr Lex.LastLexemaAtrSet=BoolVar}
>{StrAtr ProgAtr Lex.LastLexemaAtrSet=StrVar}
AfterMnemoEqv.SuccessAfterProgSet={
MnemoTable.LinePop
MnemoTable.LastCopyAttach={Lex.LexemaReplaceToReceiver}
Console.LnOut="AfterMnemoEqv"
Lex.LastLexemaVarSet
Lex.LastLexemaCopyOutMk=MnemoTable.LineLoadSet
Lex.ReceiverMkSet=Start.FindOr
}
AfterLoad.Set=
>{SeperatAtr="}" ProgAtr Stack.EmptyProgExec={Console.LnOut="'}' without '{'" Lex.Stop}
Stack.EmptyProgExec={Stack.LastLineDelMk Lex.ReceiverMkSet=Start.FindOr}
Lex.ReceiverMkSet=Start.FindOr}
>{0 ProgAtr Lex.LastLexemaOutMk=Start.FindOr}
StrGenGenStr.ReceiverMkSet=Lex.Lexing
StrGen.Start="Prog.txt"
Console.LnOut="---MnemoTable-----"
MnemoTable.OutMk=Console.LnOut
Приложение В
Тестирование работы экспериментального компилятора
№ |
Исходные данные |
Ожидаемый результат |
Полученный результат |
Комментарий |
|
1. |
x=10 |
Переменная “x” в таблице идентификаторов переменных содержит число 10 |
---"---- |
Тест успешный |
|
2. |
x=10 x=20 |
Переменная “x” в таблице идентификаторов переменных содержит число 20 |
---"---- |
Тест успешный |
|
3. |
Atr*-30 |
Атрибут “Atr” содержит число -30 |
---"---- |
Тест успешный |
|
4. |
Atr*-30 Atr*-50 |
Ошибка, т.к. нельзя переопределять атрибут |
Ошибка «MK without load» |
Тест успешный |
|
5. |
MnemoIC{10#10} |
Указатель с именем «MnemoIC» на ИК в таблице идентификаторов переменных |
---"--- |
Тест успешный |
|
6. |
MnemoIC{10#10 |
Ошибка, нет «}» |
Ошибка, «} is expected» |
Тест успешный |
|
7. |
Atr*-10 FU.MK={Atr#1} |
Нет общения об ошибке, в таблице мнемоник присутствует описание атрибута Atr. |
---"--- |
Тест успешный |
|
8. |
Atr=-10 FU.MK={Atr=1} |
Ошибка |
Ошибка « '=' is not found! » |
Тест успешный |
|
9. |
MnemoIC{10#10}} |
Ошибка |
Ошибка «} is expected» |
Тест успешный |
|
10. |
MnemoIC{} |
Ошибка |
Ошибка «} is expected» |
Тест успешный |
|
11. |
X=10 MnemoIC{3#X} |
Нет ошибки |
Нет ошибки |
Тест успешный |
|
12. |
X=10 MnemoIC{ FU.MK #X} |
Нет ошибки |
Нет ошибки |
Тест успешный |
Приложение Г
Листинг программы
Файл “Consts.h”
// Описание основных констант и информационных конструкций
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
// Типы переменных
const int Tvoid = 0, Tint = 2, Tfloat = 4, Tdouble = 6, Tchar = 8, Tstring = 10, TIP = 12, Tbool = 14, TIC = 16;
const int TPPoint = 18, TGraph=20, TFU=22;
// Типы констант
const int Cvoid = 1, Cint = 3, Cfloat = 5, Cdouble = 7, Cchar = 9, Cstring = 11, CIP = 13, Cbool = 15, CIC = 17;
const int CPPoint = 19, CGraph = 21, CFU = 23;
// Общие типы данных (остаток от целочисленного деления на 2 типа переменной или константы)
const int Dvoid=0, Dint = 1, Dfloat = 2, Ddouble = 3, Dchar = 4, Dstring = 5, DIP = 6, Dbool = 7, DIC = 8;
const int DPPoint = 9, DGraph = 10, DFU = 11;
// Типы ФУ
const int FUBus = 0, FUCons = 1, FUStrGen = 2, FULex = 3, FUList = 4, FUFind = 5;
// Общие атрибуты
const int ProgAtr = -10, Atr=-6;
void* findOriginalIC(vector<void*>* ptrn, void* LocTable, void* uK); //Найти адрес ИК исходного графа по таблице соответствий
bool isIPinIC(void* iP, void* iC); //проверка, что ИК входит в ИП
class LoadPoint
{
public:
unsigned int Type = 0; // Неизвестный тип
void *Point;
bool IsConvert(unsigned int T) {}; // Тест на возможность конвертации значения из Point в определенный тип
int ToInt() { return *(int*)Point; }; // Перевод в integer
double ToDouble() { return *(double*)Point; }; // Перевод в integer
bool ToBool() { return *(bool*)Point; }; // Перевод в integer
char ToChar() { return *(char*)Point; }; // Перевод в integer
string ToStr() { return *(string*)Point; }; // Перевод в integer
void Copy(LoadPoint *LP);
void Clear(); // Сброс нагрузки ИП
void VarClear(); // Сброс нагрузки ИП в том числе и с переменной (переменная стирается)
void print(void* AtrMnemo=nullptr, string offset=""); // Параметр - указатель на табл. мнемоник атрибутов
LoadPoint Clone(); // Дублировать нагрузку
void ConstTypeSet(bool F = true) { if (F)Type |= 1; else VarTypeSet(); }; // Установить тип 'константа'
// Установить тип 'переменная'
void VarTypeSet(bool F = true) {
if (!F) { ConstTypeSet(); return; } Type |= 1; if (Type >= 0)Type -= 1; else Type += 1;}
};абстрактный автомат транслятор виртуальный
// struct TAtrMnrmo
class ip // Информационная пара
{
public:
int atr = 0;
LoadPoint Load = {0, nullptr }; // Указатель на нагрузку с типом даннных
~ip() { }//Load.Clear(); };
void copy(ip *IP)// Копирование ИП
{
atr = IP->atr;
Load.Point = IP->Load.Point;
Load.Type = IP->Load.Type;
};
void copy(void *IP) { copy(*(ip*)IP); }// Копирование ИП
void copy(ip &IP)// Копирование ИП
{
atr = IP.atr;
Load.Copy(&IP.Load);
};
void copy(LoadPoint &LP)// Копирование ИП
{
switch (LP.Type >> 1)
{
case DIP:
atr = ((ip*)LP.Point)->atr;
Load.Copy(&((ip*)LP.Point)->Load);
break;
case DIC:
atr = ((vector<ip>*)LP.Point)->begin()->atr;
Load.Copy(&((vector<ip>*)LP.Point)->begin()->Load);
}
};
ip* сlone()
{
ip* ip_new = new ip;
ip_new->copy(*this);
return ip_new;
}
};
struct deletedIC //удаленная ИП
{
vector<ip*>* IC; // информационная капсула, содержащая удаленную ИП
void* programm; // указатель на милипрограмму (ИК, содержащую набор милликоманд)
};
class FU { // Ядро функционального устройства
public:
virtual void ProgFU(int MK, LoadPoint Load) {}; // Реализация логики работы ФУ
FU() { Bus = nullptr; };
FU(FU *BusContext) { Bus = BusContext; };
void MkExec(int MK, LoadPoint Load, FU* BusContext = nullptr); // Выполнить одну милликоманду
// void OutMK2(LoadPoint MKL, LoadPoint Load)
// {if(MKL.Point!=nullptr && MKL.Type>>1==Dint)
// MkExec(*((int*)(Load.Point)), Load); };
FU *Bus; // Ссылка на контекст Шины
int FUMkRange = 1000; // Диапазон МК для каждого ФУ
void CommonMk(int Mk, LoadPoint Uk); // Выполнение общих МК для ФУ
};
typedef vector<vector<ip>*> ICVect;
typedef vector<ip>* IC_type;
void ICDel(void* Uk);// Удаление ИК
void* ICCopy(LoadPoint uk);// Копирование ИК
void ProgExec(void *Uk, FU* Bus, vector<ip>::iterator *Start=nullptr); // Исполнение программы из ИК
bool LoadCmp(LoadPoint x, LoadPoint y); // Сравнение двух нагрузок ИП
bool IPCmp(ip* x, ip* y); // Сравнение двух ИП
void AtrProgExec(vector<ip>* Prog, int Atr, FU* Bus, bool AfterContinue = false); // Найти в ИК ИП с атрибутом Atr и выполнить программу либо по адр. в нагрузке, либо после найденной ИП
Файл «Consts.cpp»
#include "stdafx.h"
#include "Consts.h"
#include <iostream>
#include <string>
#include "LocationTable.h"
using namespace std;
void ICDel(void* Uk) // Удаление ИК
{
for (auto i : *(IC_type)Uk)
i.Load.Clear();
delete (IC_type)Uk;
}
void* ICCopy(LoadPoint uk) // Копирование ИК
{
IC_type CapsNew = new vector<ip>;
if (uk.Type >> 1 == DIP) // Если передается ИП
{
CapsNew->push_back(*(*(ip*)uk.Point).сlone());
return CapsNew;
}
IC_type Uk = (IC_type)uk.Point;
CapsNew->resize(((IC_type)Uk)->size());
for (auto i = ((IC_type)Uk)->begin(), j = CapsNew->begin(); j != CapsNew->end(); i++, j++)
{
j->atr = i->atr;
j->Load.Copy(&i->Load);
}
return CapsNew;
}
LoadPoint LoadPoint::Clone()
{
switch (Type)
{
case Cstring: return { Type, new string(*(string*)Point) };
case Cint: return { Type, new int(*(int*)Point) };
case Cfloat: return { Type, new float(*(float*)Point)};
case Cdouble: return { Type,new double(*(double*)Point)};
case Cchar: return { Type,new char(*(char*)Point) };
case Cbool: return { Type,new bool(*(bool*)Point) };
case CPPoint: return { Type,new (void*)(*(void**)Point) };
case CIP: return { Type, (*(ip*)Point).сlone()};
case CIC: return { Type, Point = ICCopy(*this) };
default: return *this;
}
}
void LoadPoint::Copy(LoadPoint *LP)
{
Type = LP->Type;
if (LP->Type % 2 == 0)
{
Point = LP->Point;
return;
}
switch (Type)
{
case Cstring: Point = new string(*(string*)LP->Point); break;
case Cint: Point = new int(*(int*)LP->Point); break;
case Cfloat: Point = new float(*(float*)LP->Point); break;
case Cdouble: Point = new double(*(double*)LP->Point); break;
case Cchar: Point = new char(*(char*)LP->Point); break;
case Cbool: Point = new bool(*(bool*)LP->Point); break;
case CPPoint: Point = new (void*)(*(void**)LP->Point); break;
case CIP: // ???
break;
case CIC:
Point = ICCopy(*LP);
break;
}
}
void LoadPoint::Clear() // Сбросить нагрузку
{
if (Type % 2 == 0) return;
switch (Type)
{
case Cstring: delete (string*)Point; break;
case Cint: delete (int*)Point; break;
case Cfloat: delete (float*)Point; break;
case Cdouble: delete (double*)Point; break;
case Cchar: delete (char*)Point; break;
case Cbool: delete (bool*)Point; break;
case CPPoint: delete (void**)Point; break;
case CIP: // ???
break;
case CIC:
ICDel(Point);
break;
}
Type = 0; Point = nullptr;
}
void ProgExec(void *UK, FU* Bus, vector<ip>::iterator *Start) // Исполнение программы из ИК
{
vector<ip> *Uk = (IC_type) UK;
if (Uk == nullptr || Bus == nullptr) return;
if(Start==nullptr)
for (auto &i : *Uk)
Bus->ProgFU(i.atr, i.Load);
else
for(auto i= *Start;i!=Uk->end();i++)
Bus->ProgFU(i->atr, i->Load);
}
void FU::CommonMk(int Mk, LoadPoint Uk)
{
switch (Mk)
{
case 990: // ProgExec
ProgExec(((vector<ip>*)Uk.Point), Bus);
break;
case 995: //ContextOut Выдать указатель на контекст ФУ
if (Uk.Type >> 1 == Dvoid || Uk.Type >> 1 == DPPoint)
Uk.Point = this;
break;
case 999: //ContextOutMK Выдать милликоманду с указателем на контекст ФУ
if (Uk.Type >> 1 == Dint)
Bus->ProgFU(*(int*)Uk.Point, { TFU, this });
break;
}
}
void FU::MkExec(int MK, LoadPoint Load, FU* BusContext) // Выдача МК с нагрузкой
{
if(MK<FUMkRange) // Если МК адресована сомому ФУ
ProgFU(MK, Load);
else
if (BusContext != nullptr && BusContext!=NULL)
BusContext->ProgFU(MK, Load);
else
Bus->ProgFU(MK, Load);
}
bool LoadCmp(LoadPoint x, LoadPoint y) // Сравнение двух нагрузок ИП
{
// Доработать с указателями на ИК и ИП
if (x.Point == nullptr || y.Point == nullptr)
return true;
int xt = x.Type >> 1, yt = y.Type >> 1;
if( (xt== Dint || xt == Dfloat || xt== Ddouble || xt== Dchar)&&(yt == Dint || yt == Dfloat || yt == Ddouble || yt == Dchar) )
switch (xt)
{
case Dint:
switch (yt)
{
case Dint: return *(int*)x.Point == *(int*)y.Point;
case Dfloat: return *(int*)x.Point == *(float*)y.Point;
case Ddouble: return *(int*)x.Point == *(double*)y.Point;
case Dchar: return *(int*)x.Point == *(char*)y.Point;
}
case Dfloat:
switch (yt)
{
case Dint: return *(float*)x.Point == *(int*)y.Point;
case Dfloat: return *(float*)x.Point == *(float*)y.Point;
case Ddouble: return *(float*)x.Point == *(double*)y.Point;
case Dchar: return *(float*)x.Point == *(char*)y.Point;
}
case Ddouble:
switch (yt)
{
case Dint: return *(double*)x.Point == *(int*)y.Point;
case Dfloat: return *(double*)x.Point == *(float*)y.Point;
case Ddouble: return *(double*)x.Point == *(double*)y.Point;
case Dchar: return *(double*)x.Point == *(char*)y.Point;
}
case Dchar:
switch (yt)
{
case Dint: return *(char*)x.Point == *(int*)y.Point;
case Dfloat: return *(char*)x.Point == *(float*)y.Point;
case Ddouble: return *(char*)x.Point == *(double*)y.Point;
case Dchar: return *(char*)x.Point == *(char*)y.Point;
}
}
if (xt == Dbool && yt == Dbool)
return *(bool*)x.Point == *(bool*)y.Point;
if (xt == Dstring && yt == Dstring)
return *(string*)x.Point == *(string*)y.Point;
return false;
}
bool IPCmp(ip* x, ip* y) // Сравнение двух ИП
{
if (!LoadCmp(x->Load, y->Load))
return false;
else
if (x->atr == y->atr || x->atr == 0 || y->atr == 0)
return true;
else
return false;
}
// Найти в ИК ИП с атрибутом Atr и выполнить программу либо по адр. в нагрузке, либо после найденной ИП
void AtrProgExec(vector<ip>* Prog, int Atr, FU* Bus, bool AfterContinue)
{
auto i = Prog->begin();
for (; i != Prog->end() && i->atr != Atr; i++);
if (i != Prog->end())
{
if (i->Load.Point != nullptr)
ProgExec((vector<ip> *)i->Load.Point, Bus);
if((++i)!=Prog->end() && AfterContinue)
ProgExec(Prog, Bus,&i);
}
}
bool isIPinIC(void* iP, void* iC) //проверка, что ИК входит в ИП
{
for (auto i = ((IC_type)iC)->begin()._Ptr; i != ((IC_type)iC)->end()._Ptr; i++) {
if (IPCmp(i, ((ip*)iP)))
return true;
}
return false;
}
Файл «Searsh.h»
#pragma once
#include "Consts.h"
#include "Search.h"
#include <set>
class Search
{
private:
bool null_check();// Проверка на нуль (false, если всё в порядке)
void MkAtrExec();
public:
// vector<ip>* Template; // Шаблон для поиска
LoadPoint Template={0, nullptr}; // Шаблон для поиска
LoadPoint Obj = { 0, nullptr }; //ИК для поиска
bool MkMode = false; // Режим выполнения всех МК в ИК-шаблоне (МК-ой считается любой атрибут, индекс которого больше 0)
set<int> MkAtr; // Список атрибтов, представляющих МК, выполняющиеся в случае успешного поиска
FU *MainFU; // Ссылка на главное ФУ, короторое пользуется функционалом searcher-а
bool Rez=false; // Результат поиска
vector<ip> *SuccessProg = nullptr, *FailProg = nullptr; // Указатели на программы по успеху и неуспеху поиска
vector<ip> *SuccessAfterProg = nullptr, *FailAfterProg = nullptr; // Указатели на программы по успеху и неуспеху поиска, выполняющиеся после обработки программы линии
ip *IPTemplPoint = nullptr, *IPPoint = nullptr; // Указатели на найденные ИП в шаблоне и в ИК
int Prog_atr = ProgAtr; // Атрибут программы, выполняющейся при успешном поиске (<0 атрибут не учитывается)
void MkAtrAdd(int MK) { MkAtr.insert(MK); };
void MkAtrClear() { MkAtr.clear(); };
bool Search::FindIPObj(LoadPoint obj, LoadPoint Templ, bool XOR=false); // Поиск, если obj является ИП (Для Or And)
bool FindOr(LoadPoint obj); // Поиск
bool FindXor(LoadPoint obj); // Поиск
bool FindAnd(LoadPoint obj); // Поиск
bool FindAndSource(LoadPoint obj); // Поиск
bool FindIP(LoadPoint obj) {}; // Сравнеие ИП
};
Файл «Searsh.cpp»
// Объект для поиска в ИК, встраивается в FUFind и FUList
#include "stdafx.h"
#include <string.h>
#include "Search.h"
using namespace std;
bool Search::null_check()// Проверка на нуль (false, если всё в порядке)
{
if (Template.Point != nullptr && Obj.Point != nullptr)
return false;
else
{
IPTemplPoint = nullptr;
IPPoint = nullptr;
Rez = false;
return true;
}
}
void Search::MkAtrExec() // Выполнить Милликоманды из ИК-шаблона
{
if (Template.Point == nullptr || Template.Type>>1!=DIC) return;
for (auto i=((IC_type)Template.Point)->begin();i<((IC_type)Template.Point)->end();i++)
if (MkMode)
{
if (i->atr == ProgAtr && i->Load.Point==nullptr)
break;
if(i->atr>0) MainFU->MkExec(i->atr, i->Load);
}
else
if (MkAtr.count(i->atr))
MainFU->MkExec(i->atr, i->Load);
}
bool Search::FindIPObj(LoadPoint Templ, LoadPoint obj, bool XOR) // Поиск, если obj является ИП (Для Or And)
{
if(Templ.Type>>1==DIP && obj.Type >> 1 == DIP)// Нагрузка и объект - оба ИП
if(IPCmp((ip*)Templ.Point, (ip*)obj.Point))
{
Rez = true;
IPTemplPoint = (ip*)Templ.Point;
IPPoint = (ip*)obj.Point;
return true;
}
else
{
Rez = false; IPTemplPoint = nullptr; IPPoint = nullptr;
ProgExec(FailProg, MainFU->Bus);
return false;
}
int Count = 0; // Счетчик количества совпадений ИП
auto i = ((IC_type)Templ.Point)->begin();
for (; i != ((IC_type)Templ.Point)->end() && (Prog_atr < 0 || i->atr != Prog_atr); i++)
{
if (MkAtr.count(i->atr)) continue;
if (IPCmp(i._Ptr, (ip*)obj.Point))
if(!XOR)
break;
else
{
Count++;
if (Count > 2) break;
}
}
if (i == ((IC_type)Templ.Point)->end() || i->atr == Prog_atr || Count==2)
{
Rez = false; IPTemplPoint = nullptr; IPPoint = nullptr;
ProgExec(FailProg, MainFU->Bus);
return false;
}
else
{
Rez = true;
IPTemplPoint = i._Ptr;
IPPoint = (ip*)obj.Point;
return true;
}
}
bool Search::FindOr(LoadPoint obj)
{
Obj = obj; // Запомнить ИК для поиска
if (null_check()) return false;
// Поиск одно ИП
Rez = false;
IPTemplPoint = nullptr;
IPPoint = nullptr;
if (Obj.Type >> 1 == DIP)
if (!FindIPObj(Template, Obj))
return false;
else
{
ProgExec(SuccessProg, MainFU->Bus);
AtrProgExec((IC_type)Template.Point, Prog_atr, MainFU->Bus, true);
MkAtrExec();
ProgExec(SuccessAfterProg, MainFU->Bus);
return true;
}
auto i = ((IC_type)Template.Point)->begin();
for (; i != ((IC_type)Template.Point)->end() && (Prog_atr < 0 || i->atr != Prog_atr); i++)
{
if (MkAtr.count(i->atr)) continue;
auto j = ((vector<ip>*)(Obj.Point))->begin();
for (; j != ((vector<ip>*)(Obj.Point))->end() && (Prog_atr < 0 || j->atr != Prog_atr); j++)
{
if (MkAtr.count(j->atr)) continue;
if (IPCmp(i._Ptr, j._Ptr))
{
IPTemplPoint = i._Ptr;
IPPoint = j._Ptr;
break;
}
}
if (j != ((vector<ip>*)(Obj.Point))->end() || i->atr == Prog_atr)
break;
}
if (i == ((IC_type)Template.Point)->end() || i->atr == Prog_atr)
{
Rez = false; IPTemplPoint = nullptr; IPPoint = nullptr;
ProgExec(FailProg, MainFU->Bus);
return false;
}
else
{
Rez = true;
ProgExec(SuccessProg, MainFU->Bus);
AtrProgExec((IC_type)Template.Point, Prog_atr, MainFU->Bus, true);
MkAtrExec();
ProgExec(SuccessAfterProg, MainFU->Bus);
return true;
}
}
bool Search::FindXor(LoadPoint obj)
{
int Count = 0; // Счетчик количества совпадений
Obj = obj;
Rez = false;
if (Obj.Type >> 1 == DIP)
if (!FindIPObj(Template, Obj, true))
return false;
else
{
ProgExec(SuccessProg, MainFU->Bus);
AtrProgExec((IC_type)Template.Point, Prog_atr, MainFU->Bus, true);
MkAtrExec();
ProgExec(SuccessAfterProg, MainFU->Bus);
return true;
}
if (null_check()) return false;
for (auto i = ((IC_type)Template.Point)->begin();
Count<2 && i != ((IC_type)Template.Point)->end() && (Prog_atr < 0 || i->atr != Prog_atr); i++)
{
if (MkAtr.count(i->atr)) continue;
for (auto j = ((vector<ip>*)(Obj.Point))->begin();
Count<2 && j != ((vector<ip>*)(Obj.Point))->end() && (Prog_atr < 0 || j->atr != Prog_atr); j++)
{
if (MkAtr.count(j->atr)) continue;
if (IPCmp(i._Ptr, j._Ptr))
{
Count++;
IPTemplPoint = i._Ptr;
IPPoint = j._Ptr;
}
}
}
if (Count == 1)
{// Выполнилось условие
Rez = true;
ProgExec(SuccessProg, MainFU->Bus);
AtrProgExec((IC_type)Template.Point, Prog_atr, MainFU->Bus, true);
MkAtrExec();
ProgExec(SuccessAfterProg, MainFU->Bus);
return true;
}
else
{
Rez = false;
IPTemplPoint = nullptr;
IPPoint = nullptr;
ProgExec(FailProg, MainFU->Bus);
return false;
}
}
bool Search::FindAnd(LoadPoint obj) // Поиск
{
Obj = obj;
if (null_check()) return false;
IPTemplPoint = nullptr;
IPPoint = nullptr;
Rez = false;
if (Obj.Type >> 1 == DIP)
if (!FindIPObj(Template, Obj))
return false;
else
{
ProgExec(SuccessProg, MainFU->Bus);
AtrProgExec((IC_type)Template.Point, Prog_atr, MainFU->Bus, true);
MkAtrExec();
ProgExec(SuccessAfterProg, MainFU->Bus);
return true;
}
auto i = ((vector<ip>*)(Obj.Point))->begin();
for (; i != ((vector<ip>*)(Obj.Point))->end(); i++)
{
if (MkAtr.count(i->atr)) continue;
auto j = ((IC_type)Template.Point)->begin();
for (; j != ((IC_type)Template.Point)->end() && (!IPCmp(i._Ptr,j._Ptr) || (MkAtr.count(j->atr))); j++);
if (j == ((IC_type)Template.Point)->end()) break;
if (IPTemplPoint==nullptr)
{
IPTemplPoint = j._Ptr;
IPPoint = i._Ptr;
}
}
if (i==((vector<ip>*)(Obj.Point))->end())
{// Выполнилось условие
Rez = true;
ProgExec(SuccessProg, MainFU->Bus);
AtrProgExec((IC_type)Template.Point, Prog_atr, MainFU->Bus);
MkAtrExec();
ProgExec(SuccessAfterProg, MainFU->Bus);
return true;
}
else
{
Rez = false;
IPTemplPoint = nullptr;
IPPoint = nullptr;
ProgExec(FailProg, MainFU->Bus);
return false;
}
}
bool Search::FindAndSource(LoadPoint obj) // Поиск
{
Obj = obj;
Rez = false;
if (null_check()) return false;
IPTemplPoint = nullptr;
IPPoint = nullptr;
if (Template.Type >> 1 == DIP && obj.Type >> 1 == DIP)
if (!FindIPObj(Template, Obj))
return false;
else
{
ProgExec(SuccessProg, MainFU->Bus);
AtrProgExec((IC_type)Template.Point, Prog_atr, MainFU->Bus, true);
MkAtrExec();
ProgExec(SuccessAfterProg, MainFU->Bus);
return true;
}
if (Template.Type >> 1 == DIP)
if (!FindIPObj(Obj, Template))
return false;
else
{
swap(IPTemplPoint,IPPoint);
ProgExec(SuccessProg, MainFU->Bus);
AtrProgExec((IC_type)Template.Point, Prog_atr, MainFU->Bus, true);
MkAtrExec();
ProgExec(SuccessAfterProg, MainFU->Bus);
return true;
}
if (Obj.Type >> 1 == DIP)
{
auto i = ((IC_type)Template.Point)->begin();
for (; i != ((IC_type)Template.Point)->end() && IPCmp(i._Ptr,(ip*)obj.Point); i++);
if (i == ((IC_type)Template.Point)->end())
{
Rez = true;
IPTemplPoint = (ip*)Template.Point;
IPPoint = (ip*)obj.Point;
return true;
}
else
{
Rez = false;
IPTemplPoint = nullptr;
IPPoint = nullptr;
return false;
}
}
auto i = ((IC_type)Template.Point)->begin();
for (; i != ((IC_type)Template.Point)->end(); i++)
{
if (MkAtr.count(i->atr)) continue;
auto j = ((vector<ip>*)(Obj.Point))->begin();
for (; j != ((vector<ip>*)(Obj.Point))->end() && (!IPCmp(i._Ptr, j._Ptr) || (MkAtr.count(j->atr))); j++);
if (j == ((vector<ip>*)(Obj.Point))->end()) break;
if (IPTemplPoint == nullptr)
{
IPTemplPoint = i._Ptr;
IPPoint = j._Ptr;
}
}
if (i != ((IC_type)Template.Point)->end())
{// Выполнилось условие
Rez = true;
ProgExec(SuccessProg, MainFU->Bus);
AtrProgExec((IC_type)Template.Point, Prog_atr, MainFU->Bus, true);
MkAtrExec();
ProgExec(SuccessAfterProg, MainFU->Bus);
return true;
}
else
{
Rez = false;
IPTemplPoint = nullptr;
IPPoint = nullptr;
ProgExec(FailProg, MainFU->Bus);
return false;
}
}
Файл «StrGen.h»
#pragma once
#include "Consts.h"
#include <iostream>
#include <string>
#include <fstream>
class StrGenContext : public FU {
private:
int LineCount = 0;
void *Receiver = nullptr;
int ReceiverMK = 0;
bool work = true;
ifstream Source;
string Filename;
int TimeStart = 0, TimeLong = 0;// Время начала компиляции, время конца компиляции
int str_count = 0; // счетчик считанных строк
vector<string> str_buf; // Буфер строк
int str_buf_size;// Размер буфера строк
int str_bufCount = 0; // Индекс текущей строки в буфере
void *StartProg = nullptr, *FinProg = nullptr, *StopProg = nullptr; // Ссылки на программы, аапускаемые при начале, оокончании и прерывании генерации строк
public:
void ProgFU(int MK, LoadPoint Load) override;
StrGenContext(FU *BusContext, FU *Templ) : FU(BusContext) { ProgFU(0, { 0, nullptr }); Bus = BusContext;};
StrGenContext(): FU() { StrGenContext(nullptr, nullptr); };
};
Файл «StrGen.cpp»
#include "stdafx.h"
#include "StrGen.h"
#include <ctime>
void StrGenContext::ProgFU(int MK, LoadPoint Load)
{
switch (MK)
{
case 0: //Reset
str_buf.clear();
str_buf.push_back("");
Receiver = nullptr;
ReceiverMK = 0;
str_buf_size = 1;
LineCount = 0;
Source.close();
Receiver = Bus;
str_bufCount = 0;
break;
case 20: //ReceiverSet Установить ссылку на приемник строк
Receiver = Load.Point;
case 21: //ReceiverMkSet Установить МК для приемника строк
if (Load.Type >> 1 == Dint) ReceiverMK = *(int*)Load.Point; break;
case 1: // SourceSet
break;
case 2: // SourceSetStart
break;
case 3: // Start Начать генерацию
work = true;
ProgExec(StartProg,Bus);// Выполнить стартовую программу
TimeStart = clock();
TimeLong = 0;
if (Load.Point != nullptr)
{
Filename = *((std::string*)(Load.Point));
Source.open(Filename);
LineCount = 0;
}
while (Source && work)
{
string str;
getline(Source, str, '\n');
LineCount++;
str_bufCount = (str_bufCount+1)%str_buf_size;
str_buf[str_bufCount] = str;
LoadPoint Point;
Point.Type = 2;
Point.Point = &str;
((FU*)Receiver)->ProgFU(ReceiverMK, Point);
system("pause");
}
Source.close();
TimeLong = clock() - TimeStart;
ProgExec(FinProg, Bus);// Выполнить завершающую программу
break;
case 4: // Stop
work = false;
ProgExec(StopProg, Bus);// Выполнить программу по прерыванию генерации строк
break;
case 5: // Pause
work = false;
break;
case 6: // Continue
{work = true;
ProgFU(3, { 0, nullptr }); }
break;
case 15: // TimeOut Выдать время компиляции в секундах
if (Load.Type == Tdouble)
*(double*)Load.Point = (double) TimeLong/ CLOCKS_PER_SEC;
if (Load.Type == Tfloat)
*(float*)Load.Point = (float) TimeLong / CLOCKS_PER_SEC;
break;
case 30: // TimeMkOut Выдать МК со времем компиляции в секундах
MkExec(*(int*)(Load.Point), { Cdouble , new double((double)TimeLong / CLOCKS_PER_SEC) });
break;
case 35: // LineBufSizeSet Установить размер буфера строк
str_buf_size = *(int*)Load.Point;
str_bufCount = 0;
str_buf.resize(str_buf_size);
break;
case 40: // LogOut
break;
case 50: // LineCountOutMk
MkExec(*(int*)Load.Point, { Tint, &LineCount });
break;
case 51: // LastLineBufOutMk Выдать МК с последней строкой из буфера
MkExec(*(int*)Load.Point, { Tstring, &str_buf[str_bufCount] });
break;
case 52: // LineBufOutMk // Выдать МК со строками из буфера
for (int i = 0; i < str_buf_size; i++)
{
MkExec(*(int*)Load.Point, { Tstring, &str_buf[str_bufCount] });
str_bufCount = (str_bufCount + 1) % str_buf_size;
}
break;
case 60: // StartProgSet // Установить указатель на программу, выполняемую при запуске нерации строк из файла
StartProg = Load.Point;
break;
case 61: // FinProgSet // Установить указатель на программу, выполняемую по завершению генерации строк из файла
FinProg = Load.Point;
break;
case 62: // StopProgSet // Установить указатель на программу, выполняемую при прерывании генерации строк из файла
StopProg = Load.Point;
break;
default:
CommonMk(MK, Load);
break;
}
}
Файл «Lex.h»
#pragma once
#include "Consts.h"
#include <set>
#include <map>
struct MkFu
{
int Mk;
FU* Fu;
};
class Lex : public FU {
private:
void LexOut(bool Copy=false);
string ABC_templ = "_QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm"; // Алфавит символов
string Seps_templ = "`!@#$%^&*()+=-{}[]?;:,.\\/|\"";// Алфавит разделителей
set<char> ABC, Seps, Digit;
void *StartProg = nullptr, *StopProg = nullptr, *FinProg = nullptr; // Программы, выполняемые при запуске процесса лексического анализа
public:
void ProgFU(int MK, LoadPoint Load);
Lex(FU *BusContext, FU *Templ);
Lex() ;
FU *Receiver = nullptr;
int ReceiverMK = 0;
int S = 0; // Номер состояния распознающего автомата
bool Work = true; // Флаг рабочего режима лексера
int MnemoAtr = -1, SeperatAtr=-2, IntAtr=-3, DoubleAtr=-4, BoolAtr=-5, StrAtr=-6;
int ib = 0, SizeBuf = 5; // Текущая позиция выходной ИП выходной лексемы и размер буфера
ip *LexBuf; // Буфер выходных лексем
vector<ip> *ErrProg=nullptr; // Программа, запускаемая при ошибке
map<int,MkFu> UnicAtr; // Список специфических атрибутов, по которым идет обработки другими ФУ
};
Файл «Lex.cpp»
#include "stdafx.h"
#include "Lex.h"
#include <string.h>
using namespace std;
void Lex::LexOut(bool Copy)
{
auto uk = UnicAtr.find(LexBuf[ib].atr);
if (uk!= UnicAtr.end())
{
if (uk->second.Fu != nullptr && uk->second.Mk!= 0)
if(Copy)
uk->second.Fu->ProgFU(uk->second.Mk, { TIP, &LexBuf[ib] });
else
uk->second.Fu->ProgFU(uk->second.Mk, { TIP, LexBuf[ib].сlone() });
}
else
if (Receiver != nullptr)
if (Copy)
Receiver->ProgFU(ReceiverMK, { TIP, LexBuf[ib].сlone() });
else
Receiver->ProgFU(ReceiverMK, { TIP, &LexBuf[ib] });
}
void Lex::ProgFU(int MK, LoadPoint Load)
{
// Доделать буфер ИП с лексемами
switch (MK)
{
case 0: // Reset
S = 0;
// FigureBuf = "";
UnicAtr.clear();
ReceiverMK = 0;
ErrProg = nullptr;
break;
case 5: //ReceiverMKSet
if (Load.Type >> 1 == Dint) ReceiverMK = *(int*)Load.Point; break;
case 10: //ErrProgSet
ErrProg = (vector<ip> *)Load.Point;
break;
case 12: // StartProgSet Установить программу, запускаемую перед началом компиляции
StartProg = Load.Point;
break;
case 13: // StopProgSet Установить программу, запускаемую при досрочном завершении лексисческого анализа по МК Stop
StopProg = Load.Point;
break;
case 14: // FinProgSet Установить программу, запускаемую после окончания анализа строки
FinProg = Load.Point;
break;
case 15:// UnicAtrSet Установить уникальный атрибут
UnicAtr[*(int*)Load.Point] = { 0,Bus };
break;
case 16:// UnicMkSet Установить МК для уникального атрибута
if(UnicAtr.size())
(--UnicAtr.end())->second.Mk= *(int*)Load.Point;
break;
case 17:// UnicFuSet Установить контекст для уникального атрибута
if (UnicAtr.size())
(--UnicAtr.end())->second.Fu = (FU*)Load.Point;
break;
case 18:// UnicReset Сбросить список уникальных атрибутов
UnicAtr.clear();
break;
case 20: // LexBufSizeSet Установить размер буфера лексем
if (Load.Type >> 1 != Dint) break;
for (int i = 0; i < SizeBuf; LexBuf[i++].Load.Clear());
delete[] LexBuf;
SizeBuf = *(int*)Load.Point;
LexBuf = new ip[SizeBuf];
for (int i = 0; i < SizeBuf; LexBuf[i++].Load = { 0,nullptr });
break;
case 27: //LexemaReplace Заменить тукущую лексему в буфере
case 28: //LexemaReplaceToReceiver Выдать лексему из нагрузка МК получателю, заменив тукущую лексему в буфере
case 29: //LexemaReplaceCopyToReceiver Выдать копию лексемы из нагрузки МК получателю, заменив тукущую лексему в буфере
case 30: //LexemaToReceiver Выдать лексему из нагрузка МК получателю
case 31: //LexemaCopyToReceiver Выдать копию лексемы из нагрузки МК получателю
if(MK==30 || MK==31) ib = (ib + 1) % SizeBuf;
LexBuf[ib].Load.Clear(); // Удаляем нагрузку ИП
LexBuf[ib].copy(Load);
if(MK!=27)LexOut(MK==31);
break;
case 32: //LastLexemaToReceiver Выдать последнюю лексему получателю
case 33: //LastLexemaCopyToReceiver Выдать последнюю лексему получателю
if (Receiver != nullptr)
if (MK==33)
Receiver->ProgFU(ReceiverMK, { TIP, LexBuf[ib].сlone() });
else
Receiver->ProgFU(ReceiverMK, { TIP, &LexBuf[ib] });
// LexOut(MK==33);
break;
case 35: //LastLexemaOutMk Выдать MK c последней лексемой
if (Receiver != nullptr && Load.Type >> 1 == Dint)
Receiver->ProgFU(*(int*)Load.Point, { TIP, &LexBuf[ib] });
break;
case 36: // LastLexemaCopyOutMk Выдать МК с копией последней лексемы
if (Receiver != nullptr && Load.Type >> 1 == Dint)
Receiver->ProgFU(*(int*)Load.Point, { TIP, LexBuf[ib].сlone() });
break;
case 40: //PrevLexemaToReseiver Выдать предыдущую лексему получателю
if (Receiver != nullptr && Load.Type >> 1 == Dint)
Receiver->ProgFU(*(int*)Load.Point, { TIP, &LexBuf[(ib-1+ SizeBuf)% SizeBuf] });
break;
case 41: //PrevLexemaCopyToReseiver Выдать копию предыдущей лексемы получателю
if (Receiver != nullptr && Load.Type >> 1 == Dint)
Receiver->ProgFU(*(int*)Load.Point, { TIP, LexBuf[(ib - 1 + SizeBuf) % SizeBuf].сlone() });
break;
case 45: //PrevLexemaOutMk Выдать МК с предыдущей лексемой
if (Receiver != nullptr && Load.Type >> 1 == Dint)
Receiver->ProgFU(*(int*)Load.Point, { TIP, &LexBuf[(ib - 1 + SizeBuf) % SizeBuf] });
break;
case 46: //PrevLexemaCopyOutMk Выдать МК с копией предыдущей лексемы
if (Receiver != nullptr && Load.Type >> 1 == Dint)
Receiver->ProgFU(*(int*)Load.Point, { TIP, LexBuf[(ib - 1 + SizeBuf)% SizeBuf].сlone() });
break;
case 50: // LastLexemaAtrSet Установить атрибут последней лексемы
if (Load.Type >> 1 == Dint)
LexBuf[ib].atr=*(int*)Load.Point;
break;
case 55: // LastLexemaLoadSet Установить нагрзузку у последней лексемы
LexBuf[ib].Load = Load;
break;
case 57: // LastLexemaLoadCopySet Установить копию нагрзузки у последней лексемы
LexBuf[ib].Load.Copy(&Load);
break;
case 65: // LastLexemaVarSet Установить тип переменной для нагрузки последней лексемы
LexBuf[ib].Load.Type |= 1;
LexBuf[ib].Load.Type --;
break;
case 99: // Stop Остановить лексический анализ
Work = false;
ProgExec((IC_type)StopProg,Bus); // выполнить программу по останову лексического анализа
break;
case 100: // Lexing
{
ProgExec((IC_type)StartProg,Bus);
(*(string*)Load.Point) += " "; // Добавление мнимого конечного элемента
S = 0; // Номер состояния распознающего автомата
Work = true;
string FigureBuf;
for (auto i = (*(string*)Load.Point).begin(); i != (*(string*)Load.Point).end() && Work; i++)
switch (S)
{
case 0: // Стартовое состояние
if (*i == ' ') break;
if (*i == '"')
{
FigureBuf = "";
S = 4;
}
if (Seps.count(*i))
{
string *tstr = new string;
*tstr += *i;
ib = (ib + 1) % SizeBuf;
LexBuf[ib].Load.Clear();
LexBuf[ib] = { SeperatAtr,Tstring , tstr };
LexOut();
break;
}
if (*i >= '0' && *i <= '9')
{
FigureBuf = *i;
S = 1;
ib = (ib + 1) % SizeBuf; // Индекс буфера лексем
break;
}
if (ABC.count(*i))
{<...
Подобные документы
Методы грамматического разбора при разработке учебного транслятора. Проектирование лексического анализатора и магазинного автомата. Программная реализация синтаксического анализатора текстового языка высокого уровня. Разработка модуля интерпретации.
курсовая работа [697,2 K], добавлен 06.01.2013Методика минимизации абстрактного автомата. Порядок построения графа полученного минимизированного автомата. Синтез на элементах ИЛИ-НЕ и Т-тригерах. Составление таблицы переходов. Разработка микропрограммного автомата, реализующего микропрограмму.
курсовая работа [997,7 K], добавлен 28.03.2011Методика разработки и частичная реализация транслятора для языка "С" с использованием языка "С++", производящего разбиение на минимальные неделимые конструкции языка исходной цепочки символов основываясь на лексике языка. Анализ работы программы.
курсовая работа [841,3 K], добавлен 19.03.2012Транслятор как программа или техническое средство, выполняющее трансляцию программы. Рассмотрение основных особенностей постройки лексического анализатора. Знакомство с этапами разработки транслятора с ограниченного подмножества языка высокого уровня.
курсовая работа [580,5 K], добавлен 06.08.2013Минимизация абстрактного автомата Мили, моделирование его работы. Синтез схемы конечного автомата, микропрограммного автомата и счетчика числа микрокоманд. Разработка цифровой линии задержки. Построение граф-схем исходного и оптимизированного автоматов.
курсовая работа [823,8 K], добавлен 19.07.2012Синтез автомата для преобразования двоично-десятичного кода. Кодировка алфавитов и состояний. Построение булевых функций, минимизация. Разметка вход-выходных слов для автомата Мили и автомата Мура. Реализация на элементах малой степени интеграции.
контрольная работа [141,5 K], добавлен 14.10.2012Синтез цифрового автомата с комбинационной частью на логических элементах. Реализация спроектированного автомата в виде иерархического блока со схемой замещения на библиотечных компонентах в режиме SPICE–проектов. Разработка абстрактных символов.
курсовая работа [831,2 K], добавлен 23.09.2013Разработка управляющего автомата, ориентированного на выполнение заданной микрооперации. Разработка алгоритма работы управляющего автомата. Листинг программы. Выбор оптимального варианта кодирования состояний автомата. Синтез функции возбуждения.
курсовая работа [506,9 K], добавлен 26.12.2012Нормализация предметной области "Сайт знакомств" и ее программная реализация с использованием СУБД MySQL, языка HTML, технологии PHP и ADO, скриптовых языков VBScript или JavaScript. Руководство программиста, тестирование, исходный текст приложения.
реферат [29,0 K], добавлен 09.09.2010Содержание и особенности этапов синтеза дискретного автомата. Граф переходов-выходов автомата Мура, кодирование входных и выходных сигналов. Построение функциональной схемы автомата Мура на RS–триггерах и элементах И-НЕ в программе Electronic WorkBench.
курсовая работа [964,2 K], добавлен 20.07.2015Оптимізація схеми мікропрограмного автомата Мура за рахунок нестандартного подання кодів станів. Аналіз методів синтезу автомата та аналіз сучасного елементного базису. Використанні особливостей автомата для зменшення площини матричної схеми автомата.
презентация [357,0 K], добавлен 16.10.2013Проектирование лексического и синтаксического анализаторов учебного языка. Правила преобразования логических выражений в ПОЛИЗ. Формирование триад, оптимизация их списка. Логическая структура программы. Тестирование модулей транслятора-интерпретатора.
курсовая работа [1,3 M], добавлен 28.05.2013Понятие и свойства конечного автомата, его назначение и сферы применения. порядок разработки специальной функции, реализующей конечный автомат. Способы описания данной функции, обоснование выбора одного из них. Программная реализация решения задачи.
курсовая работа [466,4 K], добавлен 20.01.2010Программная реализация настольного приложения с использованием языка программирования C#. Проектирование и структура пользовательского интерфейса, требования к нему и оценка функциональности. Разработка руководства пользователя и его использование.
курсовая работа [297,6 K], добавлен 10.03.2015Специфика построения и минимизации детерминированного автомата методом разбиения. Построение детерминированной сети Петри, моделирующей работу распознающего автомата. Особенности программной реализации праволинейной грамматики, построение ее графа.
курсовая работа [615,1 K], добавлен 19.06.2012Изучение методов построения конечного автомата, распознающего заданный язык, и принципы его программной реализации. Проектирование комбинационной и принципиальной схем распознающего конечного автомата с использованием библиотеки интегральных микросхем.
дипломная работа [1,8 M], добавлен 18.08.2013Понятие, последовательность построения и схемная реализация цифрового автомата. Описание форм представления функций алгебры логики. Принципы минимизации функций выходов и переходов автомата, их перевода в базис. Сведенья о программе Electronics Workbench.
курсовая работа [2,0 M], добавлен 27.10.2010Сведение недетерминированного конечного автомата к детерминированному. Построение минимального детерминированного автомата из праволинейной грамматики двумя различными способами: с помощью сетей Петри и с помощью таблиц. Описание контрольного примера.
курсовая работа [903,9 K], добавлен 14.07.2012Обоснование выбора языка, виды языков программирования. Характеристика программного продукта, постановка задачи, методы решения, программная реализация, программная документация. Руководство по использованию программы. Защита программного продукта.
дипломная работа [1,6 M], добавлен 22.02.2010Разработка управляющего автомата процессора с жесткой логикой в САПР Quartus II. Построение схемы функциональной микропрограммы команды "Исключающее ИЛИ" в размеченном виде. Унитарное кодирование состояний автомата. Запись функций переходов и выходов.
курсовая работа [671,3 K], добавлен 04.11.2014