ТЯП — лабораторная работа 2. Исходники «распознавателя».


Файл Token.cs

using System;

using System.Collections.Generic;
using System.Collections;
using System.Text;

namespace ТЯП_лб2_м6
{
enum TokenType { ERROR =0, Num, Identificator, BracketLeft, BracketRight, Not, End, Assign, OperatorBoolean};

enum LexType { Terminal = 0, Nonterminal};

enum LexRelation { Empty=0, Equality, Before, After};

delegate TokenType ChangeState(TokenType type);

class Token
{
#region Поля
private TokenType type;
private string name;
#endregion

#region Конструкторы
public Token()
{
type = TokenType.Identificator;
name = «»;
}

public Token(TokenType type, string name)
{
this.type = type;
this.name = name;
}
#endregion

#region Свойства
public TokenType Type
{
get { return this.type; }
set { this.type = value; }
}

public string Name
{
get { return this.name; }
set { this.name = value; }
}
#endregion

#region Методы
static bool IsLiter(char ch)
{
return ch >= ‘a’ && ch<=’z’ || ch>=’A’ && ch <=’Z’|| ch== ‘_’;
}

static bool IsDigit(char ch)
{
return ch==’0′ || ch==’1′;
}

public static Token[] GetTokens(string bufer)
{
List<Token> tokens = new List<Token>();
string tempName = «»;
Token tempToken;

for (int i = 0; i < bufer.Length; i++)
{
tempName = «»;

#region Буквенные слова
if(Token.IsLiter(bufer[i]))
{
do
{
tempName += bufer[i];
i++;
}
while(i < bufer.Length && (Token.IsLiter(bufer[i]) || Char.IsDigit(bufer[i])));

tempToken = new Token();
tempToken.Name = tempName;
switch (tempName)
{
case «not»:
tempToken.Type = TokenType.Not;
break;
case «or»:
case «xor»:
case «and»:
tempToken.Type = TokenType.OperatorBoolean;
break;
default:
tempToken.Type = TokenType.Identificator;
break;
}
tokens.Add(tempToken);
tempName = «»;
i—;
continue;
}
#endregion

#region Цифровые слова
if (Char.IsDigit(bufer[i]))
{
do
{
tempName += bufer[i];
i++;
}
while (i < bufer.Length && Char.IsDigit(bufer[i]));

if (tempName == «0» || tempName == «1»)
{
tempToken = new Token(TokenType.Num, tempName);
tokens.Add(tempToken);
}
else
{
tempToken = new Token(TokenType.ERROR, tempName);
tokens.Add(tempToken);
}
tempName = «»;
i—;
continue;
}
#endregion

tempName += bufer[i];

switch(bufer[i])
{
case ‘(‘:
tempToken = new Token(TokenType.BracketLeft, tempName);
tokens.Add(tempToken);
break;
case ‘)’:
tempToken = new Token(TokenType.BracketRight, tempName);
tokens.Add(tempToken);
break;
case ‘;’:
tempToken = new Token(TokenType.End, tempName);
tokens.Add(tempToken);
break;
case’ ‘:
case ‘\n’:
case ‘\0’:
break;
case ‘:’:
if (i+1 < bufer.Length && bufer[i+1] == ‘=’)
{
tempName += bufer[i+1];
i++;
tempToken = new Token(TokenType.Assign, tempName);
tokens.Add(tempToken);
}
else
{
tempToken = new Token(TokenType.ERROR, tempName);
tokens.Add(tempToken);
}
break;
default:
tempToken = new Token(TokenType.ERROR, tempName);
tokens.Add(tempToken);
break;
}
}
return tokens.ToArray();
}

public static bool ScanBool(Token[] tokens, int iStart, int iEnd)
{
if(iStart >= tokens.Length || iStart > iEnd)
return true;
//
int brackets = 0;
TokenType currentState;
ChangeState changeState = StateStartBool;
//
currentState = changeState(tokens[iStart].type);
if (currentState == TokenType.BracketLeft) brackets++;

for (int i = iStart+1; i <= iEnd && i < tokens.Length; i++)
{
if (currentState == TokenType.ERROR)
break;
switch (currentState)
{
case TokenType.Identificator:
changeState = StateIdentificator;
break;
case TokenType.Num:
changeState = StateNum;
break;
case TokenType.Assign:
changeState = StateAssign;
break;
case TokenType.Not:
changeState = StateNot;
break;
case TokenType.BracketLeft:
changeState = StateBracketLeft;
break;
case TokenType.BracketRight:
changeState = StateBracketRight;
break;
case TokenType.OperatorBoolean:
changeState = StateOperatorBool;
break;
}
currentState = changeState(tokens[i].type);
if (currentState == TokenType.BracketLeft) brackets++;
if (currentState == TokenType.BracketRight) brackets—;
if (brackets < 0)
{
currentState = TokenType.ERROR;
break;
}
}
//
if (brackets != 0)
return false;
if (currentState == TokenType.BracketRight)
return true;
if (currentState == TokenType.Num)
return true;
if (currentState == TokenType.Identificator)
return true;
return false;
}

public static bool ScanGeneral(Token[] tokens, int iStart, int iEnd)
{
bool result = true;
int iPoint;
int i = iStart;
//
while (i < iEnd && i < tokens.Length && result)
{
iPoint = Token.IndexOf(TokenType.End, tokens, i, tokens.Length — 1);
if ((iPoint — i) == 0) { i++; continue; }
if (iPoint < 3) return false;

result &= tokens[i].Type == TokenType.Identificator;
i++;
result &= tokens[i].Type == TokenType.Assign;
i++;
result &= ScanBool(tokens, i, iPoint — 1);
i = iPoint+1;
}

return result;
}

public static int IndexOf(TokenType tokenType, Token[] tokens, int iStart, int iEnd)
{
for (int i = iStart; i <= iEnd && i < tokens.Length; i++)
if (tokens[i].Type == tokenType)
return i;
return -1;
}

#region Состояния
public static TokenType StateStartBool(TokenType type)
{
TokenType result;
switch (type)
{
case TokenType.Not:
result = TokenType.Not;
break;
case TokenType.Identificator:
result = TokenType.Identificator;
break;
case TokenType.Num:
result = TokenType.Num;
break;
case TokenType.BracketLeft:
result = TokenType.BracketLeft;
break;
//case TokenType.BracketRight:
// result = TokenType.BracketRight;
// break;
default:
result = TokenType.ERROR;
break;
}
return result;
}

public static TokenType StateIdentificator(TokenType type)
{
TokenType result;
switch (type)
{
case TokenType.OperatorBoolean:
result = TokenType.OperatorBoolean;
break;
case TokenType.Assign:
result = TokenType.Assign;
break;
case TokenType.BracketRight:
result = TokenType.BracketRight;
break;
default:
result = TokenType.ERROR;
break;
}
return result;
}

public static TokenType StateAssign(TokenType type)
{
TokenType result;
switch (type)
{
case TokenType.Not:
result = TokenType.Not;
break;
case TokenType.Identificator:
result = TokenType.Identificator;
break;
case TokenType.Num:
result = TokenType.Num;
break;
case TokenType.BracketLeft:
result = TokenType.BracketLeft;
break;
default:
result = TokenType.ERROR;
break;
}
return result;
}

public static TokenType StateBracketLeft(TokenType type)
{
TokenType result;
result = StateStartBool(type);
return result;
}

public static TokenType StateBracketRight(TokenType type)
{
TokenType result;
switch (type)
{
case TokenType.OperatorBoolean:
result = TokenType.OperatorBoolean;
break;
case TokenType.BracketRight:
result = TokenType.BracketRight;
break;
default:
result = TokenType.ERROR;
break;
}
return result;
}

public static TokenType StateNot(TokenType type)
{
TokenType result;
switch (type)
{
case TokenType.Identificator:
result = TokenType.Identificator;
break;
case TokenType.Num:
result = TokenType.Num;
break;
case TokenType.BracketLeft:
result = TokenType.BracketLeft;
break;
default:
result = TokenType.ERROR;
break;
}
return result;
}

public static TokenType StateOperatorBool(TokenType type)
{
TokenType result;
switch (type)
{
case TokenType.Not:
result = TokenType.Not;
break;
case TokenType.Identificator:
result = TokenType.Identificator;
break;
case TokenType.Num:
result = TokenType.Num;
break;
case TokenType.BracketLeft:
result = TokenType.BracketLeft;
break;
default:
result = TokenType.ERROR;
break;
}
return result;
}

public static TokenType StateNum(TokenType type)
{
TokenType result;
switch (type)
{
case TokenType.OperatorBoolean:
result = TokenType.OperatorBoolean;
break;
case TokenType.BracketRight:
result = TokenType.BracketRight;
break;
default:
result = TokenType.ERROR;
break;
}
return result;
}
#endregion

public override string ToString()
{
return this.type.ToString()+» «+this.name;
}
#endregion
}

class Lex
{
#region Поля
private Token _token;
private string _name;
private LexType _type;
#endregion

#region Конструкторы
public Lex()
{
this._name = null;
this._token = null;
this._type = LexType.Nonterminal;
}

public Lex(string name, LexType type)
{
this._name = name;
this._token = null;
this._type = type;
}

public Lex(Token token)
{
this._token = token;
this._name = token.Name;
this._type = LexType.Terminal;
}
#endregion

#region Свойства
public Token Token
{
get { return this._token; }
set
{
this._token = value;
if (value != null)
{
this._type = LexType.Terminal;
this._name = value.Name;
}
}
}

public LexType Type
{
get { return this._type; }
set { this._type = value; }
}

public string Name
{
get { return this._name; }
set { this._name = value; }
}
#endregion

#region Методы
public override string ToString()
{
if (this._token == null) return this._name;
else return this.Token.Name;
}

public Lex Clone()
{
Lex clone = new Lex();
clone._token = this._token;
clone._name = this._name;
clone._type = this._type;
return clone;
}

static public int[] GetRules(Token[] tokens, LexRuleTable ruleTable, LexRelationTable relationTable, Lex lexStart, Lex lexEnd)
{
List<int> ruleList;
int ruleNumber;
List<Lex> tempList;
Stack<Lex> bufer, magazine;
Lex tempCur, tempNext;
LexRelation relation;
//
ruleList = new List<int>();
tempList = new List<Lex>();
bufer = new Stack<Lex>();
magazine = new Stack<Lex>();
//
magazine.Push(lexStart);
bufer.Push(lexEnd);
for (int i = tokens.Length — 1; i >= 0; i—)
{
tempCur = new Lex(tokens[i]);
if (tempCur.Token.Type == TokenType.Num || tempCur.Token.Type == TokenType.Identificator)
tempCur.Name = «a»;
bufer.Push(tempCur);
}

while (bufer.Count > 0)
{
tempCur = magazine.Peek();
tempNext = bufer.Peek();
relation = relationTable.GetRelation(tempCur.Name, tempNext.Name);
switch (relation)
{
case LexRelation.Before:
case LexRelation.Equality:
magazine.Push(bufer.Pop());
break;
case LexRelation.After:
tempNext = magazine.Pop();
tempCur = magazine.Peek();
tempList.Add(tempNext);
while (relationTable.GetRelation(tempCur.Name, tempNext.Name) == LexRelation.Equality)
{
tempNext = magazine.Pop();
tempCur = magazine.Peek();
tempList.Insert(0, tempNext);
}
tempCur = ruleTable.GetParient(tempList.ToArray(), out ruleNumber);
tempList.Clear();
if (tempCur == null) return ruleList.ToArray();
ruleList.Add(ruleNumber);
magazine.Push(tempCur);
break;
default:
return ruleList.ToArray();
break;
}
}
//
return ruleList.ToArray();
}
#endregion
}

class Tree
{
#region Поля
private Lex _current;
private List<Tree> _children;
#endregion

#region Конструкторы
public Tree()
{
this._current = new Lex();
this._children = new List<Tree>(3);
}

public Tree(Tree parient)
{
this._current = new Lex();
this._children = new List<Tree>(3);
}

public Tree(Lex lex)
{
this._current = lex;
this._children = new List<Tree>(3);
}

public Tree(Lex lex, Tree parient)
{
this._current = lex;
this._children = new List<Tree>(3);
}
#endregion

#region Свойства
public Lex Current
{
get { return this._current; }
set { this._current = value; }
}

public List<Tree> Children
{
get { return this._children; }
set { this._children = value; }
}
#endregion

#region Методы
private int GenerateNumber(Random rand, Lex lex, LexRuleTable table, int[] count, int[] decrements)
{
float[] p = new float[count.Length];
int maxindex;
int[] ruleNums;
float a;
Lex tempLex;
for (int i = 0; i < p.Length; i++)
{
a = (float)rand.NextDouble() * 100;
p[i] = a / (float)count[i];
}

tempLex = lex;
ruleNums = table.GetRuleNums(tempLex);
if (ruleNums == null)
return -1;
maxindex = ruleNums[0];

for (int i = 1; i < ruleNums.Length; i++)
{
if (p[ruleNums[i]] > p[maxindex])
{
maxindex = ruleNums[i];
}
}
count[maxindex] += decrements[maxindex];
return maxindex;
}

private void GenerateChildren(LexRuleTable table, int[] count, int[] decrements, Random rand)
{
if (this._current.Type == LexType.Terminal || table == null) return;

if (this._children == null) this._children = new List<Tree>(3);

int ruleNum = this.GenerateNumber(rand, this._current, table, count, decrements);

if (ruleNum < 0) return;

List<Lex> tempListLex;

this._children = new List<Tree>();
tempListLex = table.GetChildren(this._current, ruleNum);
for (int i = 0; i < tempListLex.Count;i++ )
this._children.Add(new Tree(tempListLex[i]));
}

public void GenerateTree(LexRuleTable table, int[] count, int[] decrements)
{
if (this._current == null || this._current.Type == LexType.Terminal)
return;

Random rand = new Random((int)DateTime.Now.Millisecond);

this.GenerateChildren(table, count, decrements, rand);

for (int i = this._children.Count-1; i >= 0; i—)
this._children[i].GenerateTree(table, count, decrements);
}

public void GetLexes(List<Lex> lexes)
{
for (int i = 0; i < this._children.Count; i++)
if (this._children[i]._current.Type == LexType.Nonterminal)
this._children[i].GetLexes(lexes);
else
lexes.Add(this._children[i]._current);
}

public void BuildTree(Stack<int> rules, LexRuleTable ruleTable, Stack<Token> tokens)
{
if (this._current.Type == LexType.Terminal || rules.Count <=0) return;

Lex tempLex;
int i;
int ruleNumber = rules.Pop();
List<Lex> children = ruleTable.GetChildren(this._current, ruleNumber);

if (children == null)
{
rules.Push(ruleNumber);
return;
}

if (this._children == null)
this._children = new List<Tree>(children.Count);

for (i = 0; i < children.Count; i++)
{
tempLex = children[i].Clone();
this._children.Add(new Tree(tempLex));
}

for (i = this._children.Count — 1; i >= 0; i—)
if (this._children[i].Current.Type == LexType.Nonterminal)
this._children[i].BuildTree(rules, ruleTable, tokens);
else
if (tokens.Count > 0)
this._children[i].Current.Token = tokens.Pop();
}

public void OptimizeTranzetive()
{
while (this.Children.Count == 1 && this.Children[0] != null)
{
if (this.Children[0].Current.Type == LexType.Nonterminal)
this.Children = this.Children[0].Children;
else
{
this.Current = this.Children[0].Current;
this.Children = null;
return;
}
}

for (int i = 0; i < this.Children.Count; i++)
if (this.Children[i] != null && this.Children[i].Current.Type == LexType.Nonterminal)
this.Children[i].OptimizeTranzetive();
}

public void OptimizeBrackets()
{
while (this.Children.Count == 3 && this.Children[0] != null && this.Children[0].Current.Type == LexType.Terminal && this.Children[0].Current.Token.Type == TokenType.BracketLeft)
{
if (this.Children[1].Current.Type == LexType.Nonterminal)
this.Children = this.Children[1].Children;
else
{
this.Current = this.Children[1].Current;
this.Children = null;
return;
}
}

while (this.Children.Count == 4 && this.Children[0] != null && this.Children[0].Current.Type == LexType.Terminal && this.Children[0].Current.Token.Type == TokenType.Not)
{
this.Children.RemoveRange(3, 1);
this.Children.RemoveRange(1, 1);
}

for (int i = 0; i < this.Children.Count; i++)
if (this.Children[i] != null && this.Children[i].Current.Type == LexType.Nonterminal)
this.Children[i].OptimizeBrackets();
}
#endregion
}

class LexRuleTable
{
#region Поля
private List<int> _number;
private List<Lex> _lexesParient;
private List<List<Lex>> _lexesChildren;
#endregion

#region Конструкторы
public LexRuleTable()
{
this._number = new List<int>();
this._lexesParient = new List<Lex>();
this._lexesChildren = new List<List<Lex>>();
}
#endregion

#region Методы
public void Add(Lex parient, List<Lex> children, int ruleNumber)
{
this._number.Add(ruleNumber);
this._lexesParient.Add(parient);
this._lexesChildren.Add(children);
}

public void Add(Lex parient, Lex[] children, int ruleNumber)
{
this._number.Add(ruleNumber);
this._lexesParient.Add(parient);
List<Lex> tempList = new List<Lex>(children.Length);
for (int i = 0; i < children.Length;i++ )
tempList.Add(children[i]);
this._lexesChildren.Add(tempList);
}

public void Remove(Lex parient, Lex[] children, int ruleNumber)
{
int i = 0, j = 0;
for (i = 0; i < this._lexesParient.Count; i++)
{
if (this._lexesChildren[i].Count == children.Length)
for (j = 0; j < children.Length; j++)
if (this._lexesChildren[i][j].Name != children[j].Name)
break;
if (j >= children.Length)
{
this._number.RemoveRange(i, 1);
this._lexesParient.RemoveRange(i, 1);
this._lexesChildren.RemoveRange(i, 1);
break;
}
}
}

public void Remove(Lex parient, List<Lex> children, int ruleNumber)
{
int i = 0, j = 0;
for (i = 0; i < this._lexesParient.Count; i++)
{
if (this._lexesChildren[i].Count == children.Count)
for (j = 0; j < children.Count; j++)
if (this._lexesChildren[i][j].Name != children[j].Name)
break;
if (j >= children.Count)
{
this._number.RemoveRange(i, 1);
this._lexesParient.RemoveRange(i, 1);
this._lexesChildren.RemoveRange(i, 1);
break;
}
}
}

public Lex GetParient(Lex[] children, out int ruleNumber)
{
int i = 0, j = 0;
for (i = 0; i < this._lexesParient.Count; i++)
{
if (this._lexesChildren[i].Count == children.Length)
for (j = 0; j < children.Length; j++)
if (this._lexesChildren[i][j].Name != children[j].Name)
break;
if (j == children.Length)
{
ruleNumber = this._number[i];
return this._lexesParient[i];
}
}
ruleNumber = -1;
return null;
}

public Lex GetParient(List<Lex> children, out int ruleNumber)
{
int i = 0, j = 0;
for (i = 0; i < this._lexesParient.Count; i++)
{
if (this._lexesChildren[i].Count == children.Count)
for (j = 0; j < children.Count; j++)
if (this._lexesChildren[i][j].Name != children[j].Name)
break;
if (j == children.Count)
{
ruleNumber = this._number[i];
return this._lexesParient[i];
}
}
ruleNumber = -1;
return null;
}

public int GetRuleNum(Lex[] children)
{
int i = 0, j = 0;
for (i = 0; i < this._lexesParient.Count; i++)
{
if (this._lexesChildren[i].Count == children.Length)
for (j = 0; j < children.Length; j++)
if (this._lexesChildren[i][j].Name != children[j].Name)
break;
if (j == children.Length)
{
return this._number[i];
}
}
return -1;
}

public int GetRuleNum(List<Lex> children)
{
int i = 0, j = 0;
for (i = 0; i < this._lexesParient.Count; i++)
{
if (this._lexesChildren[i].Count == children.Count)
for (j = 0; j < children.Count; j++)
if (this._lexesChildren[i][j].Name != children[j].Name)
break;
if (j == children.Count)
{
return this._number[i];
}
}
return -1;
}

public List<Lex> GetChildren(Lex parient, int ruleNumber)
{
int i = 0;
for (i = 0; i < this._lexesParient.Count; i++)
{
if (this._number[i] == ruleNumber && this._lexesParient[i].Name == parient.Name)
return this._lexesChildren[i];
}
return null;
}

public int[] GetRuleNums(Lex parient)
{
List<int> result = new List<int>();
int i = 0;
for (i = 0; i < this._lexesParient.Count; i++)
{
if (this._lexesParient[i].Name == parient.Name)
result.Add(this._number[i]);
}
if (result.Count == 0)
return null;
else
return result.ToArray();
}

public override string ToString()
{
string outline= «Правила»;
for (int i = 0; i < this._number.Count; i++)
{
outline += «\n» + this._number[i] + » : » + this._lexesParient[i].Name + » ->»;
for (int j = 0; j < this._lexesChildren[i].Count; j++)
outline += » » + this._lexesChildren[i][j].Name;
}
return outline;
}
#endregion
}
//
class LexRelationTable
{
private List<string> _lexCur, _lexNext;
private List<LexRelation> _relations;

public LexRelationTable()
{
this._lexCur = new List<string>();
this._lexNext = new List<string>();
this._relations = new List<LexRelation>();
}

public int Count
{
get { return this._relations.Count; }
}

public void Add(string lexCurrent, string lexNext, LexRelation relation)
{
this._lexCur.Add(lexCurrent);
this._lexNext.Add(lexNext);
this._relations.Add(relation);
}

public void Add(Lex lexCurrent, Lex lexNext, LexRelation relation)
{
this._lexCur.Add(lexCurrent.Name);
this._lexNext.Add(lexNext.Name);
this._relations.Add(relation);
}

public LexRelation GetRelation(string lexCurrent, string lexNext)
{
for (int i = 0; i < this.Count; i++)
if (this._lexCur[i] == lexCurrent && this._lexNext[i] == lexNext)
return this._relations[i];
return LexRelation.Empty;
}

public void RemoveRelation(string lexCurrent, string lexNext)
{
for (int i = 0; i < this.Count; i++)
if (this._lexCur[i] == lexCurrent && this._lexNext[i] == lexNext)
{
this._lexCur.RemoveRange(i, 1);
this._lexNext.RemoveRange(i, 1);
this._relations.RemoveRange(i, 1);
return;
}
}
}
//
class Triad
{
#region Поля
Token _oper, _obj1, _obj2;
int _tread1, _tread2;
#endregion

#region Конструкторы
public Triad()
{
this._obj1 = this._obj2 = this._oper = null;
this._tread1 = this._tread2 = 0;
}

public Triad(Token oper, Token obj1, Token obj2)
{
this._oper = oper;
this._obj1 = obj1;
this._obj2 = obj2;
this._tread1 = this._tread2 = 0;
}

public Triad(Token oper, int tread1, int tread2)
{
this._oper = oper;
this._tread1 = tread1;
this._tread2 = tread2;
this._obj1 = null;
this._obj2 = null;
}
#endregion

#region Свойства
public Token Operator
{
get { return this._oper; }
set { this._oper = value; }
}

public Token Operand1
{
get { return this._obj1; }
set
{
this._obj1 = value;
this._tread1 = 0;
}
}

public Token Operand2
{
get { return this._obj2; }
set
{
this._obj2 = value;
this._tread2 = 0;
}
}

public int Tread1
{
get { return this._tread1; }
set
{
this._tread1 = value;
this._obj1 = null;
}
}

public int Tread2
{
get { return this._tread2; }
set
{
this._tread2 = value;
this._obj2 = null;
}
}
#endregion

#region Методы
static public void GetTriads(Tree tree, List<Triad> result, ref int num)
{
Triad tempTriad = new Triad();

switch (tree.Children.Count)
{
case 2:// not F или not a
if (tree.Children[0] != null)
tempTriad._oper = tree.Children[0].Current.Token;
if (tree.Children[1] != null)
if (tree.Children[1].Current.Type == LexType.Terminal)
tempTriad._obj1 = tree.Children[1].Current.Token;
else
{
Triad.GetTriads(tree.Children[1], result, ref num);
tempTriad._tread1 = num;
}
else
tempTriad._obj1 = null;
tempTriad._obj2 = null;
result.Add(tempTriad);
num++;
break;
case 3:// если это оператор
if(tree.Children[1] != null)
{
if (tree.Children[1].Current.Type == LexType.Terminal && tree.Children[1].Current.Token.Type == TokenType.OperatorBoolean)
{
tempTriad._oper = tree.Children[1].Current.Token;
if (tree.Children[0].Current != null)
if (tree.Children[0].Current.Type == LexType.Nonterminal)
{
Triad.GetTriads(tree.Children[0], result, ref num);
tempTriad._tread1 = num;
}
else
tempTriad._obj1 = tree.Children[0].Current.Token;
if (tree.Children[2].Current != null)
if (tree.Children[2].Current.Type == LexType.Nonterminal)
{
Triad.GetTriads(tree.Children[2], result, ref num);
tempTriad._tread2 = num;
}
else
tempTriad._obj2 = tree.Children[2].Current.Token;
}
}
result.Add(tempTriad);
num++;
break;
case 4:
tempTriad._oper = tree.Children[1].Current.Token;
tempTriad._obj1 = tree.Children[0].Current.Token;
if (tree.Children[2].Current.Type == LexType.Nonterminal)
{
Triad.GetTriads(tree.Children[2], result, ref num);
tempTriad._tread2 = num;
}
else
tempTriad._obj2 = tree.Children[2].Current.Token;
result.Add(tempTriad);
num++;
break;
default:
break;
}
}

static public string[] GetAssemblerCode(List<Triad> triads)
{
string tempCommand;
List<string> commandsList = new List<string>();
for (int i = 0; i < triads.Count; i++)
{
tempCommand = «»;
switch (triads[i]._oper.Type)
{
case TokenType.OperatorBoolean:
if (triads[i]._obj1 == null)
tempCommand += «pop AX»;
else
tempCommand += «move AX » + triads[i]._obj1.Name;
tempCommand += «\n»;
if (triads[i]._obj2 == null)
tempCommand += «pop DX»;
else
tempCommand += «move DX » + triads[i]._obj2.Name;
tempCommand += «\n»;
tempCommand += triads[i]._oper.Name.ToLower()+» AX DX»;
tempCommand += «\n»;
tempCommand+= «push AX»;
break;
case TokenType.Assign:
if (triads[i]._obj2 == null)
tempCommand += «pop AX»;
else
tempCommand += «move AX» + triads[i]._obj2.Name;
tempCommand += «\n»;
tempCommand += «move «+triads[i]._obj1.Name+» AX»;
tempCommand += «\n»;
tempCommand += «push AX»;
break;
case TokenType.Not:
if (triads[i]._obj1 == null)
tempCommand += «pop AX»;
else
tempCommand += «move AX » + triads[i]._obj1.Name;
tempCommand += «\n»;
tempCommand += «not AX»;
tempCommand += «\n»;
tempCommand += «push AX»;
break;
default:
break;
}
commandsList.Add(tempCommand);
}
return commandsList.ToArray();
}

public override string ToString()
{
string outStr = «(» + this._oper.Name + «, «;
if (this._obj1 == null)
outStr += «^»+this._tread1.ToString();
else
outStr += this._obj1.Name;
outStr += «, «;
if (this._obj2 == null)
outStr += «^»+this._tread2.ToString();
else
outStr += this._obj2.Name;
outStr += «)»;
return outStr;
}
#endregion
}
}

Файл Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace ТЯП_лб2_м6
{
public partial class Form1 : Form
{
Tree genTree;
LexRelationTable relationTable;
LexRuleTable ruleTable;
Lex S, F, T, E, a, assigne, or, xor, and, lb, rb, not, semicolon, start, end;

public Form1()
{
InitializeComponent();
List<Lex> tempList;

S = new Lex(«S», LexType.Nonterminal);
F = new Lex(«F», LexType.Nonterminal);
T = new Lex(«T», LexType.Nonterminal);
E = new Lex(«E», LexType.Nonterminal);
a = new Lex(«a», LexType.Terminal);
or = new Lex(«or», LexType.Terminal);
xor = new Lex(«xor», LexType.Terminal);
and = new Lex(«and», LexType.Terminal);
lb = new Lex(«(«, LexType.Terminal);
rb = new Lex(«)», LexType.Terminal);
not = new Lex(«not», LexType.Terminal);
assigne = new Lex(«:=», LexType.Terminal);
semicolon = new Lex(«;», LexType.Terminal);
start = new Lex(@»\s», LexType.Terminal);
end = new Lex(@»\e;», LexType.Terminal);

#region Заполнение таблицы правил
ruleTable = new LexRuleTable();

tempList = new List<Lex>();
tempList.Add(a);
tempList.Add(assigne);
tempList.Add(S);
tempList.Add(semicolon);
ruleTable.Add(S, tempList, 0);

tempList = new List<Lex>();
tempList.Add(F);
ruleTable.Add(S, tempList, 1);

tempList = new List<Lex>();
tempList.Add(T);
tempList.Add(or);
tempList.Add(F);
ruleTable.Add(F, tempList, 2);

tempList = new List<Lex>();
tempList.Add(T);
tempList.Add(xor);
tempList.Add(F);
ruleTable.Add(F, tempList, 3);

tempList = new List<Lex>();
tempList.Add(T);
ruleTable.Add(F, tempList, 4);

tempList = new List<Lex>();
tempList.Add(E);
tempList.Add(and);
tempList.Add(T);
ruleTable.Add(T, tempList, 5);

tempList = new List<Lex>();
tempList.Add(E);
ruleTable.Add(T, tempList, 6);

tempList = new List<Lex>();
tempList.Add(not);
tempList.Add(lb);
tempList.Add(F);
tempList.Add(rb);
ruleTable.Add(E, tempList, 7);

tempList = new List<Lex>();
tempList.Add(lb);
tempList.Add(F);
tempList.Add(rb);
ruleTable.Add(E, tempList, 8);

tempList = new List<Lex>();
tempList.Add(not);
tempList.Add(a);
ruleTable.Add(E, tempList, 9);

tempList = new List<Lex>();
tempList.Add(a);
ruleTable.Add(E, tempList, 10);
#endregion

this.outputBox.Text = ruleTable.ToString();

#region Заполнение таблицы отношений предшествования
relationTable = new LexRelationTable();
relationTable.Add(or, not, LexRelation.Before);
relationTable.Add(or, lb, LexRelation.Before);
relationTable.Add(or, a, LexRelation.Before);
relationTable.Add(or, E, LexRelation.Before);
relationTable.Add(or, T, LexRelation.Before);
relationTable.Add(or, F, LexRelation.Equality);

relationTable.Add(xor, not, LexRelation.Before);
relationTable.Add(xor, lb, LexRelation.Before);
relationTable.Add(xor, a, LexRelation.Before);
relationTable.Add(xor, E, LexRelation.Before);
relationTable.Add(xor, T, LexRelation.Before);
relationTable.Add(xor, F, LexRelation.Equality);

relationTable.Add(and, not, LexRelation.Before);
relationTable.Add(and, lb, LexRelation.Before);
relationTable.Add(and, a, LexRelation.Before);
relationTable.Add(and, E, LexRelation.Before);
relationTable.Add(and, T, LexRelation.Equality);

relationTable.Add(not, lb, LexRelation.Equality);
relationTable.Add(not, a, LexRelation.Equality);

relationTable.Add(lb, not, LexRelation.Before);
relationTable.Add(lb, lb, LexRelation.Before);
relationTable.Add(lb, a, LexRelation.Before);
relationTable.Add(lb, E, LexRelation.Before);
relationTable.Add(lb, T, LexRelation.Before);
relationTable.Add(lb, F, LexRelation.Equality);

relationTable.Add(rb, or, LexRelation.After);
relationTable.Add(rb, xor, LexRelation.After);
relationTable.Add(rb, and, LexRelation.After);
relationTable.Add(rb, rb, LexRelation.After);
relationTable.Add(rb, semicolon, LexRelation.After);
relationTable.Add(rb, end, LexRelation.After);

relationTable.Add(a, or, LexRelation.After);
relationTable.Add(a, xor, LexRelation.After);
relationTable.Add(a, and, LexRelation.After);
relationTable.Add(a, rb, LexRelation.After);
relationTable.Add(a, semicolon, LexRelation.After);
relationTable.Add(a, assigne, LexRelation.Equality);
relationTable.Add(a, end, LexRelation.Equality);

relationTable.Add(assigne, not, LexRelation.Before);
relationTable.Add(assigne, lb, LexRelation.Before);
relationTable.Add(assigne, a, LexRelation.Before);
relationTable.Add(assigne, T, LexRelation.Before);
relationTable.Add(assigne, E, LexRelation.Before);
relationTable.Add(assigne, F, LexRelation.Before);
relationTable.Add(assigne, S, LexRelation.Equality);

relationTable.Add(S, semicolon, LexRelation.Equality);

relationTable.Add(F, rb, LexRelation.Equality);
relationTable.Add(F, semicolon, LexRelation.After);
relationTable.Add(F, end, LexRelation.After);

relationTable.Add(T, or, LexRelation.Equality);
relationTable.Add(T, xor, LexRelation.Equality);
relationTable.Add(T, rb, LexRelation.After);
relationTable.Add(T, semicolon, LexRelation.After);
relationTable.Add(T, end, LexRelation.After);

relationTable.Add(E, or, LexRelation.After);
relationTable.Add(E, xor, LexRelation.After);
relationTable.Add(E, and, LexRelation.Equality);
relationTable.Add(E, rb, LexRelation.After);
relationTable.Add(E, semicolon, LexRelation.After);
relationTable.Add(E, end, LexRelation.After);

relationTable.Add(semicolon, end, LexRelation.After);
relationTable.Add(semicolon, semicolon, LexRelation.After);

relationTable.Add(start, a, LexRelation.Before);
relationTable.Add(start, F, LexRelation.Before);
#endregion
}

private void buttonRecognize_Click(object sender, EventArgs e)
{
this.outputBox.Clear();
string line = this.inputBox.Text;
Token[] tokens = Token.GetTokens(line);
if (tokens != null)
{
for (int i = 0; i < tokens.Length; i++)
this.outputBox.Text += tokens[i].ToString() + «\n»;
}

bool result = Token.ScanGeneral(tokens, 0, tokens.Length — 1); //Token.ScanBool(tokens, 0, tokens.Length — 1);
this.outputBox.Text += «\n\n» + result;
}

private void buttonLoad_Click(object sender, EventArgs e)
{
string filename = Directory.GetCurrentDirectory() + @»\compiletext.txt»;
StreamReader reader = new StreamReader(filename, Encoding.GetEncoding(1251));
this.inputBox.Text = reader.ReadToEnd();
}

private void buttonGenerate_Click(object sender, EventArgs e)
{
Tree tree = new Tree(new Lex(«S», LexType.Nonterminal));
int rulesCount = 11;
int[] maxCount = new int[rulesCount];
int[] decrements = new int[rulesCount];
for (int i = 0; i < maxCount.Length; i++)
maxCount[i] = 1;

#region Штрафы
decrements[0] = 7;
decrements[1] = 0;
decrements[2] = 3;
decrements[3] = 3;
decrements[4] = 0;
decrements[5] = 3;
decrements[6] = 0;
decrements[7] = 4;
decrements[8] = 4;
decrements[9] = 0;
decrements[10] = 0;
#endregion

tree.GenerateTree(ruleTable, maxCount, decrements);

List<Lex> leses = new List<Lex>();
tree.GetLexes(leses);

string line = «»;
for (int i = 0; i < leses.Count; i++)
line += leses[i].Name + » «;

this.inputBox.Text = line;

this.treeViewOut.Nodes.Clear();
this.treeViewOut.Nodes.Add(tree.Current.Name);
this.GetTree(tree, this.treeViewOut.Nodes[0]);

}

private void GetTree(Tree tree, TreeNode treeNode)
{
TreeNode temp;
for (int i = 0; i < tree.Children.Count; i++)
if (tree.Children[i].Current.Type == LexType.Nonterminal)
{
temp = new TreeNode(tree.Children[i].Current.Name);
GetTree(tree.Children[i], temp);
treeNode.Nodes.Add(temp);
}
else
treeNode.Nodes.Add(tree.Children[i].Current.Name);
}

private void button1_Click(object sender, EventArgs e)
{
Tree tree = new Tree(S);
int[] rules;
string line;
Stack<int> stackRule = new Stack<int>();
Stack<Token> stackToken = new Stack<Token>();

this.outputBox.Clear();
this.outputBox.Text= this.ruleTable.ToString()+»\n\n»;

line = this.inputBox.Text;
Token[] tokens = Token.GetTokens(line);
if (tokens == null)
{
this.outputBox.Text += «\nError»;
return;
}
for (int i = 0; i < tokens.Length; i++)
this.outputBox.Text += tokens[i].ToString() + «\n»;
bool result = Token.ScanGeneral(tokens, 0, tokens.Length — 1);
this.outputBox.Text += «\n\n» + result;

rules = Lex.GetRules(tokens, ruleTable, relationTable, start, end);

if (rules == null)
{
this.outputBox.Text += «\nError»;
return;
}
outputBox.Text += «\n»;
for (int i = rules.Length — 1; i >= 0; i—) this.outputBox.Text += rules[i] + » «;

for (int i = 0; i < rules.Length; i++) stackRule.Push(rules[i]);
for (int i = 0; i < tokens.Length; i++) stackToken.Push(tokens[i]);

tree.BuildTree(stackRule, ruleTable, stackToken);
genTree = tree;
//
this.treeViewOut.Nodes.Clear();
this.treeViewOut.Nodes.Add(tree.Current.Name);
this.GetTree(tree, this.treeViewOut.Nodes[0]);
}

private void optimizeButton_Click(object sender, EventArgs e)
{
genTree.OptimizeTranzetive();
genTree.OptimizeBrackets();
this.treeViewOut.Nodes.Add(genTree.Current.Name);
this.GetTree(genTree, this.treeViewOut.Nodes[1]);

int num=0;
List<Triad> triats = new List<Triad>();

Triad.GetTriads(genTree, triats, ref num);

outputBox.Text += «\n\nТриады:\n»;
for (int i = 0; i < triats.Count; i++)
outputBox.Text += (i+1)+») «+triats[i].ToString()+»\n»;

outputBox.Text += «\n\nКод ассемблера:\n»;
string[] commands = Triad.GetAssemblerCode(triats);
for (int i = 0; i < triats.Count; i++)
outputBox.Text+= commands[i]+»\n»;
}
}
}

Скриншот ПО Распознаватель:

Распознаватель

compiletext.txt

var1 := b or ( c and  d);