роектирование модуля интерпретации

 

На начальном этапе реализации константы (CONSTANTS) и переменные (IDENTIFIES) кладутся в формируемую запись в порядке их появления в исходном массиве.

 

s1.Push(CONSTANTS[CounterConstants++]);

s1.Push(IDENTIFIES[CounterIdentifies++]);

 

При появлении операции в исходном массиве:

a. если в стеке нет операций или верхним элементом стека является открывающая скобка, операции кладётся в стек

if (operations.Peek() == "16" || operations.Peek() == "00")

{

operations.Push(TokensStack.Pop());

break;

}

 

if (TokensStack.Peek() == "16") // (

{

operations.Push(TokensStack.Pop());

break;

}

b. если новая операция имеет больший приоритет, чем верхняя операции в стеке, то новая операции кладётся в стек

if (Convert.ToInt32(TokensStack.Peek()) > Convert.ToInt32(operations.Peek()))

{

operations.Push(TokensStack.Pop());

}

c. если новая операция имеет меньший или равный приоритет, чем верхняя операции в стеке, то операции, находящиеся в стеке, до ближайшей открывающей скобки или до операции с приоритетом меньшим, чем у новой операции, перекладываются в формируемую запись, а новая операции кладётся в стек

while (Convert.ToInt32(TokensStack.Peek()) > Convert.ToInt32(operations.Peek()) || operations.Peek() != "16")

{

if (operations.Peek() == "00")

break;

s1.Push(BinOp(operations.Pop()));

}

Открывающая скобка кладётся в стек.

if (operations.Peek() == "16" || operations.Peek() == "00")

{

operations.Push(TokensStack.Pop());

break;

}

Закрывающая скобка выталкивает из стека в формируемую запись все операции до ближайшей открывающей скобки, открывающая скобка удаляется из стека

if (TokensStack.Peek() == "17") // ) => +/- to stack

{

while (operations.Peek() != "16")

{

s1.Push(BinOp(operations.Pop()));

}

TokensStack.Pop();

operations.Pop();

break;

}

После того, как мы добрались до конца исходного выражения, операции, оставшиеся в стеке, перекладываются в формируемое выражение.

while (operations.Peek() != "00")

s1.Push(BinOp(operations.Pop()));

 

Краткая спецификация модуля интерпретации:

 

МодульShell

Название процедуры: Equal

Назначение процедуры: Реализует постфиксную запись.

 

Название процедуры: BinOp

Назначение процедуры: переводит число в знак

 

Название процедуры: FindOperations

Назначение процедуры: проход по коду в поисках функций

 

4. РЕАЛИЗАЦИЯ

одирование

Программа была написана на языке программирования C# в среде Microsoft Visual Studio 2012. Исходный текст программы представлен в приложении А.

 

естирование

Проверка разработанной программы заключалась в её активном использовании с целью выявления ошибок и некорректной работы. В результате этого ошибок обнаружено не было, что позволяет сделать вывод о работоспособности программы.

 

Этапы тестирования представлены в таблице 3. Скриншоты результатов тестирования представлены в приложении Б.

 

Таблица2 – план тестирования

№ теста Цель теста Ожидаемый результат Полученный результат
Проверка вывода ошибок при вводе не корректного кода. Вывод сообщения об ошибки Полученный результат совпадает с ожидаемым (рис. 3,4,5).
Вычисление необъявленной переменной Вывод сообщения об ошибки Полученный результат совпадает с ожидаемым (рис. 6).
Ввод корректного кода программы Программа выводит результат работы программы Полученный результат совпадает с ожидаемым (рис. 7).

 

Заключение

 

В данной курсовой работе была поставлена задача разработки компилятора к заданной грамматике.

В ходе решения задачи был разработан интерфейс программы, алгоритмического анализатора. Программа производит анализ исходного текста и выдает сообщения об ошибках, если они есть. Было произведено кодирование на языке программирования C# в среде объектно-ориентированного программирования Visual Studio 2012 и тестирование, в ходе которого было выявлено, что программа решает задачу корректно и устойчиво работает на тестовом наборе данных.

 

 

Список используемых источников

 

1. Д. Креншоу «Пишем компилятор»

2. Р. Хантер «Проектирование и конструирование компиляторов»

3. Компаниец Р.И., Маньков Е.В., Филатов Н.Е. «Системное программирование. Основы построения трансляторов»

4. Костельцев А.В. «Построение интерпретаторов и компиляторов»

5. Касьянов В.Н., Поттосин И.В. «Методы построения трансляторов»

6. Д. Грис «Конструирование компиляторов для цифровых вычислительных машин»

7. Ахо А., Ульман Дж. «Теория синтаксического анализа, перевода и компиляции»

8. Льюис Ф., Розенкранц Д., Смирну Д. «Теоретические основы проектирования компиляторов»

 

 

ПРИЛОЖЕНИЕ А

 

 

Исходный код Form1.cs

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.Threading;

using System.IO;

 

namespace KYRS_TLP

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

 

private void Form1_Load(object sender, EventArgs e)

{

AsmRichTextBox.ReadOnly = true;

menuStrip1.Renderer = new CustomProfessionalRenderer();

 

label1.Text = "";

for (int i = 0; i < 1; label1.Text += "", i++) ;

label1.Text += "DEFAULT.FLP";

for (int i = 0; i < 40; label1.Text += "", i++) ;

label1.Text += "\r";

for (int i = 0; i < 26; i++)

{

label1.Text += "";

for (int j = 0; j < 52; label1.Text += " ", j++) ;

label1.Text += "\r";

}

label1.Text += "";

for (int i = 0; i < 52; label1.Text += "", i++) ;

label1.Text += "";

 

label2.Text = "";

for (int i = 0; i < 1; label2.Text += "", i++) ;

label2.Text += "OUTPUT";

for (int i = 0; i < 17; label2.Text += "", i++) ;

label2.Text += "\r";

for (int i = 0; i < 26; i++)

{

label2.Text += "";

for (int j = 0; j < 24; label2.Text += " ", j++) ;

label2.Text += "\r";

}

label2.Text += "";

for (int i = 0; i < 24; label2.Text += "", i++) ;

label2.Text += "";

 

label3.Visible = false;

}

 

int len = 0;

static bool IsEnter = false;

static string ReadString = "";

 

delegate void AddText(string msg);

 

delegate void IsVisible(bool msg);

 

struct snd

{

public List<Stack<string>> IN;

public RichTextBox rtb;

public snd(List<Stack<string>> a, RichTextBox b)

{

IN = a;

rtb = b;

}

};

 

struct ConstIdent

{

public string Ident;

public string Const;

public ConstIdent(string a, string b)

{

Ident = a;

Const = b;

}

 

};

 

struct CaseStruct

{

public int one;

public string two;

public string three;

public CaseStruct(int a, string b, string c)

{

one = a;

two = b;

three = c;

}

};

 

//компилим

private void debugToolStripMenuItem_Click(object sender, EventArgs e)

{

Lexer lex = new Lexer(CodeRichTextBox.Text);

Parser pars = new Parser(lex.TOKENS);

if (pars.DebugMsg == "debug successful")

{

AsmRichTextBox.Focus();

Shell shell = new Shell(pars.TokensShell, lex.IDENTIFIES, lex.CONSTANTS);

snd[] snd1 = { new snd(shell.OUT, AsmRichTextBox) };

 

Thread RunThread = new Thread(Run);

RunThread.Start(snd1);

}

label3.Visible = true;

label3.Text = pars.DebugMsg;

Thread time = new Thread(timer);

time.Start(label3);

}

 

static void Run( object INI)

{

snd[] snd1 = (snd[])INI;

List<ConstIdent> CI = new List<ConstIdent>();

 

for (int i = 0; i < snd1[0].IN.Count(); i++)

{

while (snd1[0].IN[i].Count() != 0)

{

switch (snd1[0].IN[i].Peek())

{

case "05":

{

if (snd1[0].rtb.InvokeRequired)

snd1[0].rtb.Invoke(new IsVisible((s) => snd1[0].rtb.ReadOnly = s), false);

snd1[0].IN[i].Pop();

while(snd1[0].IN[i].Count !=0)

{

int rr=0;

string b = "";

string a = snd1[0].IN[i].Pop();

while (rr == 0)

{

while (IsEnter == false) { Thread.Sleep(100); }

b = ReadString;

 

try { int k = Convert.ToInt32(b); IsEnter = false; rr++; }

catch

{

if (snd1[0].rtb.InvokeRequired)

snd1[0].rtb.Invoke(new AddText((s) => snd1[0].rtb.AppendText(s)), "Incorrect type\n");

IsEnter = false;

}

}

CI.Add(new ConstIdent(a, b));

}

IsEnter = false;

if (snd1[0].rtb.InvokeRequired)

snd1[0].rtb.Invoke(new IsVisible((s) => snd1[0].rtb.ReadOnly = s), true);

break;

}

 

case "06":

{

snd1[0].IN[i].Pop();

while (snd1[0].IN[i].Count != 0)

{

for (int j = CI.Count-1; j >= 0 ; j-- )

{

if(snd1[0].IN[i].Peek() == CI[j].Ident)

{

try

{

Convert.ToInt32(CI[j].Const);

if (snd1[0].rtb.InvokeRequired)

snd1[0].rtb.Invoke(new AddText((s) => snd1[0].rtb.AppendText(s)), Convert.ToString(CI[j].Const + "\n"));

}

catch

{

if (snd1[0].rtb.InvokeRequired)

snd1[0].rtb.Invoke(new AddText((s) => snd1[0].rtb.AppendText(s)), "");

}

 

snd1[0].IN[i].Pop();

break;

}

}

}

break;

}

 

case "07":

{

Stack<string> s1 = new Stack<string>();

List<CaseStruct> CS = new List<CaseStruct>();

string three;

int case1 = 0;

snd1[0].IN[i].Pop();

snd1[0].IN[i].Pop();

 

string case2 = snd1[0].IN[i].Pop();

 

if(snd1[0].IN[i].Peek() == "$")

{

try

{

case1 = Convert.ToInt32(case2);

}

catch

{

try { case1 = Convert.ToInt32(TryFind(case2, CI)); }

catch

{

if (snd1[0].rtb.InvokeRequired)

snd1[0].rtb.Invoke(new AddText((s) => snd1[0].rtb.AppendText(s)), TryFind(case2, CI) + "\n");

}

}

}

else

{

snd1[0].IN[i].Push(case2);

try

{

case1 = Convert.ToInt32(Operation(snd1[0].IN[i], CI));

}

catch

{

if (snd1[0].rtb.InvokeRequired)

snd1[0].rtb.Invoke(new AddText((s) => snd1[0].rtb.AppendText(s)), Operation(snd1[0].IN[i], CI) + "\n");

}

}

 

snd1[0].IN[i].Pop();

while(snd1[0].IN[i].Count != 0)

{

int one = Convert.ToInt32(snd1[0].IN[i].Pop());

string two = snd1[0].IN[i].Pop();

 

snd1[0].IN[i].Pop();

three = Operation(snd1[0].IN[i], CI);

 

CS.Add(new CaseStruct(one, two, three));

snd1[0].IN[i].Pop();

}

 

for (int j = 0; j < CS.Count; j++ )

{

if (case1 == CS[j].one)

{

CI.Add(new ConstIdent(CS[j].two, CS[j].three));

break;

}

}

break;

}

 

default:

{

if (snd1[0].IN[i].Count() == 4)

{

string a = snd1[0].IN[i].Pop();

snd1[0].IN[i].Pop();

string err = TryFind(snd1[0].IN[i].Pop(), CI);

CI.Add(new ConstIdent(a, err));

snd1[0].IN[i].Pop();

break;

}

else

{

string a = snd1[0].IN[i].Pop();

snd1[0].IN[i].Pop();

string ww = Operation(snd1[0].IN[i], CI);

if (ww == "variable is not set" || ww == "zero division")

if (snd1[0].rtb.InvokeRequired)

snd1[0].rtb.Invoke(new AddText((s) => snd1[0].rtb.AppendText(s)), ww + "\n");

 

CI.Add(new ConstIdent(a, ww));

snd1[0].IN[i].Pop();

}

break;

}

 

}

}

}

}

 

static string TryFind( string a, List<ConstIdent> ci)

{

int ret;

int kol=0;

while (true)

{

try { ret = Convert.ToInt32(a); return a; }

catch

{

kol = 0;

for (int j = ci.Count-1; j >= 0; j--)

{

if (ci[j].Ident == a)

{

a = ci[j].Const;

kol++;

break;

}

}

if (kol == 0)

return "variable is not set";

}

}

}

 

static string Operation(Stack<string> a, List<ConstIdent> CI)

{

Stack<string> s1 = new Stack<string>();

 

while (a.Peek() != "$")

{

switch (a.Peek())

{

case "+":

{

a.Pop();

int b1, c1;

try

{

b1 = Convert.ToInt32(TryFind(s1.Pop(), CI));

c1 = Convert.ToInt32(TryFind(s1.Pop(), CI));

}

catch

{

return "variable is not set";

}

if (a.Peek() != "$")

s1.Push(Convert.ToString(b1 + c1));

else

return Convert.ToString(b1 + c1);

break;

}

case "-":

{

a.Pop();

int b1, c1;

try

{

b1 = Convert.ToInt32(TryFind(s1.Pop(), CI));

c1 = Convert.ToInt32(TryFind(s1.Pop(), CI));

}

catch

{

return "variable is not set";

}

if (a.Peek() != "$")

s1.Push(Convert.ToString(c1 - b1));

else

return Convert.ToString(c1 - b1);

break;

}

case "/":

{

a.Pop();

int b1, c1;

try

{

b1 = Convert.ToInt32(TryFind(s1.Pop(), CI));

c1 = Convert.ToInt32(TryFind(s1.Pop(), CI));

if (b1 == 0)

return "zero division";

}

catch

{

return "variable is not set";

}

if (a.Peek() != "$")

s1.Push(Convert.ToString(c1 / b1));

else

return Convert.ToString(c1 / b1);

break;

}

default:

{

s1.Push(a.Pop());

if(a.Peek()=="$" && s1.Count == 1)

{

return s1.Pop();

}

break;

}

}

}

return "error";

}

 

static void timer(object l3)

{

Label lbl = (Label)l3;

Thread.Sleep(10000);

if (lbl.InvokeRequired)

lbl.Invoke(new IsVisible((s) => lbl.Visible = s), false);

}

 

//новый проект

private void newProjectToolStripMenuItem_Click(object sender, EventArgs e)

{

CodeRichTextBox.Text = "";

}

 

//открыть

private void openToolStripMenuItem_Click(object sender, EventArgs e)

{

using(OpenFileDialog OpnFDlg = new OpenFileDialog())

{

try

{

OpnFDlg.Filter = "TLP files(*.TLP)|*.TLP|All files(*.*)|*.*";

OpnFDlg.FilterIndex = 1;

OpnFDlg.InitialDirectory = "D:";

if(OpnFDlg.ShowDialog() == DialogResult.OK)

{

StreamReader sr = new StreamReader(OpnFDlg.FileName, Encoding.Default);

string str = sr.ReadToEnd();

sr.Close();

CodeRichTextBox.Text = str;

 

}

}

catch(Exception msg)

{

MessageBox.Show(msg.Message);

}

}

}

 

//сохранить

private void saveToolStripMenuItem_Click(object sender, EventArgs e)

{

SaveFileDialog SvFlDlg = new SaveFileDialog();

SvFlDlg.DefaultExt = "*.TLP";

SvFlDlg.Filter = "TLP files(*.TLp)|*.TLP";

if(SvFlDlg.ShowDialog() == DialogResult.OK && SvFlDlg.FileName.Length > 0)

{

CodeRichTextBox.SaveFile(SvFlDlg.FileName, RichTextBoxStreamType.PlainText);

}

}

 

//выход

private void exitToolStripMenuItem_Click(object sender, EventArgs e)

{

Close();

}

 

//о программе

private void helpToolStripMenuItem_Click(object sender, EventArgs e)

{

About about = new About();

about.Show();

}

 

//обработка сочетаний клавиш

private void CodeRichTextBox_KeyDown(object sender, KeyEventArgs e)

{

if (e.KeyValue == (int)Keys.Control || e.KeyValue == (int)Keys.E || e.KeyValue == (int)Keys.J || e.KeyValue == (int)Keys.R)

{

e.Handled = true;

}

}

 

 

//обработка сочетаний клавиш

private void AsmRichTextBox_KeyDown(object sender, KeyEventArgs e)

{

if (e.KeyValue == (int)Keys.Control || e.KeyValue == (int)Keys.E || e.KeyValue == (int)Keys.J || e.KeyValue == (int)Keys.R || e.KeyValue == (int)Keys.Z)

{

e.Handled = true;

}

 

if (e.KeyValue == (int)Keys.Control || e.KeyValue == (int)Keys.A)

{

e.Handled = true;

int k = AsmRichTextBox.Text.Length - AsmRichTextBox.GetFirstCharIndexOfCurrentLine();

AsmRichTextBox.Select(AsmRichTextBox.GetFirstCharIndexOfCurrentLine(), k);

AsmRichTextBox.Refresh();

}

 

if (e.KeyValue == (int)Keys.Control || e.KeyValue == (int)Keys.Home)

{

e.Handled = true;

}

 

if(e.KeyValue == (int)Keys.Up || e.KeyValue == (int)Keys.Down)

{

e.Handled = true;

}

 

if(e.KeyValue == (int)Keys.Left)

{

if (AsmRichTextBox.SelectionStart <= len)

{

e.Handled = true;

}

}

if(e.KeyValue == (int)Keys.PageDown || e.KeyValue == (int)Keys.PageUp)

{

e.Handled = true;

}

 

if (e.KeyValue == (int)Keys.Back)

{

if(AsmRichTextBox.SelectionStart <= len)

{

e.Handled = true;

}

}

 

if (e.KeyValue == (int)Keys.Enter)

{

if (AsmRichTextBox.ReadOnly == false)

{

ReadString = AsmRichTextBox.Lines[AsmRichTextBox.GetLineFromCharIndex(AsmRichTextBox.GetFirstCharIndexFromLine(AsmRichTextBox.SelectionStart-1))];

IsEnter = true;

}

len = AsmRichTextBox.SelectionStart = AsmRichTextBox.Text.Length+1;

}

}

}

}

 

class CustomProfessionalRenderer : ToolStripProfessionalRenderer

{

protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)

{

Rectangle r = Rectangle.Inflate(e.Item.ContentRectangle, 1, 1);

if (e.Item.Selected)

{

using (Brush b = new SolidBrush(Color.DarkGray))

{

e.Graphics.FillRectangle(b, r);

}

}

else

{

using (Pen p = new Pen(Color.Black))

{

e.Graphics.DrawRectangle(p, r);

Brush b = new SolidBrush(Color.Black);

e.Graphics.FillRectangle(b, r);

}

}

}

}

 

Исходный код Lexer.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Text.RegularExpressions;

 

namespace KYRS_TLP

{

class Lexer

{

const int IdentLength = 11;

string Code;

int FindInt = 0;

public string Error="";

public int kolError = 0;

 

struct KeyWords

{

public string Words;

public string WordKey;

 

public KeyWords(string a, string b)

{

Words = a;

WordKey = b;

}

}

 

KeyWords[] KEYS = { new KeyWords("VAR", "01"), new KeyWords("INTEGER", "02"),new KeyWords("BEGIN", "03"),

new KeyWords("END", "04"), new KeyWords("READ", "05"),new KeyWords("WRITE", "06"),

new KeyWords("CASE", "07"), new KeyWords("OF", "08"),new KeyWords("END_CASE", "09") };

 

KeyWords[] CHARS = { new KeyWords(":", "10"), new KeyWords(";", "11"), new KeyWords("=", "12"),

new KeyWords("+", "13"), new KeyWords("-", "14"), new KeyWords("/", "15"),

new KeyWords("(", "16"), new KeyWords(")", "17"), new KeyWords(",", "18") };

 

/*

Недопустимый символ 91

Слишком длинное имя переменной 92

Повторное объявление переменной 93

Необъявленная переменная 94

Неверное имя переменной 95

*/

 

//регулярное выражение

string rgz = @"(?<char>[^:;\(\)\=\+\-\/\s\,]*)(?<separator>[:;\(\)\=\+\-\/\s\,]{1})?";

 

//список полученных токенов, идентификаторов, констант

public Stack<string> TOKENS = new Stack<string>();

public List<string> IDENTIFIES = new List<string>();

public List<string> CONSTANTS = new List<string>();

 

public Lexer()

{

this.Error = "Lexer error.\n";

}

 

public Lexer(string Code)

{

this.Code = Code;

string pattern = "( )+";

string replacement = " ";

if (this.Code.Length == 0)

{

this.Error += "Error: No entry.\n";

}

else

{

//удаление лишних пробелов, перевод в вверхний регистр

Regex rgx = new Regex(pattern);

this.Code = rgx.Replace(this.Code, replacement);

this.Code = this.Code.ToUpper();

}

LexerOut();

}

 

private void LexerOut()

{

Match match = Regex.Match(this.Code, this.rgz);

while (match.Success)

{

if (match.Groups["char"].Length > 0)

if (!IsKeyword(match.Groups["char"].ToString(), KEYS))

if (!IsIdenOrConst(match.Groups["char"].ToString(), "[^0-9]+", "21", CONSTANTS, int.MaxValue.ToString().Length))

{

IDENTIFIES.Add(match.Groups["char"].ToString());

AddError(match.Groups["char"].ToString());

}

if ((match.Groups["separator"].ToString() != " ") && (match.Groups["separator"].ToString() != "\n"))

IsKeyword(match.Groups["separator"].ToString(), CHARS);

match = match.NextMatch();

}

}

 

private bool IsKeyword(string word, KeyWords[] kwd)

{

bool TOF = false;

for(int i=0; i< kwd.Count(); i++)

{

if (kwd[i].Words == word)

{

TOKENS.Push(kwd[i].WordKey);

TOF = true;

if (word == "BEGIN")

FindInt = IDENTIFIES.Count;

break;

}

}

return TOF;

}

 

private bool IsIdenOrConst(string word, string regular, string ID, List<string> lst, int len)

{

bool TOF = true;

if (Regex.Match(word, regular).Success)

TOF = false;

else

{

TOKENS.Push(ID);

lst.Add(word);

}

return TOF;

}

 

private void AddError(string word)

{

int kol = 0;

for (int i = 0; i < 5; i++)

{

switch (i)

{

case 0: { if (Regex.Match(word, @"[^A-Z0-9:;\(\)\=\+\-\/\s\,]").Success) { kol++; TOKENS.Push("91"); } break; }

case 1: { if (word.Length > IdentLength) { kol++; TOKENS.Push("92"); } break; }

case 2: { int k2 = 0; if (FindInt == 0) for (int j = 0; j < IDENTIFIES.Count; j++) if (word == IDENTIFIES[j]) k2++; if (k2 > 1) { kol++; TOKENS.Push("93"); } break; }

case 3: { int k2 = 1; if (FindInt != 0) { k2 = 0; for (int j = 0; j < FindInt; j++) if (word == IDENTIFIES[j]) k2++; } if (k2 == 0) { kol++; TOKENS.Push("94"); } break; }

case 4: { if (Regex.Match(word, "[^A-Z]").Success) { kol++; TOKENS.Push("95"); } break; }

}

}

if (kol == 0)

TOKENS.Push("20");

}

}

}

 

 

Исходный код Parser.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace KYRS_TLP

{

class Parser

{

private Stack<string> Tokens = new Stack<string>();

private Stack<string> TokensStack = new Stack<string>();

private Stack<string> StatesStack = new Stack<string>();

public string DebugMsg = "";

public Stack<string> TokensShell = new Stack<string>();

 

public Parser(Stack<string> Tokens)

{

this.Tokens = Tokens;

Parsing();

}

 

//создаем список состояний

string[,] States = { { "04", "53", "03", "11", "02", "10", "51", "00" },

{ "54", "11", "17", "51", "16", "00", "00", "00" },

{ "54", "11", "09", "56", "08", "58", "00", "00" },

{ "54", "11", "58", "12", "00", "00", "00", "00" },

{ "11", "58", "12", "00", "00", "00", "00", "00" },

{ "57", "55", "10", "00", "00", "00", "00", "00" },

{ "60", "17", "58", "00", "00", "00", "00", "00" } };

 

//записываем лексемы в стек

private void ToStack()

{

TokensStack.Push("$");

TokensShell.Push("$");

while (Tokens.Count != 0)

{

TokensStack.Push(Tokens.Peek());

TokensShell.Push(Tokens.Pop());

}

}

 

//парсер

private int Parsing()

{

ToStack();

StatesStack.Push("$");

StatesStack.Push("50");

while((StatesStack.Count != 0) || (TokensStack.Count != 0))

{

switch(StatesStack.Pop())

{

case "50":

{

switch(TokensStack.Pop())

{

case "01": { int i = 0; while (States[0, i] != "00") StatesStack.Push(States[0, i++]); break; }

default: { DebugMsg = "error: expected \"VAR\""; return 0; }

}

break;

}

 

case "51":

{

switch(TokensStack.Pop())

{

case "20": { StatesStack.Push("52"); break; }

case "91": { DebugMsg = "error: invalid code"; return 0; }

case "92": { DebugMsg = "error: long variable name"; return 0; }

case "93": { DebugMsg = "error: re variable declaration"; return 0; }

case "94": { DebugMsg = "error: undeclared variable"; return 0; }

case "95": { DebugMsg = "error: incorrect variable name"; return 0; }

default: { DebugMsg = "error: expected variable"; return 0; }

}

break;

}

 

case "52":

{

switch(TokensStack.Pop())

{

case "18": { StatesStack.Push("51"); break; }

case "10": { StatesStack.Pop(); break; }

case "17": { StatesStack.Pop(); break; }

default: { DebugMsg = "error: Syntax error"; return 0; }

}

break;

}

 

case "53":

{

switch(TokensStack.Pop())

{

case "05": { int i = 0; while (States[1, i] != "00") StatesStack.Push(States[1, i++]); break; }

case "06": { int i = 0; while (States[1, i] != "00") StatesStack.Push(States[1, i++]); break; }

case "07": { int i = 0; while (States[2, i] != "00") StatesStack.Push(States[2, i++]); break; }

case "20": { int i = 0; while (States[3, i] != "00") StatesStack.Push(States[3, i++]); break; }

case "91": { DebugMsg = "error: invalid code"; return 0; }

case "92": { DebugMsg = "error: long variable name"; return 0; }

case "93": { DebugMsg = "error: re variable declaration"; return 0; }

case "94": { DebugMsg = "error: undeclared variable"; return 0; }

case "95": { DebugMsg = "error: incorrect variable name"; return 0; }

default: { DebugMsg = "error: Syntax error"; return 0; }

}

break;

}

 

case "54":

{

switch(TokensStack.Peek())

{

case "05": { StatesStack.Push("53"); break; }

case "06": { StatesStack.Push("53"); break; }

case "07": { StatesStack.Push("53"); break; }

case "20": { StatesStack.Push("53"); break; }

case "04": { StatesStack.Pop(); TokensStack.Pop(); break; }

case "91": { DebugMsg = "error: invalid code"; return 0; }

case "92": { DebugMsg = "error: long variable name"; return 0; }

case "93": { DebugMsg = "error: re variable declaration"; return 0; }

case "94": { DebugMsg = "error: undeclared variable"; return 0; }

case "95": { DebugMsg = "error: incorrect variable name"; return 0; }

default: { DebugMsg = "error: Syntax error"; return 0; }

}

break;

}

 

case "55":

{

switch(TokensStack.Pop())

{

case "20": { int i = 0; while (States[4, i] != "00") StatesStack.Push(States[4, i++]); break; }

case "91": { DebugMsg = "error: invalid code"; return 0; }

case "92": { DebugMsg = "error: long variable name"; return 0; }

case "93": { DebugMsg = "error: re variable declaration"; return 0; }

case "94": { DebugMsg = "error: undeclared variable"; return 0; }

case "95": { DebugMsg = "error: incorrect variable name"; return 0; }

default: { DebugMsg = "error: Syntax error"; return 0; }

}

break;

}

 

case "56":

{

switch(TokensStack.Pop())

{

case "21": { int i = 0; while (States[5, i] != "00") StatesStack.Push(States[5, i++]); break; }

default: { DebugMsg = "error: Syntax error"; return 0; }

}

break;

}

 

case "57":

{

switch(TokensStack.Peek())

{

case "21": { StatesStack.Push("56"); break; }

case "09": { TokensStack.Pop(); break; }

default: { DebugMsg = "error: Syntax error"; return 0; }

}

break;

}

 

case "58":

{

switch(TokensStack.Peek())

{

case "14": { TokensStack.Pop(); StatesStack.Push("59"); break; }

case "16": { StatesStack.Push("59"); break; }

case "20": { StatesStack.Push("59"); break; }

case "21": { StatesStack.Push("59"); break; }

case "91": { DebugMsg = "error: invalid code"; return 0; }

case "92": { DebugMsg = "error: long variable name"; return 0; }

case "93": { DebugMsg = "error: re variable declaration"; return 0; }

case "94": { DebugMsg = "error: undeclared variable"; return 0; }

case "95": { DebugMsg = "error: incorrect variable name"; return 0; }

default: { DebugMsg = "error: incorrect expression"; return 0; }

}

break;

}

 

case "59":

{

switch(TokensStack.Pop())

{

case "16": { int i = 0; while (States[6, i] != "00") StatesStack.Push(States[6, i++]); break; }

case "20": { StatesStack.Push("60"); break; }

case "21": { StatesStack.Push("60"); break; }

case "91": { DebugMsg = "error: invalid code"; return 0; }

case "92": { DebugMsg = "error: long variable name"; return 0; }

case "93": { DebugMsg = "error: re variable declaration"; return 0; }

case "94": { DebugMsg = "error: undeclared variable"; return 0; }

case "95": { DebugMsg = "error: incorrect variable name"; return 0; }

default: { DebugMsg = "error: Syntax error"; return 0; }

}

break;

}

 

case "60":

{

switch(TokensStack.Pop())

{

case "13": { StatesStack.Push("59"); break; }

case "14": { StatesStack.Push("59"); break; }

case "15": { StatesStack.Push("59"); break; }

case "08": { StatesStack.Pop(); break; }

case "11": { StatesStack.Pop(); break; }

case "17": { StatesStack.Pop(); break; }

default: { DebugMsg = "error: Syntax error"; return 0; }

}

break;

}

 

case "02":

{

switch(TokensStack.Pop())

{

case "02": { break; }

default: { DebugMsg = "error: expected \"integer\""; return 0; }

}

break;

}

 

case "03":

{

switch(TokensStack.Pop())

{

case "03": { break; }

default: { DebugMsg = "error: expected \"begin\""; return 0; }

}

break;

}

 

case "11":

{

switch(TokensStack.Pop())

{

case "11": { break; }

default: { DebugMsg = "error: expected \";\""; return 0; }

}

break;

}

 

case "12":

{

switch (TokensStack.Pop())

{

case "12": { break; }

default: { DebugMsg = "error: expected \"=\""; return 0; }

}

break;

}

 

case "10":

{

switch (TokensStack.Pop())

{

case "10": { break; }

default: { DebugMsg = "error: expected \":\""; return 0; }

}

break;

}

 

case "16":

{

switch (TokensStack.Pop())

{

case "16": { break; }

default: { DebugMsg = "error: expected \"(\""; return 0; }

}

break;

}

 

case "17":

{

switch (TokensStack.Pop())

{

case "17": { break; }

default: { DebugMsg = "error: expected \")\""; return 0; }

}

break;

}

 

case "$":

{

switch (TokensStack.Pop())

{

case "$": { break; }

default: { DebugMsg = "error: incorrect completion"; return 0; }

 

}

break;

}

default: { break; }

 

}

}

DebugMsg = "debug successful";

return 0;

}

 

}

}

 

Исходный код Shell.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace KYRS_TLP

{

class Shell

{

private List<string> IDENTIFIES = new List<string>();

private List<string> CONSTANTS = new List<string>();

private Stack<string> TokensStack = new Stack<string>();

 

private int CounterIdentifies = 0;

private int CounterConstants = 0;

public List<Stack<string>> OUT = new List<Stack<string>>();

private string OutAdd = "";

private string[] priority = { "14", "13", "15" };

 

public Shell(Stack<string> TOKENS, List<string> IDENTIFIES, List<string> CONSTANTS)

{

this.TokensStack = TOKENS;

this.IDENTIFIES = IDENTIFIES;

this.CONSTANTS = CONSTANTS;

FindOperations();

}

 

private void FindOperations()

{

while(TokensStack.Peek() != "03")

{

if(TokensStack.Pop() == "20")

{

CounterIdentifies++;

}

}

 

while(TokensStack.Count != 0)

{

switch(TokensStack.Peek())

{

case "05":

{

Stack<string> s1 = new Stack<string>();

Stack<string> s2 = new Stack<string>();

s1.Push(TokensStack.Pop());

while(TokensStack.Peek() != "11")

{

if(TokensStack.Pop() == "20")

{

s1.Push(IDENTIFIES[CounterIdentifies++]);

}

}

while (s1.Count != 0)

s2.Push(s1.Pop());

OUT.Add(s2);

break;

}

 

case "06":

{

Stack<string> s1 = new Stack<string>();

Stack<string> s2 = new Stack<string>();

s1.Push(TokensStack.Pop());

while (TokensStack.Peek() != "11")

{

if (TokensStack.Pop() == "20")

{

s1.Push(IDENTIFIES[CounterIdentifies++]);

}

}

while (s1.Count != 0)

s2.Push(s1.Pop());

OUT.Add(s2);

break;

}

 

case "07":

{

Stack<string> s1 = new Stack<string>();

Stack<string> s2 = new Stack<string>();

s1.Push(TokensStack.Pop());

s2 = Equal("08");

while (s2.Count != 0)

s1.Push(s2.Pop());

while(TokensStack.Pop() != "09")

{

if (TokensStack.Peek() == "09")

break;

s1.Push(CONSTANTS[CounterConstants++]);

for (int i = 0; i < 4; TokensStack.Pop(), i++);

s1.Push(IDENTIFIES[CounterIdentifies++]);

s2 = Equal("11");

while (s2.Count != 0)

s1.Push(s2.Pop());

}

while (s1.Count != 0)

s2.Push(s1.Pop());

OUT.Add(s2);

break;

}

 

case "12":

{

Stack<string> s1 = new Stack<string>();

Stack<string> s2 = new Stack<string>();

s1.Push(IDENTIFIES[CounterIdentifies++]);

TokensStack.Pop();

s2 = Equal("11");

while (s2.Count != 0)

s1.Push(s2.Pop());

while (s1.Count != 0)

s2.Push(s1.Pop());

OUT.Add(s2);

break;

}

 

default:

{

TokensStack.Pop();

break;

}

}

}

}

 

private Stack<string> Equal(string end)

{

Stack<string> s1 = new Stack<string>();

Stack<string> s2 = new Stack<string>();

s1.Push("$");

Stack<string> operations = new Stack<string>();

operations.Push("00");

while (TokensStack.Peek() != end)

{

switch (TokensStack.Peek())

{

case "20": { s1.Push(IDENTIFIES[CounterIdentifies++]); TokensStack.Pop(); break; }

case "21": { s1.Push(CONSTANTS[CounterConstants++]); TokensStack.Pop(); break; }

default:

{

//для унарного минуса

//если стек пуст и мы считываем минус

if(s1.Peek() == "$" && TokensStack.Peek() == "14")

s1.Push("0");

if (operations.Peek() == "16" && TokensStack.Peek() == "14")

s1.Push("0");

if (operations.Peek() == "16" || operations.Peek() == "00")

{

operations.Push(TokensStack.Pop());

break;

}

if(TokensStack.Peek() == "16")

{

operations.Push(TokensStack.Pop());

break;

}

if(TokensStack.Peek() == "17")

{

while(operations.Peek() != "16")

{

s1.Push(BinOp(operations.Pop()));

}

TokensStack.Pop();

operations.Pop();

break;

}

if(Convert.ToInt32(TokensStack.Peek()) > Convert.ToInt32(operations.Peek()))

{

operations.Push(TokensStack.Pop());

}

else

{

while(Convert.ToInt32(TokensStack.Peek()) > Convert.ToInt32(operations.Peek()) || operations.Peek() != "16")

{

if(operations.Peek() == "00")

break;

s1.Push(BinOp(operations.Pop()));

}

}

 

break;

}

}

}

while (operations.Peek() != "00")

s1.Push(BinOp(operations.Pop()));

s1.Push("$");

while (s1.Count != 0)

s2.Push(s1.Pop());

return s2;

}

 

private string BinOp(string str)

{

if (str == "13")

return "+";

if (str == "14")

return "-";

return "/";

}

}

}

 

 

Исходный код About.cs

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

 

namespace KYRS_TLP

{

public partial class About : Form

{

public About()

{

InitializeComponent();

}

 

private void LabelClose_Click(object sender, EventArgs e)

{

Close();

}

 

private Int32 tmpX;

private Int32 tmpY;

private bool flMove = false;

 

private void About_MouseDown(object sender, MouseEventArgs e)

{

if(e.Button == MouseButtons.Left && e.Y <= 21)

{

tmpX = Cursor.Position.X;

tmpY = Cursor.Position.Y;

flMove = true;

}

}

 

private void About_MouseMove(object sender, MouseEventArgs e)

{

if (flMove)

{

this.Left = this.Left + (Cursor.Position.X - tmpX);

this.Top = this.Top + (Cursor.Position.Y - tmpY);

 

tmpX = Cursor.Position.X;

tmpY = Cursor.Position.Y;

}

}

 

private void About_MouseUp(object sender, MouseEventArgs e)

{

flMove = false;

}

 

private void LabelClose_MouseHover(object sender, EventArgs e)

{

LabelClose.ForeColor = Color.LightGray;

}

 

private void LabelClose_MouseLeave(object sender, EventArgs e)

{

LabelClose.ForeColor = Color.White; } }}

 

ПРИЛОЖЕНИЕ Б

 

 

Рис3. Вывод сообщения об ошибки

 

Рис4. Вывод сообщения об ошибки

Рис5. Вывод сообщения об ошибки

 

Рис6. Вывод сообщения об ошибки

Рис7. Рабочая программа ввод(a = a, b = 2) вывод (a = 4, b = 2)