Транслятор

Автор работы: Пользователь скрыл имя, 19 Июня 2013 в 16:38, курсовая работа

Описание работы

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

Содержание работы

Введение…………………………………………………………………………3
1.Транслятор………………………………………………………....4
2.Лексический анализатор………….…………………………….…5
3.Синтаксический анализатор……………………………………....6
4.Генератор кода………………………………………………..…….6
5.Синтаксис языка в БНФ. Терминалы, нетерминалы, начальный символ и правила………………………..…………………….……...8
6.Лексический анализатор…………………………………………..10
7.Синтаксический анализатор………………………………………11
8.Генератор кода……………………………………………………..20
Заключение……………………………………………..……………………….24
Список литературы…………………………………………………………….25

Файлы: 1 файл

Курсовая работа транслятор.doc

— 327.00 Кб (Скачать файл)

Напишем процедуру, которая будет отвечать за перевод  выражения в static void ParseAssigmentInstruction()

{

List<string> PostFixExpRession = new List<string>();

Stack<Lexemes> Operations = new Stack<Lexemes>();

LexicalAnalyzer.ParseNextlexeme();

if(LexicalAnalyzer.Currentlexem==Lexemes.Assignment)

{

while(LexicalAnalyzer.Currentlexem!= Lexemes.EndOfOperation)

LexicalAnalyzer.ParseNextlexeme();

switch (LexicalAnalyzer.Currentlexem)

{

case Lexemes.Identificator:

{

PostFixExpRession.Add(LexicalAnalyzer.CurrentName);

break;

}

case Lexemes.Number:

{

PostFixExpRession.Add(LexicalAnalyzer.CurrentName);

break;

}

case Lexemes.Division:

{

if(Operations.Count == 0)

{

Operations.Push(LexicalAnalyzer.Currentlexem);

break;

}

else

{

if(Operations.Peek() == Lexemes.Multiplication)

{

Operations.Pop();

PostFixExpRession.Add("*");

Operations.Push(LexicalAnalyzer.Currentlexem);

}

else if( Operations.Peek()== Lexemes.Division)

{

Operations.Pop();

PostFixExpRession.Add("/");

Operations.Push(LexicalAnalyzer.Currentlexem);

}

else

{

Operations.Push(LexicalAnalyzer.Currentlexem);

}

break;

}

}

case Lexemes.Minus:

{

if(Operations.Count==0)

{

Operations.Push(LexicalAnalyzer.Currentlexem);

break;

}

else

{

if(Operations.Peek() == Lexemes.Division)

{

Operations.Pop();

PostFixExpRession.Add("/");

Operations.Push(LexicalAnalyzer.Currentlexem);

}

else if(Operations.Peek() == Lexemes.Multiplication)

{

Operations.Pop();

PostFixExpRession.Add("*");

Operations.Push(LexicalAnalyzer.Currentlexem);

}

else if(Operations.Peek()==Lexemes.Minus)

{

Operations.Pop();

PostFixExpRession.Add("-");

Operations.Push(LexicalAnalyzer.Currentlexem);

}

else if(Operations.Peek() == Lexemes.Plus)

{

Operations.Pop();

PostFixExpRession.Add("+");

Operations.Push(LexicalAnalyzer.Currentlexem);

}

else

{

Operations.Push(LexicalAnalyzer.Currentlexem);

}

break;

}

}

case Lexemes.Multiplication:

{

if(Operations.Count==0)

{

Operations.Push(LexicalAnalyzer.Currentlexem);

break;

}

else

{

if(Operations.Peek() == Lexemes.Division)

{

Operations.Pop();

PostFixExpRession.Add("/");

Operations.Push(LexicalAnalyzer.Currentlexem);

}

else if(Operations.Peek() == Lexemes.Multiplication)

{

Operations.Pop();

PostFixExpRession.Add("*");

Operations.Push(LexicalAnalyzer.Currentlexem);

}

else

{

Operations.Push(LexicalAnalyzer.Currentlexem);

}

break;

}

}

case Lexemes.Plus:

{

if(Operations.Count == 0)

{

Operations.Push(LexicalAnalyzer.Currentlexem);

break;

}

else

{

if(Operations.Peek() == Lexemes.Division)

{

Operations.Pop();

PostFixExpRession.Add("/");

Operations.Push(LexicalAnalyzer.Currentlexem);

}

else if(Operations.Peek() == Lexemes.Multiplication)

{

Operations.Pop();

PostFixExpRession.Add("*");

Operations.Push(LexicalAnalyzer.Currentlexem);

}

else if(Operations.Peek()==Lexemes.Minus)

{

Operations.Pop();

PostFixExpRession.Add("-");

Operations.Push(LexicalAnalyzer.Currentlexem);

}

else if(Operations.Peek() == Lexemes.Plus)

{

Operations.Pop();

PostFixExpRession.Add("+");

Operations.Push(LexicalAnalyzer.Currentlexem);

}

else

{

Operations.Push(LexicalAnalyzer.Currentlexem); 

}

break;

}

}

case Lexemes.LeftBracket:

{

Operations.Push(LexicalAnalyzer.Currentlexem);

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("mov ax,"+ PostFixExpRession[0]);

CodeGenerator.AddInstruction(string.Format("mov {0},ax",Buffer.Name));

break;

}

default:

{

CodeGenerator.AssigmentPostfixExprressionGeneration(PostFixExpRession);

CodeGenerator.AddInstruction(string.Format("mov {0},ax", Buffer.Name));

break;

}   

}

/// <summary>

/// метод, осуществляющий разбор инструкции печати

/// </summary>

 

Далее создаем различные методы, для синтаксического анализа отдельных частей исходного кода(ParseAssigmentInstruction, ParseInstruction, ParseInstructionSequence и тд). Исходный код метода Сompile, который является основным в нашем синтаксическом анализаторе:

/// основной метод синтаксического анализатора, в котором происходит синтаксический

/// разбор текста и параллельно происходит геренация хода

/// </summary>

        public static void Compile()

        {

CodeGenerator.Iitialize();

CodeGenerator.DeclareDataSegment();

            NameTable.Initialize();

            LexicalAnalyzer.Initialize();

ParseDeclareVariable();

CodeGenerator.DeclareVariables(); 

CodeGenerator.DeclareStackCodeSegment();

LexicalAnalyzer.ParseNextlexeme();

if ( LexicalAnalyzer.Currentlexem == Lexemes.Begin )

ParseInstructionsSequence();

}

else

{

Error("ожидалось " + LexicalAnalyzer.Currentlexem.ToString());

}

if(LexicalAnalyzer.Currentlexem != Lexemes.End)

{

Error("ожидалось " + Lexemes.End.ToString());

}

LexicalAnalyzer.ParseNextlexeme();

CheckLexem(Lexemes.EndOfFile);

CodeGenerator.DeclareMainProcedureStopping();

CodeGenerator.DeclareCodeEnds();   

        }

Далее создаем различные методы, для синтаксического анализа, оператора IF, по дополнительному заданию курсового проекта.

 

static void ParseIfInstruction()

{

List<string> Identificators = new List<string>();

 

LexicalAnalyzer.ParseNextlexeme();

if(LexicalAnalyzer.Currentlexem == Lexemes.Identificator)

{

Identificators.Add(LexicalAnalyzer.CurrentName);

LexicalAnalyzer.ParseNextlexeme();

if(LexicalAnalyzer.Currentlexem == Lexemes.Less || LexicalAnalyzer.Currentlexem == Lexemes.LessOrEqual

|| 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.ParseNextlexeme();

if(LexicalAnalyzer.Currentlexem == Lexemes.Identificator)

{

Identificators.Add(LexicalAnalyzer.CurrentName);

LexicalAnalyzer.ParseNextlexeme();

if(LexicalAnalyzer.Currentlexem == Lexemes.Then)

{

CodeGenerator.AddInstruction("mov ax," + Identificators[0]);

CodeGenerator.AddInstruction("cmp ax," + Identificators[1]);

                            switch (Buffer.lexemType)

                            {

                                case Lexemes.Less:

                                    {

                                        CodeGenerator.AddInstruction("Jge i");

                                        CodeGenerator.AddInstruction("jl e");

                                    break;

                                    }

                                case Lexemes.LessOrEqual:

                                    {

                                        CodeGenerator.AddInstruction("Jg i");

                                        CodeGenerator.AddInstruction("jle e");

                                        break;

                                    }

                                case Lexemes.More:

                                    {

                                        CodeGenerator.AddInstruction("Jle i");

                                        CodeGenerator.AddInstruction("jg e");

                                        break;

                                    }

                                case Lexemes.MoreOrEqual:

                                    {

                                        CodeGenerator.AddInstruction("Jl i");

                                        CodeGenerator.AddInstruction("jge e");

                                        break;

                                    }

                                case Lexemes.Equal:

                                    {

                                        CodeGenerator.AddInstruction("Jne i");

                                        CodeGenerator.AddInstruction("je e");

                                        break;

                                    }

                                case Lexemes.NotEqual:

                                    {

                                        CodeGenerator.AddInstruction("Je i");

                                        CodeGenerator.AddInstruction("jne e");

                                        break;

                                    }

 

                            }

                            CodeGenerator.AddInstruction("i:");

                            while (LexicalAnalyzer.Currentlexem != Lexemes.Else && LexicalAnalyzer.Currentlexem != Lexemes.EndIf)

                            {

                                LexicalAnalyzer.ParseNextlexeme();

                                ParseInstruction();

                                                           

                            }

                            if (LexicalAnalyzer.Currentlexem == Lexemes.Else)

                            {

                                CodeGenerator.AddInstruction("e:");

 

                                while (LexicalAnalyzer.Currentlexem != Lexemes.EndIf)

                                {

                                    LexicalAnalyzer.ParseNextlexeme();

                                    ParseInstruction();

                                }

                               // CodeGenerator.AddInstruction(".EndIf");

                            }

                           

}

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.First;

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 AssigmentPostfixExprressionGeneration(List<string> Postfix)

{

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#. Была рассмотрена теоретическая часть и практическая. Практическая часть состоит из построения: синтаксического анализатора с отлавливанием ошибок на данном этапе трансляции , генератора кода основных блоков исходной программы, соответствующей заданному языку, а также дополнительного блока, генератора кода основных блоков исходной программы, соответствующей заданному языку, а также дополнительного блока. Провели тестирование приложения, для проверки правильности работы.

Информация о работе Транслятор