Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
отчет_1-8.docx
Скачиваний:
3
Добавлен:
16.09.2019
Размер:
219.03 Кб
Скачать

8. Реализовать мп автомат для приведенной кс-грамматики

Класс МП-автомата.

class MPAutomate

{ // MP-Automate (Q,T,G,D,Q0,Z,F)

ArrayList Q = null; // множество состояний

ArrayList T = null; // входной алфавит

ArrayList G = new ArrayList(); // алфавит магазинных символов

ArrayList D = new ArrayList(); // отображения delta

string Q0 = null; // начальное состояние

Stack Z = new Stack(); // магазин

ArrayList F = null; // множество заключительных состояний

// атрибутное программирование на C#

public ArrayList t { get { return T; } set { T = value; } }

public ArrayList q { get { return Q; } set { Q = value; } }

public ArrayList g { get { return G; } set { G = value; } }

public ArrayList d

{

get { return D; }

set { D = value; }

}

public string q0 { get { return Q0; } set { Q0 = value; } }

public Stack z { get { return Z; } set { Z = value; } }

public ArrayList f { get { return F; } set { F = value; } }

public MPAutomate() { }

public MPAutomate(Grammar gramm)

{

Init(gramm); // иницинализация по данной КС-грамматике

}

class Delta

{ // структура Delta отображения

private string LeftQ = null; // исходное состояние

private string LeftT = null; // символ входной цепочки

private string LeftZ = null; // верхний символ магазин

private ArrayList RightQ = null; // множество следующих состояний

private ArrayList RightZ = null; // множество символов магазина

public string leftQ { get { return LeftQ; } set { LeftQ = value; } }

public string leftT { get { return LeftT; } set { LeftT = value; } }

public string leftZ { get { return LeftZ; } set { LeftZ = value; } }

public ArrayList rightQ { get { return RightQ; } set { RightQ = value; } }

public ArrayList rightZ { get { return RightZ; } set { RightZ = value; } }

// Delta ( q1 , a , z ) = { {q} , {z1z2...} }

// LeftQ LeftT LeftZ RightQ RightZ

public Delta(string LeftQ, string LeftT, string LeftZ, ArrayList RightQ, ArrayList RightZ)

{

this.LeftQ = LeftQ;

this.LeftT = LeftT;

this.LeftZ = LeftZ;

this.RightQ = RightQ;

this.RightZ = RightZ;

}

} // end class Delta

public void Init(Grammar gramm)

{ // задание отображения D

Q = new ArrayList() { "q" }; // состояние

T = gramm.t; // входной алфавит

foreach (string v1 in gramm.v) // магазинные символы

G.Add(v1);

foreach (string t1 in gramm.t)

G.Add(t1);

Q0 = Q[0].ToString(); // начальное состояние

Z.Push(gramm.s); // начальный символ в магазине

F = new ArrayList(); // пустое множество заключительных состояний

Delta delta = null;

foreach (string v1 in gramm.v)

{ // сопоставление правил с отображениями

ArrayList q1 = new ArrayList();

ArrayList z1 = new ArrayList();

foreach (Rule rule in gramm.p)

{

if (rule.left == v1)

{

Stack zb = new Stack();

ArrayList rr = new ArrayList(rule.right);

rr.Reverse();

foreach (string s in rr)

zb.Push(s);

z1.Add(zb);

q1.Add(Q0);

}

}

delta = new Delta(Q0, "e", v1, q1, z1);

D.Add(delta);

}

foreach (string t1 in gramm.t)

{

Stack e = new Stack();

e.Push("e");

delta = new Delta(Q0, t1, t1, new ArrayList() { Q0 }, new ArrayList() { e });

D.Add(delta);

}

} // end

string printstack(Stack s) // печать текущего состояния магазина

{

string p = "|";

Stack s1 = new Stack();

while (s.Count != 0)

{

s1.Push(s.Pop());

p = p + s1.Peek().ToString();

}

while (s1.Count != 0) s.Push(s1.Pop());

return p;

}

int c = 1; // нумерация шагов в log

public bool check(string s, int i, int j, Stack z0) // проверка на допустимость

{ // рекурсивный метод (i-текущий символ в строке, j-текущее состояние, z0-текущие символы в магазине)

if (z0.Count != 0 && z0.Peek().ToString() == "S") c = 1;

if (i == s.Length) // если конец строки

{

if (z0.Count == 0) // если магазин пуст

{

if (F.Count == 0) return true; // множество заключительных состояний пусто

else if (F.Contains(Q[j])) return true; // или автомат дошел до заключительного состояния

else return false;

}

else return false;

}

bool k = false; // успех/неуспех работы

string a = s[i].ToString();

string cq = Q[j].ToString();

foreach (Delta delta in D)

{

if (delta.leftQ == cq && (delta.leftT == a || delta.leftT == "e") && delta.leftZ == z0.Peek().ToString()) // подходящее правило для текущей конфигурации

{

Stack zz1 = new Stack(); // здесь и далее - создание дополнительных стеков для магазина (предотвращение потери данных)

Stack zz2 = new Stack();

Console.Write(c.ToString() + ")"); // оформление отчета

c++;

Console.Write("Входная цепочка: ");

for (int l = i; l < s.Length; l++) Console.Write(s[l].ToString());

Console.Write("\n");

Console.Write("Магазин: ");

while (z0.Count != 0) { Console.Write(z0.Peek().ToString()); zz2.Push(z0.Pop()); }

Console.Write("\n");

string zz;

while (zz2.Count != 0)

{

zz = zz2.Pop().ToString();

if (zz != "e")

{

zz1.Push(zz);

z0.Push(zz);

}

}

if (zz1.Count != 0) zz1.Pop();

foreach (string q1 in delta.rightQ)

{

j = Q.IndexOf(q1); // переход в новое состояние

foreach (Stack z2 in delta.rightZ)

{

if (delta.rightQ[delta.rightZ.IndexOf(z2)].ToString() == q1) // замена верхнего символа на цепочку

{

// стек со снятой вершиной zz1 запоминаем в zz10

Stack zz10 = new Stack();

Stack zz20 = new Stack();

while (zz1.Count != 0) zz20.Push(zz1.Pop());

string zzz;

while (zz20.Count != 0)

{

zzz = zz20.Pop().ToString();

if (zzz != "e")

{

zz10.Push(zzz);

zz1.Push(zzz);

}

}

// замена в стеке zz10

Stack z1 = new Stack();

while (z2.Count != 0)

{

z1.Push(z2.Pop());

}

string z3;

while (z1.Count != 0)

{

z3 = z1.Pop().ToString();

if (z3 != "e")

{

zz10.Push(z3);

z2.Push(z3);

}

}

// формирование стека z02 для нового такта

Stack z01 = new Stack();

Stack z02 = new Stack();

while (zz10.Count != 0) z01.Push(zz10.Pop());

string z00;

while (z01.Count != 0)

{

z00 = z01.Pop().ToString();

if (z00 != "e")

{

z02.Push(z00);

zz10.Push(z00);

}

}

if (delta.leftT == "e") i--;

if (check(s, i + 1, j, z02)) { k = true; return true; } // рекурсивный вызов

if (delta.leftT == "e") i++;

}

}

}

}

if (k) break;

}

if (k) return true;

else return false;

}

public void Debug()

{

Console.WriteLine("\n Сформирован МП-автомат");

Console.Write("Множество состояний: ");

foreach (string q in Q) Console.Write(q);

Console.Write("\n");

Console.Write("Алфавит входных символов: ");

foreach (string t in T) Console.Write(t);

Console.Write("\n");

Console.Write("Алфавит магазинных символов: ");

foreach (string g in G) Console.Write(g);

Console.Write("\n");

Console.Write("Начальное состояние: ");

Console.Write(Q0 + "\n");

Console.Write("Начальный символ в магазине: ");

Console.Write(Z.Peek().ToString() + "\n");

Console.Write("Множество заключительных состояний: ");

foreach (string f in F) Console.Write(f);

if (F.Count == 0) Console.Write("(пустое множество)");

Console.Write("\n");

Console.Write("Отображение:\n");

foreach (Delta delta in D)

{

Console.Write("( " + delta.leftQ + " , " + delta.leftT + " , " + delta.leftZ + " )= (" + delta.rightQ[0].ToString() + " , ");

foreach (Stack s in delta.rightZ)

Console.Write(printstack(s));

Console.Write(" ) \n");

}

}

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]