Автор работы: Пользователь скрыл имя, 19 Июня 2013 в 16:38, курсовая работа
Цель работы:
Построить лексический анализатор с отлавливанием ошибок на данном этапе трансляции.
Построить синтаксический анализатор с отлавливанием ошибок на данном этапе трансляции.
Построить генератор кода основных блоков исходной программы, соответствующей заданному языку, а также дополнительного блока
Введение…………………………………………………………………………3
1.Транслятор………………………………………………………....4
2.Лексический анализатор………….…………………………….…5
3.Синтаксический анализатор……………………………………....6
4.Генератор кода………………………………………………..…….6
5.Синтаксис языка в БНФ. Терминалы, нетерминалы, начальный символ и правила………………………..…………………….……...8
6.Лексический анализатор…………………………………………..10
7.Синтаксический анализатор………………………………………11
8.Генератор кода……………………………………………………..20
Заключение……………………………………………..……………………….24
Список литературы…………………………………………………………….25
Напишем процедуру, которая будет отвечать за перевод выражения в static void ParseAssigmentInstruction()
{
List<string> PostFixExpRession = new List<string>();
Stack<Lexemes> Operations = new Stack<Lexemes>();
LexicalAnalyzer.
if(LexicalAnalyzer.
{
while(LexicalAnalyzer.
{
LexicalAnalyzer.
switch (LexicalAnalyzer.Currentlexem)
{
case Lexemes.Identificator:
{
PostFixExpRession.Add(LexicalA
break;
}
case Lexemes.Number:
{
PostFixExpRession.Add(LexicalA
break;
}
case Lexemes.Division:
{
if(Operations.Count == 0)
{
Operations.Push(LexicalAnalyze
break;
}
else
{
if(Operations.Peek() == Lexemes.Multiplication)
{
Operations.Pop();
PostFixExpRession.Add("*");
Operations.Push(LexicalAnalyze
}
else if( Operations.Peek()== Lexemes.Division)
{
Operations.Pop();
PostFixExpRession.Add("/");
Operations.Push(LexicalAnalyze
}
else
{
Operations.Push(LexicalAnalyze
}
break;
}
}
case Lexemes.Minus:
{
if(Operations.Count==0)
{
Operations.Push(LexicalAnalyze
break;
}
else
{
if(Operations.Peek() == Lexemes.Division)
{
Operations.Pop();
PostFixExpRession.Add("/");
Operations.Push(LexicalAnalyze
}
else if(Operations.Peek() == Lexemes.Multiplication)
{
Operations.Pop();
PostFixExpRession.Add("*");
Operations.Push(LexicalAnalyze
}
else if(Operations.Peek()==Lexemes.
{
Operations.Pop();
PostFixExpRession.Add("-");
Operations.Push(LexicalAnalyze
}
else if(Operations.Peek() == Lexemes.Plus)
{
Operations.Pop();
PostFixExpRession.Add("+");
Operations.Push(LexicalAnalyze
}
else
{
Operations.Push(LexicalAnalyze
}
break;
}
}
case Lexemes.Multiplication:
{
if(Operations.Count==0)
{
Operations.Push(LexicalAnalyze
break;
}
else
{
if(Operations.Peek() == Lexemes.Division)
{
Operations.Pop();
PostFixExpRession.Add("/");
Operations.Push(LexicalAnalyze
}
else if(Operations.Peek() == Lexemes.Multiplication)
{
Operations.Pop();
PostFixExpRession.Add("*");
Operations.Push(LexicalAnalyze
}
else
{
Operations.Push(LexicalAnalyze
}
break;
}
}
case Lexemes.Plus:
{
if(Operations.Count == 0)
{
Operations.Push(LexicalAnalyze
break;
}
else
{
if(Operations.Peek() == Lexemes.Division)
{
Operations.Pop();
PostFixExpRession.Add("/");
Operations.Push(LexicalAnalyze
}
else if(Operations.Peek() == Lexemes.Multiplication)
{
Operations.Pop();
PostFixExpRession.Add("*");
Operations.Push(LexicalAnalyze
}
else if(Operations.Peek()==Lexemes.
{
Operations.Pop();
PostFixExpRession.Add("-");
Operations.Push(LexicalAnalyze
}
else if(Operations.Peek() == Lexemes.Plus)
{
Operations.Pop();
PostFixExpRession.Add("+");
Operations.Push(LexicalAnalyze
}
else
{
Operations.Push(LexicalAnalyze
}
break;
}
}
case Lexemes.LeftBracket:
{
Operations.Push(LexicalAnalyze
break;
}
case Lexemes.RightBracket:
{
Lexemes lex;
while ( Operations.Peek() != Lexemes.LeftBracket )
{
lex = Operations.Pop();
switch (lex)
{
case Lexemes.Division:
{
PostFixExpRession.Add("/");
break;
}
case Lexemes.Minus:
{
PostFixExpRession.Add("-");
break;
}
case Lexemes.Multiplication:
{
PostFixExpRession.Add("*");
break;
}
case Lexemes.Plus:
{
PostFixExpRession.Add("+");
break;
}
}
}
break;
}
case Lexemes.EndOfOperation:
{
Lexemes lex;
while ( Operations.Count > 0 )
{
lex = Operations.Pop();
switch ( lex )
{
case Lexemes.Division:
{
PostFixExpRession.Add("/");
break;
}
case Lexemes.Minus:
{
PostFixExpRession.Add("-");
break;
}
case Lexemes.Multiplication:
{
PostFixExpRession.Add("*");
break;
}
case Lexemes.Plus:
{
PostFixExpRession.Add("+");
break;
}
}
} break;
}
}
}
}
else
{
Error("Ожидалась инструкция присваивания");
}
switch (PostFixExpRession.Count)
{
case 1:
{
CodeGenerator.AddInstruction("
CodeGenerator.AddInstruction(s
break;
}
default:
{
CodeGenerator.
CodeGenerator.AddInstruction(s
break;
}
}
}
/// <summary>
/// метод, осуществляющий разбор инструкции печати
/// </summary>
Далее создаем различные методы,
для синтаксического анализа отдельных
частей исходного кода(
/// основной метод синтаксического анализатора, в котором происходит синтаксический
/// разбор текста и параллельно происходит геренация хода
/// </summary>
public static void Compile()
{
CodeGenerator.Iitialize();
CodeGenerator.
NameTable.Initialize();
LexicalAnalyzer.Initialize();
ParseDeclareVariable();
CodeGenerator.
CodeGenerator.
LexicalAnalyzer.
if ( LexicalAnalyzer.Currentlexem == Lexemes.Begin )
{
ParseInstructionsSequence();
}
else
{
Error("ожидалось " + LexicalAnalyzer.Currentlexem.
}
if(LexicalAnalyzer.
{
Error("ожидалось " + Lexemes.End.ToString());
}
LexicalAnalyzer.
CheckLexem(Lexemes.EndOfFile);
CodeGenerator.
CodeGenerator.DeclareCodeEnds(
}
Далее создаем различные методы, для синтаксического анализа, оператора IF, по дополнительному заданию курсового проекта.
static void ParseIfInstruction()
{
List<string> Identificators = new List<string>();
LexicalAnalyzer.
if(LexicalAnalyzer.
{
Identificators.Add(LexicalAnal
LexicalAnalyzer.
if(LexicalAnalyzer.
|| LexicalAnalyzer.Currentlexem == Lexemes.More || LexicalAnalyzer.Currentlexem == Lexemes.MoreOrEqual
|| LexicalAnalyzer.Currentlexem == Lexemes.Equal || LexicalAnalyzer.Currentlexem == Lexemes.NotEqual)
{
Buffer.lexemType = LexicalAnalyzer.Currentlexem;
Buffer.Name = LexicalAnalyzer.CurrentName;
LexicalAnalyzer.
if(LexicalAnalyzer.
{
Identificators.Add(LexicalAnal
LexicalAnalyzer.
if(LexicalAnalyzer.
{
CodeGenerator.AddInstruction("
CodeGenerator.AddInstruction("
switch (Buffer.lexemType)
{
}
{
}
CodeGenerator.AddInstruction("
while (LexicalAnalyzer.Currentlexem != Lexemes.Else && LexicalAnalyzer.Currentlexem != Lexemes.EndIf)
{
}
if (LexicalAnalyzer.Currentlexem == Lexemes.Else)
{
// CodeGenerator.AddInstruction("
}
}
else
{
Error("ожидалось Then");
}
}
else
{
Error("Ожидался идентификатор");
}
}
else
{
Error("ожидалась операция сравнения");
}
}
else
{
Error("ожидался идентификатор");
}
}
Тестовые примеры обнаружения ошибок синтаксическим анализатором, а также пример работы без синтаксических ошибок:
Пример без ошибки:
Пример с ошибкой: ( необъявленная переменная)
8. Генератор кода
Так как наш
транслятор является однопроходным, методы
генератора кода будут вызываться из
методов синтаксического
{
/// <summary>
/// класс, методы которого осуществляют генерацию кода
/// </summary>
public static class CodeGenerator
{
private static List<string> _Code= new List<string>();
/// <summary>
/// массив строк сгенерированного кода на Ассемблере
/// </summary>
public static string[] Code
{
get
{
return _Code.ToArray();
}
}
private static int CodePointer=0;
/// <summary>
/// метод, осуществляющий добавление строки Ассемблерного кода
/// в массив строк
/// </summary>
/// <param name="instruction">строка кода на Ассемблере</param>
public static void AddInstruction(string instruction)
{
_Code.Add(instruction);
CodePointer++;
}
/// <summary>
/// метод, объявляющий сегмент данных
/// </summary>
public static void DeclareDataSegment()
{
AddInstruction("data segment");
}
/// <summary>
/// метод, объявляющий сегмент кода
/// </summary>
public static void DeclareStackCodeSegment()
{
AddInstruction("PRINT_BUF DB ' ' DUP(10)");
AddInstruction("BUFEND DB '$'");
AddInstruction("data ends");
AddInstruction("stk segment stack");
AddInstruction("db 256 dup (\"?\")");
AddInstruction("stk ends");
AddInstruction("code segment");
AddInstruction("assume cs:code, ds:data, ss:stk");
AddInstruction("main proc");
AddInstruction("mov ax,data");
AddInstruction("mov ds,ax");
}
/// <summary>
/// метод, объявляющий остановку осовной процедуры программы
/// </summary>
public static void DeclareMainProcedureStopping()
{
AddInstruction("mov ax,4c00h");
AddInstruction("int 21h");
AddInstruction("main endp");
}
/// <summary>
/// метод, объявляющий конец кода
/// </summary>
public static void DeclareCodeEnds()
{
AddInstruction("code ends");
AddInstruction("end main");
}
/// <summary>
/// метод, объявляющий процедуру печати
/// </summary>
public static void DeclarePrintProcedure()
{
AddInstruction("MOV CX,10");
AddInstruction("MOV DI,BUFEND-PRINT_BUF");
AddInstruction("PRINT_LOOP:");
AddInstruction("MOV DX,0");
AddInstruction("DIV CX");
AddInstruction("ADD DL, '0'");
AddInstruction("MOV [PRINT_BUF + DI - 1], DL");
AddInstruction("DEC DI");
AddInstruction("CMP AL, 0");
AddInstruction("JNE PRINT_LOOP");
AddInstruction("LEA DX, PRINT_BUF");
AddInstruction("ADD DX, DI");
AddInstruction("MOV AH, 09H");
AddInstruction("INT 21H");
}
/// <summary>
/// меод. объявляющий объявление переменных
/// </summary>
public static void DeclareVariables()
{
LinkedListNode<Identificator> node = NameTable.Identificators.
while(node!= null)
{
AddInstruction(node.Value.name + " dw 1 ");
node = node.Next;
}
}
/// <summary>
/// Метод, инициализирующий генератор кода
/// </summary>
public static void Iitialize()
{
_Code.Clear();
}
/// <summary>
/// Метод, осуществляющий разбор постфиксной записи выражения с последующей
/// генерацией кода на Ассемблере
/// </summary>
/// <param name="Postfix">постфиксная запись выражения</param>
public static void AssigmentPostfixExprressionGen
{
for(int i=0; i<Postfix.Count; i++)
{
switch (Postfix[i])
{
case "+":
{
AddInstruction("pop bx");
AddInstruction("pop ax");
AddInstruction("add ax,bx");
AddInstruction("push ax");
break;
}
case "-":
{
AddInstruction("pop bx");
AddInstruction("pop ax");
AddInstruction("sub ax,bx");
AddInstruction("push ax");
break;
}
case "*":
{
AddInstruction("pop bx");
AddInstruction("pop ax");
AddInstruction("mul bx");
AddInstruction("push ax");
break;
}
case "/":
{
AddInstruction("pop bx");
AddInstruction("pop ax");
AddInstruction("div bx");
AddInstruction("push ax");
break;
}
default:
{
AddInstruction("mov ax," + Postfix[i]);
AddInstruction("push ax");
break;
}
}
}
AddInstruction("pop ax");
}
}
}
Заключение
В данной курсовой работе была рассмотрена разработка транслятора, в среде VisualStudio 2010, на языке C#. Была рассмотрена теоретическая часть и практическая. Практическая часть состоит из построения: синтаксического анализатора с отлавливанием ошибок на данном этапе трансляции , генератора кода основных блоков исходной программы, соответствующей заданному языку, а также дополнительного блока, генератора кода основных блоков исходной программы, соответствующей заданному языку, а также дополнительного блока. Провели тестирование приложения, для проверки правильности работы.