Автор работы: Пользователь скрыл имя, 20 Мая 2013 в 00:08, курсовая работа
Целью данной курсовой работы является разработка транслятора. Для достижения поставленной цели необходимо решить следующие задачи:
Представить синтаксис языка в БНФ. Определить терминалы, нетерминалы, начальный символ и набор правил для данного языка.
Создать каркас транслятора.
Построить лексический анализатор. Результатом работы анализатора должна быть таблица лексем.
Построить синтаксический анализатор. Приведение выражений к обратной польской записи.
Построить генератор кода.
Протестировать приложение.
Введение………………………………………………………………………3
Теоретическая часть…………………………………………………..4
Транслятор………………………………………………………...4
Лексический анализатор………….………………………………4
Синтаксический анализатор……………………………………...5
Генератор кода…………………………………………………….6
Практическая часть……………………………………………………8
Синтаксис языка в БНФ. Терминалы, нетерминалы, начальный символ и правила………………………..………………………...8
Лексический анализатор…………………………………………..10
Синтаксический анализатор………………………………………13
Генератор кода……………………………………………………..17
Заключение……………………………………
Var a,b;
Begin
a=1;
b=2;
Case a of
1:
b=a+b;
2:
b=a;
Endcase
Print b;
End
Выходной файл:
string 1 Var -> Type
string 1 a -> Identificator
string 1 , -> Separator
string 1 b -> Identificator
string 2 ; -> EndOfOperation
string 3 Begin -> Begin
string 3 a -> Identificator
string 3 = -> Assignment
string 3 1 -> Number
string 4 ; -> EndOfOperation
string 4 b -> Identificator
string 4 = -> Assignment
string 4 2 -> Number
string 5 ; -> EndOfOperation
string 5 Case -> Case
string 5 a -> Identificator
string 6 of -> Of
string 6 1 -> Number
string 7 : -> CaseBlock
string 7 b -> Identificator
string 7 = -> Assignment
string 7 a -> Identificator
string 7 + -> Plus
string 7 b -> Identificator
string 8 ; -> EndOfOperation
string 8 2 -> Number
string 9 : -> CaseBlock
string 9 b -> Identificator
string 9 = -> Assignment
string 9 a -> Identificator
string 10 ; -> EndOfOperation
string 11 Endcase -> EndCase
string 11 Print -> Print
string 11 b -> Identificator
string 12 ; -> EndOfOperation
string 12 End -> End
2.3 Синтаксический анализатор
Напишем процедуру, которая будет отвечать за перевод выражения в обратную польскую запись:
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;
}
}
Далее создаем различные методы, для синтаксического анализа отдельных частей исходного кода. Исходный код метода Сompile, который является основным в нашем синтаксическом анализаторе:
public static void Compile()
{
CodeGenerator.Iitialize();
_Errors = new List<Error>();
CodeGenerator.
NameTable.Initialize();
LexicalAnalyzer.Initialize();
ParseDeclareVariable();
CodeGenerator.
CodeGenerator.
LexicalAnalyzer.
if ( LexicalAnalyzer.Currentlexem == Lexemes.Begin )
ParseInstructionsSequence();
else
Error();
LexicalAnalyzer.
if(LexicalAnalyzer.
{
LexicalAnalyzer.
}
else
{
Error();
}
CheckLexem(Lexemes.EndOfFile);
CodeGenerator.
CodeGenerator.DeclareCodeEnds(
}
Тестовые примеры обнаружения ошибок синтаксическим анализатором, а также пример работы без синтаксических ошибок
Пример с ошибкой:
Пример без ошибки:
2.4 Формирование постфиксной записи:
2.5 Генератор кода
Так как наш транслятор является однопроходным, методы генератора кода будут вызываться из методов синтаксического анализатора. По мере выполнения синтаксического разбора будет генерироваться и ассемблерный код. Для удобства будем хранить его в массиве строк.
public static class CodeGenerator
{
private static List<string> _Code= new List<string>();
public static string[] Code
{
get
{
return _Code.ToArray();
}
}
private static int CodePointer=0;
public static void AddInstruction(string instruction)
{
_Code.Add(instruction);
CodePointer++;
}
public static void DeclareDataSegment()
{
AddInstruction("data segment");
}
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");
}
public static void DeclareMainProcedureStopping()
{
AddInstruction("mov ax,4c00h");
AddInstruction("int 21h");
AddInstruction("main endp");
}
public static void DeclareCodeEnds()
{
AddInstruction("code ends");
AddInstruction("end main");
}
public static void DeclarePrintProcedure()
{
AddInstruction("PRINT PROC NEAR");
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");
}
public static void DeclareVariables()
{
LinkedListNode<Identificator> node = NameTable.Identificators.
while(node!= null)
{
AddInstruction(node.Value.name + " dw 1 ");
node = node.Next;
}
}
public static void Iitialize()
{
_Code.Clear();
}
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");
}
}
Заключение
В данной курсовой работе была рассмотрена разработка транслятора, в среде Visual Studio 2008, на языке C#.
Поставленная цель была достигнута путём решения следующих задач:
Тверь 2012 г.