Разработка учебного транслятора с упрощенного текстового языка высокого уровня
Методы грамматического разбора при разработке учебного транслятора. Проектирование лексического анализатора и магазинного автомата. Программная реализация синтаксического анализатора текстового языка высокого уровня. Разработка модуля интерпретации.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 06.01.2013 |
Размер файла | 697,2 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Название |
Назначение |
|
string getVarName(int id) |
Получить имя переменной по её коду |
|
int getVarVal(int id) |
Получить значение переменной по её коду |
|
bool checkKeyword(String word, int line_id) |
Проверка и добавление ключевого слова в список лексем |
|
bool checkOperator(String word, int line_id) |
Проверка и добавление оператора в список лексем |
|
bool checkDelim (String word, int line_id) |
Проверка и добавление разделителя в список лексем |
|
bool checkVar (String word, int line_id) |
Проверка и добавление переменной в список лексем, добавление нового индефикатора переменной в список переменных |
|
void doWord (String word, int line_id) |
Проверка и добавление слова к лексемам |
|
void doLine (String line, int line_id) |
Разбиение строки по пробелам |
|
void prepareLine(string line) |
Удаление лишних пробелов, табуляций и прочих невидимых символов. |
|
private void doLexAnalysis(List<String> programText)ogramText) |
Целевая процедура лексического анализа - формирование списка лексем, списка переменных. |
Таблица 7 - Назначение процедур и функций синтаксического анализатора
Название |
Назначение |
|
public void addNewTreeLevel() |
Добавление нового пустого выражения в список выражений программы |
|
public void addToCurrentTreeLevel(int id, int type) |
Добавление лексемы в текушее выражение программы |
|
Public void doSynAnalysis() |
Целевая функция синтаксического анализа - проход по списку лексем, свертка, спуск выражений, формирование списка программных выражений |
Таблица 8 - Назначение процедур и функций интерпретатора
Название |
Назначение |
|
public bool showRead() |
Проверка выражения на read выражение, вывод формы ввода значений переменных |
|
public bool showWrite() |
Проверка выражения на write выражение, вывод формы вывода значений переменных |
|
public int getExprVal() |
Вычисление постфикного выражения |
|
public bool varAssign() |
Проверка выражения на выражение присваивания переменной выражение, вычисление её значения. |
|
public bool getFor() |
Проверка выражения на выражение цикла, заталкивание нового цикла в стек циклов |
|
public bool getEndFor() |
Проверка выражения на выражение конца цикла, выталкивание цикла из стека циклов,проверка выхода из цикла, увеличение счетчика цикла на 1, возвращение к телу цикла |
|
private void runProgram() |
Целевая функция - проход по списку выражений, интерпретация |
учебный транслятор грамматический разбор
Таблица 9 - Назначения процедур и функций модуля преобразования в постфиксную запись
getOpPriority(SynAnalysis.programTreeElement elem) |
Получение приоритета операции |
|
List<SynAnalysis.programTreeElement> infixToPostfix(List<SynAnalysis.programTreeElement> expression) |
Преобразование инфиксного выражения в постфиксное |
1.4 Тестирование
На основе разработанного набора тестов, представляющих собой программы на интерпретируемом языке было осуществлено функциональное тестирование разработанного транслятора. В процессе тестирования не выявлены какие-либо ошибки в логике приложения. Результаты тестирования и набор тестов приведены в таблице 6 и в приложении Б.
Таблица 10 - Тестирование
№ теста |
Тестовая программа |
Ожидание |
Результат |
|
1 |
var a,b:integer; begin a = a + c; write(a); end |
Лексический анализ проходит успешно. Синтаксический анализ находит ошибку в строке 3. |
Рисунок Б.1 и Б.2 |
|
2 |
var a,b:integer; begin a = 1 + b; write(a,b); end |
Успешное выполнение программы |
Рисунок Б.3 |
|
3 |
var a,b:integer; begin a = 1 + (b; write(a,b); end |
Cинтаксическая ошибка - не хватает) |
Рисунок Б.4 |
|
4 |
var a,b:integer; begin b = 2; for a = 0 to (b-1) *2 do b = b + 1; end_for; write(a,b); end |
Успешное выполнение программы, выполнение цикла |
Рисунок Б.5 |
|
5 |
var a,b:integer; begin b = 2; for a = 2 to a+1*2 do b = -b + 1 end_for; write(b); end |
Синтаксическая ошибка, не законченное выражение |
Рисунок Б.6 |
|
6 |
var a,b:integer; begin b = 2; for a = 2 to a+1 b = b + 2*2; end |
Cинтаксическая ошибка, не хватает end_for; |
Рисунок Б.7 |
|
7 |
var a,b,a:integer; begin b = 2; for a = 2 to a+1 b = b + 2*2; end |
Лексическая ошибка, повторное обьявление переменной |
Рисунок Б.8 |
Список использованных источников
1. Дорофеева О.С., Князев В.Н., Ракова А.Н. Теория языков программирования и методы трансляции. - Пенза, ПГУ, 2003.
2. Карпов Ю.Г. Теория и технология программирования. Основы построения трансляторов. - СПб.: БХВ-Петербург, 2005. - 272 с.
3. Мартыненко Б.К. Языки и трансляции: Учебное пособие. - СПб: Изд-во С.-Петербургского университета, 2008. - 257 с.
4. Компаниец Р.И., Маньков Е.В., Филатов Н.Е. Системное программирование. Основы построения трансляторов. - СПб.: КОРОНА принт, 2004. - 256 с.
5. Соколов А.П. Системы программирования. Теория, методы, алгоритмы. - М.: Финансы и статистика, 2004. - 320 с.
6. Карпушин А.Н., Макаров П.С. Системное программное обеспечение: Основы трансляции: Конспект лекций. - Ульяновск, УГТУ, 2007
7. Коробова И.Л., Дьяков И.А., Литовка Ю.В. Основы разработки трансляторов в САПР: Учебное пособие. - Тамбов, ТГТУ, 2007.
8. Мелихов А.Н., Кодачигов В.И. Теория алгоритмов и формальных языков: Учебное пособие. - Таганрог, ТГРУ, 2006.
9. Рыбин С.В. Языки и грамматики // Компьютерные инструменты в образовании. - СПб.: Изд-во ЦПО "Информатизация образования", 2007, № 1,
10. с. 66-70.
11. Костельцев А.В. Построение интерпретаторов и компиляторов. - М.: Наука и техника, 2001. - 224 с.
12. Ахо А. Компиляторы. Принципы, технологии, инструменты. - М.: Диалектика, 2001. - 768 с.
13. Касьянов В.Н., Поттосин И.В. Методы построения трансляторов. - Новосибирск: Наука, 1986. - 344 с.
14. Хантер Р. Проектирование и конструирование компиляторов. - М.: Финансы и статистика, 1984. - 232 с.
15. Грис Д. Конструирование компиляторов для цифровых вычислительных машин. - М.: Мир. 1975. - 554 с.
16. Ахо А., Ульман Дж. Теория синтаксического анализа, перевода и компиляции, т.1,2. - М.: Мир, 1976.
17. Льюис Ф., Розенкранц Д., Смирну Д. Теоретические основы проектирования компиляторов. - М.: Мир, 1979. - 656 с.
18. Рейруорд-Смит В. Дж. Теория формальных языков. - М.: Радио и связь, 1988. - 128 с.
19. Зелковиц М., Шоу А., Геннон Дж. Принципы разработки программного обеспечения. - М.: Мир, 1982. - 368 с.
20. Бек Л. Введение в системное программирование. - М.: Мир, 1988. - 448 с.
21. Брой М. Информатика. Структуры систем и системное программирование: В 4-х ч. Ч. 3. - М.: Диалог-МИФИ, 1996. - 224 с.
Приложение А. Листинг программного текста транслятора
А.1 Код модуля лексического анализатора
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace KursTPL
{
public struct Var
{
public String name;
public int val;
}
public struct Lex
{
public int type;
public int id;
public int line_id;
};
class LexAnalysis
{
public const int MAX_WORD_LENGTH = 20;
public const int VAR_ID = 0;
public const int BEGIN_ID = 1;
public enum LEX_TYPES {KEYWORD, OPERATOR, DELIM, CONSTANT, VAR};
public enum ERROR_TYPES{NVAR, NBEGIN, UKEY, DVAR, LNID, RVAR, SYN}
public static string[] KEYWORDS = {"var", "begin", "end", "for", "to", "end_for", "read", "write", "integer", "do"};
public static string[] OPERATORS = {"+", "-", "*", "="};
public static string[] DELIMS = {";", ")", "(", ",", ":"};
public static string[] ERRORS = {"'var' section not found!", "'begin' section not found",
"unknown keyword", "variable redefinition", "id name is to long",
"unknown symbol", "reserved name used as variable name", "syntax error"};
public List<Lex> lexs = new List<Lex>();
public List<Var> vars = new List<Var>();
public bool analysisOK = true;
public MainForm mainForm;
public bool varFind = false;
public bool beginFind = false;
public void writeLog(String message)
{
this.mainForm.writeLog(message);
}
public LexAnalysis(MainForm mainForm, List<String> programText)
{
this.mainForm = mainForm;
writeLog("Lexical analysis start");
doLexAnalysis(programText);
}
public String getVarName(int id)
{
return vars[id].name;
}
public int getVarVal(int id)
{
return vars[id].val;
}
private void writeErrorToLog(int errorCode, int line_id)
{
writeLog("Error: " + ERRORS[errorCode] + ", line: " + line_id);
this.analysisOK = false;
}
private void writeErrorToLog(String word, int errorCode, int line_id)
{
writeLog("Error: " + ERRORS[errorCode] + " - '" + word + "'" +", line: " + line_id);
this.analysisOK = false;
}
private void writeErrorToLog(int errorCode)
{
writeLog("Error: " + ERRORS[errorCode]);
this.analysisOK = false;
}
private void addLex(int type, int id, int line_id)
{
Lex lex;
lex.type = type;
lex.id = id;
lex.line_id = line_id;
lexs.Add(lex);
}
private void addVar(String name, int val)
{
Var var;
var.name = name;
var.val = val;
vars.Add(var);
}
public void setVarVal(int id, int val)
{
Var var;
var.name = vars[id].name;
var.val = val;
vars[id] = var;
}
private bool checkKeyword(String word, int line_id)
{
for(int keyword_id = 0; keyword_id < KEYWORDS.Length; keyword_id++)
{
if (word == KEYWORDS[keyword_id])
{
addLex((int)LEX_TYPES.KEYWORD, keyword_id, line_id);
if (keyword_id == VAR_ID)
this.varFind = true;
if (keyword_id == BEGIN_ID)
this.beginFind = true;
return true;
}
}
return false;
}
private bool checkOperator(String word, int line_id)
{
for (int operation_id = 0; operation_id < OPERATORS.Length; operation_id++)
{
if (word == OPERATORS[operation_id])
{
addLex((int)LEX_TYPES.OPERATOR, operation_id, line_id);
return true;
}
}
return false;
}
private bool checkDelim(String word, int line_id)
{
for (int delim_id = 0; delim_id < DELIMS.Length; delim_id++)
{
if (word == DELIMS[delim_id])
{
addLex((int)LEX_TYPES.DELIM, delim_id, line_id);
return true;
}
}
return false;
}
private bool checkConst(String word, int line_id)
{
int val;
if(!int.TryParse(word, out val))
return false;
addLex((int)LEX_TYPES.CONSTANT, val, line_id);
return true;
}
private bool checkVar(String word, int line_id)
{
Regex regex = new Regex(@"\b[a-z]+");
if (!regex.IsMatch(word))
return false;
for (int var_id = 0; var_id < vars.Count(); var_id++)
if (word == vars[var_id].name)
{
if (!this.beginFind && this.varFind)
{
this.writeErrorToLog(word, (int)ERROR_TYPES.DVAR, line_id);
return false;
}
addLex((int)LEX_TYPES.VAR, var_id, line_id);
return true;
}
if (!this.beginFind && this.varFind)
{
addVar(word, 0);
addLex((int)LEX_TYPES.VAR, vars.Count() - 1, line_id);
return true;
}
return false;
}
private void doWord(String word, int line_id)
{
if (word == "")
return;
if (word.Length > MAX_WORD_LENGTH)
{
writeErrorToLog(word, (int)ERROR_TYPES.LNID, line_id);
return;
}
while (true)
{
if (checkKeyword(word, line_id))
break;
if (checkOperator(word, line_id))
break;
if (checkDelim(word, line_id))
break;
if (checkConst(word, line_id))
break;
if (checkVar(word, line_id))
break;
writeErrorToLog(word, (int)ERROR_TYPES.UKEY, line_id);
break;
}
}
private void doLine(string line, int line_id)
{
String[] words = line.Split(' ');
foreach (String word in words)
doWord(word, line_id);
}
public String prepareLine(string line)
{
foreach (String delim in DELIMS)
line = line.Replace(delim, " " + delim + " ");
foreach (String oper in OPERATORS)
line = line.Replace(oper, " " + oper + " ");
Regex regex = new Regex(@"\s+");
return regex.Replace(line, " ").ToLowerInvariant();
}
private void doLexAnalysis(List<String> programText)
{
for (int line_id = 0; line_id < programText.Count; line_id++)
doLine(prepareLine(programText[line_id]), line_id);
if (!this.varFind)
this.writeErrorToLog((int)ERROR_TYPES.NVAR);
if(!this.beginFind)
this.writeErrorToLog((int)ERROR_TYPES.NBEGIN);
}
}
}
А.2 Код модуля синтаксического анализатора
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace KursTPL
{
class SynAnalysis
{
private Stack<int> statesStack = new Stack<int>();
public LexAnalysis lex;
public bool isAnalysisOk = true;
private int treeLevel = -1;
public struct programTreeElement
{
public int type;
public int id;
}
public List<List<programTreeElement>> programTree;
public enum ERROR_TYPES
{
NVAR,
VVAR,
NQ,
NE,
NT,
NBEG,
SYN,
NBO,
IOMA,
IOMD,
NEQ,
MBO,
MBC,
MF,
MT,
MED,
MFV,
MTE,
MD,
MFE,
MO,
NPE
}
public static string[] ERRORS = {"No var definition", "Missing ',' or ':' in vars definition",
"Missing ','","Missing ';'", "No variable type (integer)", "No 'begin' keyword",
"Syntax error", "Missing '('","I/O missing argument", "I/O missing ',' or ')'",
"Missing '='", "Missing '('", "Missing ')'", "Missing 'for'", "Missing 'to'",
"Missing 'end_for'", "Missing 'for' variable", "Missing 'to' expression",
"Missing 'do'", "Missing 'for' expression", "Missing operator","No 'end' keyword"};
public enum STATES_TYPES
{
INIT,//init state
VAR,//INIT + "var", wait for VAR_GET, else ERROR NO VARS DEF
VAR_GET,//VAR + "variable" (OR VAR_CONT + "variable") will wait for ',' or ':', else ERROR MISSING ':' or ','
VAR_CONT, //VAR_GET + ",", will wait for "variable", else ERROR MISSING VAR DEF
VAR_TYPE_DELIM, //VAR_GET + ":", will wait for "integer", else ERROR MISSING VAR TYPE
VAR_TYPE,//VAR_TYPE_DELIM + "integer", will wait for ";", else ERROR MISSING ';'
VAR_SET,//VAR_TYPE + ';'
READ_WRITE, //EXPR _DONE + "write" or "read"
READ_WRITE_O,//READ_WRITE + "(", else ERROR MISSING '('
READ_WRITE_ARG,//READ_WRITE_O + "var" (OR WRITE_CONT + "var"), wait for ")" or ",", else I/O ERROR - BAD ARG
READ_WRITE_ARG_CONT,//READ_WRITE_VAR + ",", wait for "var", else MISSING I/O ARG
READ_WRITE_C,//WRITE_ARG + ')', else ERROR MISSING ')'
EXPR_DONE, //READ_WRITE_C + ';', VAR_EXPR + ';', VAR_SET + "begin", VAR_EXPR_C + ";"
BEGIN_VAR_EXPR, //EXPR_DONE + "variable"
EQ_VAR_EXPR, //BEGIN_VAR_EXPR + "=", else ERROR missing '='
VAR_EXPR, //EQ_VAR_EXPR + "constant" or EQ_VAR_EXPR + "variable", VAR_EXPR_SIGN + "variable", "constant"
VAR_EXPR_SIGN, //EQ_VAR_EXPR, VAR_EXPR + "-","+","*"
VAR_EXPR_O,//EQ_VAR_EXPR + "(", VAR_EXPR_SIGN + "("
VAR_EXPR_C,//VAR_EXPR + ")"
BEGIN_FOR_EXPR,
FOR,
TO,
DO,
END_FOR,
END// finish state - program is OK
};
public enum LEXEM_CODES
{
VAR = 0,//var
Q = 3,//,
E = 0,//;
EQ = 3,//=
BEG = 1,//begin
END = 2,//end
INT = 8,//integer
D = 4,//:
W = 7,//write
R = 6,//read
BO = 2,//(
BC = 1,//)
MIN = 1,//-
PLUS = 0,//+
MUL = 2,//*
FOR = 3,
TO = 4,
DO = 9,
END_FOR = 5
}
public void writeLog(String message)
{
this.lex.writeLog(message);
}
private void writeErrorToLog(int errorCode, int line_id)
{
writeLog("Error: " + ERRORS[errorCode] + ", line: " + line_id);
isAnalysisOk = false;
}
public void addNewTreeLevel()
{
programTree.Add(new List<programTreeElement>());
treeLevel++;
}
public void addToCurrentTreeLevel(int id, int type)
{
programTreeElement elem;
elem.id = id;
elem.type = type;
List<programTreeElement> currentTreeLevel = this.programTree[treeLevel];
currentTreeLevel.Add(elem);
}
public SynAnalysis(LexAnalysis lex)
{
this.lex = lex;
programTree = new List<List<programTreeElement>>();
writeLog("Syntax analysis start");
doSynAnalysis();
}
public void doSynAnalysis()
{
statesStack.Push((int)STATES_TYPES.INIT);
int lexsId = 0;
while (isAnalysisOk)
{
int currentState = statesStack.Pop();
if (lex.lexs.Count - 1 < lexsId)
{
if (currentState!= (int)STATES_TYPES.END)
writeErrorToLog((int)ERROR_TYPES.NPE, lex.lexs[lex.lexs.Count - 1].line_id);
break;
}
if (currentState == (int)STATES_TYPES.END)
{
break;
}
int lexType = lex.lexs[lexsId].type;
int lexId = lex.lexs[lexsId].id;
switch (currentState)
{
case ((int)STATES_TYPES.INIT):
if (lexType == (int)LexAnalysis.LEX_TYPES.KEYWORD && lexId == (int)LEXEM_CODES.VAR)
{
lexsId++;
statesStack.Push((int)STATES_TYPES.VAR);
break;
}
writeErrorToLog((int)ERROR_TYPES.NVAR, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.VAR):
if (lexType == (int)LexAnalysis.LEX_TYPES.VAR)
{
lexsId++;
statesStack.Push((int)STATES_TYPES.VAR_GET);
break;
}
writeErrorToLog((int)ERROR_TYPES.NVAR, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.VAR_GET):
if (lexType == (int)LexAnalysis.LEX_TYPES.DELIM && lexId == (int)LEXEM_CODES.Q)
{
lexsId++;
statesStack.Push((int)STATES_TYPES.VAR_CONT);
break;
}
if (lexType == (int)LexAnalysis.LEX_TYPES.DELIM && lexId == (int)LEXEM_CODES.D)
{
lexsId++;
statesStack.Push((int)STATES_TYPES.VAR_TYPE_DELIM);
break;
}
writeErrorToLog((int)ERROR_TYPES.VVAR, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.VAR_TYPE_DELIM):
if (lexType == (int)LexAnalysis.LEX_TYPES.KEYWORD && lexId == (int)LEXEM_CODES.INT)
{
lexsId++;
statesStack.Push((int)STATES_TYPES.VAR_TYPE);
break;
}
writeErrorToLog((int)ERROR_TYPES.NT, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.VAR_TYPE):
if (lexType == (int)LexAnalysis.LEX_TYPES.DELIM && lexId == (int)LEXEM_CODES.E)
{
lexsId++;
statesStack.Push((int)STATES_TYPES.VAR_SET);
break;
}
writeErrorToLog((int)ERROR_TYPES.NE, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.VAR_CONT):
if (lexType == (int)LexAnalysis.LEX_TYPES.VAR)
{
lexsId++;
statesStack.Push((int)STATES_TYPES.VAR_GET);
break;
}
writeErrorToLog((int)ERROR_TYPES.NVAR, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.VAR_SET):
if (lexId == (int)LEXEM_CODES.BEG && lexType == (int)LexAnalysis.LEX_TYPES.KEYWORD)
{
lexsId++;
statesStack.Push((int)STATES_TYPES.EXPR_DONE);
break;
}
writeErrorToLog((int)ERROR_TYPES.NBEG, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.EXPR_DONE):
if (lexId == (int)LEXEM_CODES.END && lexType == (int)LexAnalysis.LEX_TYPES.KEYWORD)
{
if (statesStack.Count == 0)
{
statesStack.Push((int)STATES_TYPES.END);
break;
}
writeErrorToLog((int)ERROR_TYPES.MED, lex.lexs[lexsId].line_id);
break;
}
if (lexId == (int)LEXEM_CODES.END_FOR && lexType == (int)LexAnalysis.LEX_TYPES.KEYWORD)
{
statesStack.Push((int)STATES_TYPES.END_FOR);
addNewTreeLevel();
addToCurrentTreeLevel(lexId, lexType);
break;
}
if ((lexId == (int)LEXEM_CODES.W || lexId == (int)LEXEM_CODES.R) && lexType == (int)LexAnalysis.LEX_TYPES.KEYWORD)
{
lexsId++;
statesStack.Push((int)STATES_TYPES.READ_WRITE);
addNewTreeLevel();
addToCurrentTreeLevel(lexId, lexType);
break;
}
if (lexType == (int)LexAnalysis.LEX_TYPES.VAR)
{
lexsId++;
statesStack.Push((int)STATES_TYPES.BEGIN_VAR_EXPR);
addNewTreeLevel();
addToCurrentTreeLevel(lexId, lexType);
break;
}
if (lexId == (int)LEXEM_CODES.FOR && lexType == (int)LexAnalysis.LEX_TYPES.KEYWORD)
{
lexsId++;
addNewTreeLevel();
addToCurrentTreeLevel(lexId, lexType);
statesStack.Push((int)STATES_TYPES.BEGIN_FOR_EXPR);
break;
}
writeErrorToLog((int)ERROR_TYPES.SYN, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.BEGIN_FOR_EXPR):
if (lexType == (int)LexAnalysis.LEX_TYPES.VAR)
{
addNewTreeLevel();
addToCurrentTreeLevel(lexId, lexType);
statesStack.Push((int)STATES_TYPES.FOR);
statesStack.Push((int)STATES_TYPES.BEGIN_VAR_EXPR);
lexsId++;
break;
}
writeErrorToLog((int)ERROR_TYPES.MFV, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.READ_WRITE):
if (lexId == (int)LEXEM_CODES.BO && lexType == (int)LexAnalysis.LEX_TYPES.DELIM)
{
lexsId++;
statesStack.Push((int)STATES_TYPES.READ_WRITE_O);
break;
}
writeErrorToLog((int)ERROR_TYPES.NBO, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.READ_WRITE_O):
if (lexType == (int)LexAnalysis.LEX_TYPES.VAR)
{
lexsId++;
addToCurrentTreeLevel(lexId, lexType);
statesStack.Push((int)STATES_TYPES.READ_WRITE_ARG);
break;
}
writeErrorToLog((int)ERROR_TYPES.IOMA, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.READ_WRITE_ARG):
if (lexId == (int)LEXEM_CODES.Q && lexType == (int)LexAnalysis.LEX_TYPES.DELIM)
{
lexsId++;
statesStack.Push((int)STATES_TYPES.READ_WRITE_ARG_CONT);
break;
}
if (lexId == (int)LEXEM_CODES.BC && lexType == (int)LexAnalysis.LEX_TYPES.DELIM)
{
lexsId++;
statesStack.Push((int)STATES_TYPES.READ_WRITE_C);
break;
}
writeErrorToLog((int)ERROR_TYPES.IOMD, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.READ_WRITE_ARG_CONT):
if (lexType == (int)LexAnalysis.LEX_TYPES.VAR)
{
lexsId++;
statesStack.Push((int)STATES_TYPES.READ_WRITE_ARG);
addToCurrentTreeLevel(lexId, lexType);
break;
}
writeErrorToLog((int)ERROR_TYPES.IOMA, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.READ_WRITE_C):
if (lexId == (int)LEXEM_CODES.E && lexType == (int)LexAnalysis.LEX_TYPES.DELIM)
{
lexsId++;
statesStack.Push((int)STATES_TYPES.EXPR_DONE);
break;
}
writeErrorToLog((int)ERROR_TYPES.NE, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.BEGIN_VAR_EXPR):
if (lexId == (int)LEXEM_CODES.EQ && lexType == (int)LexAnalysis.LEX_TYPES.OPERATOR)
{
statesStack.Push((int)STATES_TYPES.EQ_VAR_EXPR);
lexsId++;
break;
}
writeErrorToLog((int)ERROR_TYPES.NEQ, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.EQ_VAR_EXPR):
if (lexId == (int)LEXEM_CODES.BO && lexType == (int)LexAnalysis.LEX_TYPES.DELIM)
{
addToCurrentTreeLevel(lexId, lexType);
statesStack.Push((int)STATES_TYPES.VAR_EXPR_O);
statesStack.Push((int)STATES_TYPES.EQ_VAR_EXPR);
lexsId++;
break;
}
if (lexType == (int)LexAnalysis.LEX_TYPES.CONSTANT || lexType == (int)LexAnalysis.LEX_TYPES.VAR)
{
addToCurrentTreeLevel(lexId, lexType);
lexsId++;
statesStack.Push((int)STATES_TYPES.VAR_EXPR);
break;
}
if (lexId == (int)LEXEM_CODES.MIN && lexType == (int)LexAnalysis.LEX_TYPES.OPERATOR)
{
addToCurrentTreeLevel(-1, (int)LexAnalysis.LEX_TYPES.CONSTANT);
addToCurrentTreeLevel((int)LEXEM_CODES.MUL, (int)LexAnalysis.LEX_TYPES.OPERATOR);
lexsId++;
statesStack.Push((int)STATES_TYPES.VAR_EXPR_SIGN);
break;
}
writeErrorToLog((int)ERROR_TYPES.SYN, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.VAR_EXPR_C):
if (statesStack.Count == 0)
{
writeErrorToLog((int)ERROR_TYPES.MBO, lex.lexs[lexsId].line_id);
break;
}
if (statesStack.Pop()!= (int)STATES_TYPES.VAR_EXPR_O)
{
writeErrorToLog((int)ERROR_TYPES.MBO, lex.lexs[lexsId].line_id);
break;
}
statesStack.Push((int)STATES_TYPES.VAR_EXPR);
break;
case ((int)STATES_TYPES.VAR_EXPR):
if ((lexId == (int)LEXEM_CODES.MIN || lexId == (int)LEXEM_CODES.PLUS || lexId == (int)LEXEM_CODES.MUL) && lexType == (int)LexAnalysis.LEX_TYPES.OPERATOR)
{
addToCurrentTreeLevel(lexId, lexType);
lexsId++;
statesStack.Push((int)STATES_TYPES.VAR_EXPR_SIGN);
break;
}
if (lexId == (int)LEXEM_CODES.E && lexType == (int)LexAnalysis.LEX_TYPES.DELIM)
{
if (statesStack.Count > 0)
{
currentState = statesStack.Peek();
if (currentState == (int)STATES_TYPES.VAR_EXPR_O)
{
writeErrorToLog((int)ERROR_TYPES.MBC, lex.lexs[lexsId].line_id);
break;
}
if (currentState == (int)STATES_TYPES.VAR_EXPR_C)
{
writeErrorToLog((int)ERROR_TYPES.MBO, lex.lexs[lexsId].line_id);
break;
}
}
lexsId++;
statesStack.Push((int)STATES_TYPES.EXPR_DONE);
break;
}
if (lexId == (int)LEXEM_CODES.TO && lexType == (int)LexAnalysis.LEX_TYPES.KEYWORD)
{
addNewTreeLevel();
addToCurrentTreeLevel(-1, (int)LexAnalysis.LEX_TYPES.VAR);
statesStack.Push((int)STATES_TYPES.TO);
break;
}
if (lexId == (int)LEXEM_CODES.DO && lexType == (int)LexAnalysis.LEX_TYPES.KEYWORD)
{
statesStack.Push((int)STATES_TYPES.DO);
break;
}
if (lexId == (int)LEXEM_CODES.BC && lexType == (int)LexAnalysis.LEX_TYPES.DELIM)
{
addToCurrentTreeLevel(lexId, lexType);
statesStack.Push((int)STATES_TYPES.VAR_EXPR_C);
lexsId++;
break;
}
writeErrorToLog((int)ERROR_TYPES.SYN, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.DO):
if (statesStack.Count == 0)
{
writeErrorToLog((int)ERROR_TYPES.MT, lex.lexs[lexsId].line_id);
break;
}
currentState = statesStack.Pop();
if (currentState == (int)STATES_TYPES.VAR_EXPR_O)
{
writeErrorToLog((int)ERROR_TYPES.MBC, lex.lexs[lexsId].line_id);
break;
}
if (currentState == (int)STATES_TYPES.VAR_EXPR_C)
{
writeErrorToLog((int)ERROR_TYPES.MBO, lex.lexs[lexsId].line_id);
break;
}
if (currentState!= (int)STATES_TYPES.TO)
{
writeErrorToLog((int)ERROR_TYPES.MT, lex.lexs[lexsId].line_id);
break;
}
statesStack.Push((int)STATES_TYPES.DO);
statesStack.Push((int)STATES_TYPES.EXPR_DONE);
lexsId++;
break;
case ((int)STATES_TYPES.VAR_EXPR_SIGN):
if (lexType == (int)LexAnalysis.LEX_TYPES.VAR || lexType == (int)LexAnalysis.LEX_TYPES.CONSTANT)
{
addToCurrentTreeLevel(lexId, lexType);
lexsId++;
statesStack.Push((int)STATES_TYPES.VAR_EXPR);
break;
}
if (lexId == (int)LEXEM_CODES.BO && lexType == (int)LexAnalysis.LEX_TYPES.DELIM)
{
addToCurrentTreeLevel(lexId, lexType);
statesStack.Push((int)STATES_TYPES.VAR_EXPR_O);
statesStack.Push((int)STATES_TYPES.EQ_VAR_EXPR);
lexsId++;
break;
}
if (lexType == (int)LexAnalysis.LEX_TYPES.OPERATOR && lexId == (int)LEXEM_CODES.MIN)
{
lexsId++;
addToCurrentTreeLevel(-1, (int)LexAnalysis.LEX_TYPES.CONSTANT);
addToCurrentTreeLevel((int)LEXEM_CODES.MUL, (int)LexAnalysis.LEX_TYPES.OPERATOR);
statesStack.Push((int)STATES_TYPES.VAR_EXPR_SIGN);
break;
}
writeErrorToLog((int)ERROR_TYPES.SYN, lex.lexs[lexsId].line_id);
break;
case ((int)STATES_TYPES.END_FOR):
if (statesStack.Count == 0)
{
writeErrorToLog((int)ERROR_TYPES.MD, lex.lexs[lexsId].line_id);
break;
}
if (statesStack.Pop()!= (int)STATES_TYPES.DO)
{
writeErrorToLog((int)ERROR_TYPES.MD, lex.lexs[lexsId].line_id);
break;
}
lexsId++;
statesStack.Push((int)STATES_TYPES.EXPR_DONE);
break;
case((int)STATES_TYPES.TO):
if (statesStack.Count == 0)
{
writeErrorToLog((int)ERROR_TYPES.MF, lex.lexs[
lexsId].line_id);
break;
}
currentState = statesStack.Pop();
if (currentState == (int)STATES_TYPES.VAR_EXPR_O)
{
writeErrorToLog((int)ERROR_TYPES.MBC, lex.lexs[lexsId].line_id);
break;
}
if (currentState == (int)STATES_TYPES.VAR_EXPR_C)
{
writeErrorToLog((int)ERROR_TYPES.MBO, lex.lexs[lexsId].line_id);
break;
}
if (currentState!= (int)STATES_TYPES.FOR)
{
writeErrorToLog((int)ERROR_TYPES.MF, lex.lexs[lexsId].line_id);
break;
}
statesStack.Push((int)STATES_TYPES.TO);
statesStack.Push((int)STATES_TYPES.EQ_VAR_EXPR);
lexsId++;
break;
}
}
}
}
}
А.3 Код модуля интепретатора
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace KursTPL
{
class Intepreter
{
private SynAnalysis syn;
private int treeLevel;
public struct for_struct
{
public int var_id;
public int check_val;
public int body_level;
}
public Stack<for_struct> loops;
public Intepreter(SynAnalysis syn)
{
this.syn = syn;
this.treeLevel = 0;
this.loops = new Stack<for_struct>();
for (int i = 0; i <= syn.programTree.Count() - 1; i++)
{
syn.programTree[i] = ProgramisciJakPolska.infixToPostfix(syn.programTree[i]);
}
runProgram();
}
public static DialogResult InputBox(string title, string promptText, ref string value)
{
Form form = new Form();
Label label = new Label();
TextBox textBox = new TextBox();
Button buttonOk = new Button();
form.Text = title;
label.Text = promptText;
textBox.Text = value;
buttonOk.Text = "OK";
label.SetBounds(9, 20, 372, 13);
textBox.SetBounds(12, 36, 372, 20);
buttonOk.SetBounds(228, 72, 75, 23);
buttonOk.DialogResult = DialogResult.OK;
label.AutoSize = true;
textBox.Anchor = textBox.Anchor | AnchorStyles.Right;
buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
form.ClientSize = new Size(396, 107);
form.Controls.AddRange(new Control[] { label, textBox, buttonOk });
form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height);
form.FormBorderStyle = FormBorderStyle.FixedDialog;
form.StartPosition = FormStartPosition.CenterScreen;
form.MinimizeBox = false;
form.MaximizeBox = false;
form.AcceptButton = buttonOk;
DialogResult dialogResult = form.ShowDialog();
value = textBox.Text;
return dialogResult;
}
public bool showRead()
{
if (treeLevel > syn.programTree.Count() - 1)
return false;
List<SynAnalysis.programTreeElement> level = syn.programTree[treeLevel];
SynAnalysis.programTreeElement elem = level[0];
if(elem.type!= (int) LexAnalysis.LEX_TYPES.OPERATOR && elem.id!= (int)SynAnalysis.LEXEM_CODES.R)
return true;
String msg="";
for (int i = 1; i <= level.Count() - 1; i++)
{
elem = level[i];
msg += syn.lex.getVarName(elem.id) + " ";
}
String res = "";
if (DialogResult.OK == InputBox("Input vars values", msg, ref res))
{
String[] vals = res.Split(' ');
for (int i = 1; i <= level.Count() - 1; i++)
{
elem = level[i];
int val;
if (!int.TryParse(vals[i - 1], out val))
{
MessageBox.Show
(
"Non integer var value",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
return false;
}
syn.lex.setVarVal(elem.id, val);
}
treeLevel++;
return true;
}
return true;
}
public bool showWrite()
{
if (treeLevel > syn.programTree.Count() - 1)
return false;
List<SynAnalysis.programTreeElement> level = syn.programTree[treeLevel];
SynAnalysis.programTreeElement elem = level[0];
if (elem.type!= (int)LexAnalysis.LEX_TYPES.OPERATOR && elem.id!= (int)SynAnalysis.LEXEM_CODES.W)
return true;
String msg = "Result: ";
for (int i = 1; i <= level.Count() - 1; i++)
{
elem = level[i];
msg += syn.lex.getVarName(elem.id) + "= " + syn.lex.getVarVal(elem.id) + " ";
}
MessageBox.Show(msg, "Write vars",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
treeLevel++;
return true;
}
public int getExprVal()
{
List<SynAnalysis.programTreeElement> level = syn.programTree[treeLevel];
SynAnalysis.programTreeElement elem;
Stack<int> exprVals = new Stack<int>();
for (int i = 1; i <= level.Count() - 1; i++)
{
elem = level[i];
if (elem.type == (int)LexAnalysis.LEX_TYPES.VAR)
{
exprVals.Push(syn.lex.getVarVal(elem.id));
continue;
}
if (elem.type == (int)LexAnalysis.LEX_TYPES.CONSTANT)
{
exprVals.Push(elem.id);
continue;
}
int right = exprVals.Pop();
int left = exprVals.Pop();
switch(elem.id)
{
case (int)SynAnalysis.LEXEM_CODES.PLUS:
exprVals.Push(left + right);
break;
case (int)SynAnalysis.LEXEM_CODES.MIN:
exprVals.Push(left - right);
break;
case (int)SynAnalysis.LEXEM_CODES.MUL:
exprVals.Push(left * right);
break;
}
}
return exprVals.Pop();
}
public bool varAssign()
{
if (treeLevel > syn.programTree.Count() - 1)
return false;
List<SynAnalysis.programTreeElement> level = syn.programTree[treeLevel];
SynAnalysis.programTreeElement elem = level[0];
if (elem.type!= (int)LexAnalysis.LEX_TYPES.VAR)
return true;
syn.lex.setVarVal(elem.id, getExprVal());
treeLevel++;
return true;
}
public bool getFor()
{
if (treeLevel > syn.programTree.Count() - 1)
return false;
List<SynAnalysis.programTreeElement> level = syn.programTree[treeLevel];
SynAnalysis.programTreeElement elem = level[0];
if (elem.type!= (int)LexAnalysis.LEX_TYPES.KEYWORD)
return true;
if(elem.id!= (int)SynAnalysis.LEXEM_CODES.FOR)
return true;
for_struct fs;
treeLevel++;
level = syn.programTree[treeLevel];
elem = level[0];
fs.var_id = elem.id;
syn.lex.setVarVal(elem.id, getExprVal());
treeLevel++;
level = syn.programTree[treeLevel];
elem = level[0];
fs.check_val = getExprVal();
treeLevel++;
fs.body_level = treeLevel;
loops.Push(fs);
return true;
}
public bool getEndFor()
{
if (treeLevel > syn.programTree.Count() - 1)
return false;
List<SynAnalysis.programTreeElement> level = syn.programTree[treeLevel];
SynAnalysis.programTreeElement elem = level[0];
if (elem.type!= (int)LexAnalysis.LEX_TYPES.KEYWORD)
return true;
if(elem.id!= (int)SynAnalysis.LEXEM_CODES.END_FOR)
return true;
for_struct fs = loops.Pop();
int var_val;
if ((var_val = syn.lex.getVarVal(fs.var_id)) < fs.check_val)
{
treeLevel = fs.body_level;
syn.lex.setVarVal(fs.var_id, ++var_val);
loops.Push(fs);
return true;
}
treeLevel++;
return true;
}
private void runProgram()
{
while (true)
{
if(!showRead())
break;
if(!showWrite())
break;
if(!varAssign())
break;
if(!getFor())
break;
if (!getEndFor())
break;
}
syn.writeLog("Interpretation OK");
}
}
}
А.4 Код модуля постфиксной записи
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace KursTPL
{
class ProgramisciJakPolska // Программисты любят Польшу
{
private static Stack<SynAnalysis.programTreeElement> operatorsStack = new Stack<SynAnalysis.programTreeElement>();
private static int getOpPriority(SynAnalysis.programTreeElement elem)
{
if (elem.id == (int)SynAnalysis.LEXEM_CODES.MUL && elem.type == (int)LexAnalysis.LEX_TYPES.OPERATOR)
return 3;
if ((elem.id == (int)SynAnalysis.LEXEM_CODES.MIN || elem.id == (int)SynAnalysis.LEXEM_CODES.PLUS) && elem.type == (int)LexAnalysis.LEX_TYPES.OPERATOR)
return 2;
//if(elem.type == LexAnalysis.LEX_TYPES.DELIM)
return 1;
}
public static List<SynAnalysis.programTreeElement> infixToPostfix(List<SynAnalysis.programTreeElement> expression)
{
operatorsStack.Clear();
List<SynAnalysis.programTreeElement> result = new List<SynAnalysis.programTreeElement>();
SynAnalysis.programTreeElement elem = expression[0];
if (elem.type!= (int)LexAnalysis.LEX_TYPES.VAR)
return expression;
result.Add(elem);
for (int i = 1; i <= expression.Count() - 1; i++)
{
elem = expression[i];
if (elem.id == (int)SynAnalysis.LEXEM_CODES.BC && elem.type == (int)LexAnalysis.LEX_TYPES.DELIM) // Если очеpедной символ - ')'
{
while (true)
{
SynAnalysis.programTreeElement pop = operatorsStack.Pop();
if (pop.id == (int)SynAnalysis.LEXEM_CODES.BO && pop.type == (int)LexAnalysis.LEX_TYPES.DELIM)
break;
result.Add(pop);
}
continue;
}
if (elem.type == (int)LexAnalysis.LEX_TYPES.VAR || elem.type == (int)LexAnalysis.LEX_TYPES.CONSTANT)
{
result.Add(elem);
continue;
}
if (elem.id == (int)SynAnalysis.LEXEM_CODES.BO && elem.type == (int)LexAnalysis.LEX_TYPES.DELIM)
{
operatorsStack.Push(elem);
continue;
}
if (elem.type == (int)LexAnalysis.LEX_TYPES.OPERATOR)
{
if (operatorsStack.Count == 0)
operatorsStack.Push(elem);
else
if (getOpPriority(elem) > getOpPriority(operatorsStack.Peek()))
operatorsStack.Push(elem);
else
{
while (true)
{
if (operatorsStack.Count == 0)
break;
if (getOpPriority(elem) > getOpPriority(operatorsStack.Peek()))
break;
result.Add(operatorsStack.Pop());
}
operatorsStack.Push(elem);
}
}
}
while (operatorsStack.Count!= 0)
result.Add(operatorsStack.Pop());
return result;
}
}
}
Приложение Б. Результаты тестирования
Рисунок Б.1-Результат работы тестовой программы №1
Рисунок Б.2-Результат работы тестовой программы №2
Рисунок Б.3-Результат работы тестовой программы №3
Рисунок Б.4-Результат работы тестовой программы №4
Рисунок Б.5-Результат работы тестовой программы №5
Рисунок Б.6-Результат работы тестовой программы №6
Рисунок Б.7-Результат работы тестовой программы №7
Приложение В. Схема программы транслятора
Рисунок В.1 Схема программы лексического анализатора
Рисунок В.2 - Схема программы синтаксического анализатора.
Рисунок В.3- Схема программы работы интерпретатора
Рисунок В.4- Схема программы работы программы
Размещено на Allbest.ru
Подобные документы
Транслятор как программа или техническое средство, выполняющее трансляцию программы. Рассмотрение основных особенностей постройки лексического анализатора. Знакомство с этапами разработки транслятора с ограниченного подмножества языка высокого уровня.
курсовая работа [580,5 K], добавлен 06.08.2013Проектирование лексического и синтаксического анализаторов учебного языка. Правила преобразования логических выражений в ПОЛИЗ. Формирование триад, оптимизация их списка. Логическая структура программы. Тестирование модулей транслятора-интерпретатора.
курсовая работа [1,3 M], добавлен 28.05.2013Общая характеристика и оценка возможностей языка программирования си-шарп, его сходные и отличительные черты от С++ и Java. Разработка с помощью данного языка программирования лексического и синтаксического анализатора. Составление таблиц разбора.
курсовая работа [111,6 K], добавлен 11.06.2010Проектирование программы-анализатора, состоящей из двух частей: лексического анализатора, разбивающего исходный текст программы на лексемы и заполняющего таблицу имен; синтаксического анализатора, проверяющего соответствие текста заданной грамматике.
курсовая работа [2,0 M], добавлен 14.06.2010Написание программы, которая выполняет лексический и синтаксический анализ входного языка программирования, порождает таблицу лексем с указанием их типов и значений, а также строит синтаксическое дерево; текст входного языка вводится с клавиатуры.
курсовая работа [761,5 K], добавлен 23.02.2012Методика разработки и частичная реализация транслятора для языка "С" с использованием языка "С++", производящего разбиение на минимальные неделимые конструкции языка исходной цепочки символов основываясь на лексике языка. Анализ работы программы.
курсовая работа [841,3 K], добавлен 19.03.2012Структура, классификация и требования к реализации компилятора. Проектирование и реализация анализирующей части компилятора языка С++. Способы реализации лексического анализа. Алгоритм работы синтаксического анализатора. Принципы программной реализации.
курсовая работа [774,2 K], добавлен 26.01.2013Создание транслятора, обрабатывающего код программы на языке Паскаль и за счет эквивалентных операторов генерирующего программу на Си. Особенности внешней спецификации и работы лексического анализатора. Структура программы, вывод результатов на экран.
курсовая работа [254,0 K], добавлен 02.07.2011Методы грамматического разбора. Разработка структуры учебного транслятора на базовом языке программирования Object Pascal в среде объектно-ориентированного визуального программирования Borland DELPHI 6.0 с использованием операционной системы Windows XP.
курсовая работа [493,8 K], добавлен 12.05.2013Программная реализация настольного приложения с использованием языка программирования C#. Проектирование и структура пользовательского интерфейса, требования к нему и оценка функциональности. Разработка руководства пользователя и его использование.
курсовая работа [297,6 K], добавлен 10.03.2015