
- •Лексический анализатор………………………………………………………….…..11
- •Синтаксический анализатор…………………………………………….……………15
- •Генератор кода………………………………………………………………..………..18
- •Теоретическая часть.
- •Транслятор.
- •Лексический анализатор.
- •Синтаксический анализатор.
- •1.4 Генератор кода.
- •Практическая часть.
- •2.1 Синтаксис языка в бнф. Терминалы, нетерминалы, начальный символ и правила.
- •2.2 Каркас транслятора.
- •2.3 Лексический анализатор.
- •2.3 Синтаксический анализатор.
- •2.4 Генератор кода.
- •Тестирование приложения.
2.3 Синтаксический анализатор.
После того как был создан класс class Reader, далее начнем заполнять его функционалом.
Напишем класс и процедуру, которая будет отвечать за перевод выражения в обратную польскую запись:
public static class PostFix
{
private static List<string> res;
private static Stack<Lexems> stack;
/// <summary>
/// Инициализировать
/// </summary>
public static void Initialize()
{
res = new List<string>();
stack = new Stack<Lexems>();
}
/// <summary>
/// Добавить
/// </summary>
/// <param name="lexem"></param>
public static void Add(Lexems lexem)
{
switch (lexem)
{
case Lexems.Name:
{
string temp = LexicalAnalyzer.CurrentName;
res.Add(temp);
}
break;
case Lexems.Number:
{
string temp = LexicalAnalyzer.CurrentName;
res.Add(temp);
}
break;
case Lexems.LeftBracket:
{
stack.Push(Lexems.LeftBracket);
}
break;
case Lexems.RightBracket:
{
while (stack.Peek() != Lexems.LeftBracket)
{
res.Add(ConvertToString(stack.Pop()));
}
stack.Pop();
}
break;
case Lexems.Minus:
case Lexems.Plus:
{
Lexems lex = new Lexems();
if (stack.Count > 0)
lex = stack.Peek();
while (lex == Lexems.Plus
|| lex == Lexems.Minus
|| lex == Lexems.Multiplication
|| lex == Lexems.Division)
{
res.Add(ConvertToString(stack.Pop()));
if (stack.Count > 0)
lex = stack.Peek();
else
break;
}
stack.Push(lexem);
}
break;
case Lexems.Multiplication:
case Lexems.Division:
{
Lexems lex = new Lexems();
if (stack.Count > 0)
lex = stack.Peek();
while (lex == Lexems.Multiplication
|| lex == Lexems.Division)
{
res.Add(ConvertToString(stack.Pop()));
if (stack.Count > 0)
lex = stack.Peek();
else
break;
}
stack.Push(lexem);
}
break;
case Lexems.Determine:
{
stack.Push(lexem);
}
break;
}
}
Далее создаем различные методы, для синтаксического анализа отдельных частей исходного кода: Блок объявления переменных, блок непосредственно выполнения каких либо операция, блок вывода на печать, блок цикла UNTIL.
public static void Compille()
{
PostFix.Initialize();
CodeGenerator.DeclairDataSegment();
LexicalAnalyzer.Initialize();
NameTable.Initialize();
ParseVariables();
CodeGenerator.DeclairVariables();
CodeGenerator.DeclairSegmentOfStackAndCode();
CheckLexem(Lexems.Semi);
if (LexicalAnalyzer.CurrentLexem == Lexems.Begin)
LexicalAnalyzer.ParseNextLexem();
ParseInstructionSequence();
CheckLexem(Lexems.End);
CodeGenerator.DeclairEndMainProc();
CodeGenerator.DeclairPrint();
CodeGenerator.DeclairCodeEnd();
if (Errors.ErrorsCount == 0)
Errors.Error("Compille success");
}
public static void ParseCycle()
{
CheckLexem(Lexems.Until);
CodeGenerator.AddLabel();
string upperLabel = CodeGenerator.GetCurrentLabel();
CodeGenerator.AddLabel();
string lowerLabel = CodeGenerator.GetCurrentLabel();
CodeGenerator.AddInstruction(upperLabel + ":");
ParseExpression();
CheckLexem(Lexems.Do);
ParseInstructionSequence();
CheckLexem(Lexems.EndUntil);
CodeGenerator.AddInstruction("jmp " + upperLabel);
CodeGenerator.AddInstruction(lowerLabel + ":");
}
static void ParseVariables()
{
CheckLexem(Lexems.None);
CheckLexem(Lexems.Int);
if (LexicalAnalyzer.CurrentLexem != Lexems.Name)
Errors.Error("Не является идентификатором");
else
{
NameTable.AddIdentificator(LexicalAnalyzer.CurrentName, tCat.Var);
LexicalAnalyzer.ParseNextLexem();
}
while (LexicalAnalyzer.CurrentLexem == Lexems.Comma)
{
LexicalAnalyzer.ParseNextLexem();
if (LexicalAnalyzer.CurrentLexem != Lexems.Name)
Errors.Error("Не является идентификатором");
else
{
NameTable.AddIdentificator(LexicalAnalyzer.CurrentName, tCat.Var);
LexicalAnalyzer.ParseNextLexem();
}
}