езультат обработки контрольного примера

остановка задачи

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

Тип автомата — Мили.

Вариант — № 21; преобразование цикла do {…} while (…)

в циклwhile (…) do {…}.

 

 

екстовое описание

Данный автомат реализуется на языке C++. Для обозначения состояний и переходов по ним используется оператор выбора switch-case.

Идеальный проход по автомату осуществляется так:

· найти ключевое слово } while(

· вывести l:

· выводить данные в файл без изменения пока не встретится закрывающая скобка }

· найти ключевое слово } do(

· вывести if (

· выводить пока не встретится закрывающая скобка )

· если найдено ещё одно ключевое слово do {, перейти к п.2, иначе — продолжить считывать код;

 

тображение автомата в виде графа

 

аблица обозначения входных символов

Входной символ Значение
Zd Символ ‘d’
Zo Символ ‘o’
Zbr Символ ‘{’
Zsp Пробел
Zbrs Символ ‘}’
Zbrc Символ ‘(’
Zbrck Символ ‘)’
Zi Символ ‘i’
Zf Символ ‘f’
Ztz Символ ‘;’
Znsn Символ ‘/’
Znd Любой символ, кроме ‘d’
Zno Любой символ, кроме ‘0’
Znbrck Любой символ, кроме ‘)’
Znnsn Любой символ, кроме ‘/’
Znn Любой символ, кроме ‘/’ и ‘}’
Znsp Любой символ, кроме пробела

аблица обозначений функций выходов

Функция Значение
W0 Нет вывода
W1 Вывод входного символа
W2 Вывод “d”, далее – входного символа
W4 Вывод “do”, далее – входного символа
W5 Вывод “l:”
W6 Вывод “if (”
W7 Вывод “{\n goto l;\n}”

 

 

онтрольный пример

Входной файл cycle.cpp:

 

 

езультат обработки контрольного примера

Выходной файл cycleout.cpp:

 

ЗАКЛЮЧЕНИЕ

В данном курсовом проекте мы реализовали автомат для разбора и преобразования циклов, написанных на языке, соответствующих требованию варианта задания. Вариант работы подразумевал также типы входного и выходного циклов. Мы обработали один цикл, в случае множественных или вложенных циклов во входных данных.

 

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

1. Горбатов В.А. Теория автоматов: учебник для вузов. - М.: АСТ: Астрель, 2008. - (Высшая школа). - 559с.

2. Карпов Ю.Г. Теория автоматов: Учебник для вузов. - СПб.: Питер, 2003. - (Учебник для вузов). - 206с.

3. Кузнецов О.П. Дискретная математика для инженера: учебник. - 6-е изд., стер. - СПб. [и др. ]: Лань, 2009. - 395 с.: ил.

4. Ахо А., Лам М., Сети Р., Ульман Дж.Д Компиляторы: принципы, технологии и инструментарий, 2 изд.: Пер. с англ. – М.: ООО «И.Д.Вильямс», 2011. – 1184 с.

 

ПРИЛОЖЕНИЕ

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

namespace CSSample

{

class Program

{

private static string code;

private static int pos = 0;

/// Получение следующего символ из входного потока данных автомата

/// <returns>Символ</returns>

private static char Next()

{

if (pos >= code.Length - 1)

return ' ';

//Символ с кодом 255 означает конец последовательности символов

return code.ToCharArray()[pos++];

}

static void Main(string[] args)

{

//Прочитаем содержимое файла, указанного параметром к командной строке

StreamReader F = new System.IO.StreamReader(args[0]);

code = F.ReadToEnd().ToUpperInvariant();

F.Close(); //закрываем файл

StreamWriter Fw = new System.IO.StreamWriter(args[1]); //Создаём выходной файл

 

string ident = ""; //Идентификатор цикла

string fromval = ""; //Значение «ОТ»

string toval = ""; //Значение «ДО»

string stepval = ""; //Значение шага

string nident = ""; //Идентификатор, встреченный после NEXT

int identpos = 0; //Позиция в идентификаторе

char c; //Обрабатываемый символ

s0:

c = Next();

if (c == 'F') goto s1;

//Если символ во входном потоке F - может быть, начало слова FOR?

Fw.Write(c);

goto s0;

s1:

c = Next();

if (c == 'O') goto s2;

//Если символы во входном потоке FO - может быть, начало слова FOR?

Fw.Write("F" + c);

goto s0;

s2:

c = Next();

if (c == 'R')

goto s3; //Если символы во входном потоке FOR - может быть, начало слова FOR?

Fw.Write("FO" + c);

goto s0;

s3:

c = Next();

if ((c == ' ') || (c == '\n') || (c == '\r')) goto s4; // FOR и пробел - определённо, FOR!

Fw.Write("FOR" + c);//А если нет - что-то другое, продолжаем дальше

goto s0;

s4:

c = Next(); //Пропускаем пробелы

if ((c == ' ') || (c == '\n') || (c == '\r'))

goto s4;

else

goto s5;

s5: //Сохраняем в память идентификатор

ident += c;

c = Next();

if (c == '=')

goto s6;

else

goto s5;

 

s6: //Опять пробелы

c = Next();

if ((c == ' ') || (c == '\n') || (c == '\r'))

goto s6;

else

goto s7;

s7: //Сохраняем начальное значение переменной

fromval += c;

c = Next();

if ((c == ' ') || (c == '\n') || (c == '\r'))

goto s8;

else

goto s7;

s8: //Начинаем поиски фразы TO

c = Next();

if ((c == ' ') || (c == '\n') || (c == '\r'))

goto s8;

else

if (c == 'T')

goto s9;

s9:

c = Next();

if (c == 'O')

goto s10;

s10:

c = Next();

if ((c == ' ') || (c == '\n') || (c == '\r'))

goto s10;

else

goto s11;

s11:

toval += c;

c = Next();

if ((c == ' ') || (c == '\n') || (c == '\r'))

goto s12;

else

goto s11;

s12: //Ищем слово STEP

c = Next();

if ((c == ' ') || (c == '\n') || (c == '\r'))

goto s12;

else

if (c == 'S') goto s13;

//Переходим к телу цикла, если STEP отсутствует

//Запись заголовка цикла

Fw.WriteLine(ident.Trim() + " = " + fromval + "\r\nDO WHILE " + ident.Trim() + " <= " + toval + "\r\n");

goto s19;

s13:

c = Next();

if (c == 'T')

goto s14;

 

s14:

c = Next();

if (c == 'E')

goto s15;

s15:

c = Next();

if (c == 'P')

goto s16;

s16:

c = Next();

if ((c == ' ') || (c == '\n') || (c == '\r'))

goto s16;

goto s17;

s17:

stepval += c;

c = Next();

if ((c == ' ') || (c == '\n') || (c == '\r'))

{

//Запись заголовка цикла

Fw.WriteLine(ident.Trim() + " = " + fromval + "\r\nDO WHILE " + ident.Trim() + " <= " + toval + "\r\n");

goto s19;

}

else

goto s17;

 

s19: //Запись тела цикла и поиск слова NEXT

 

Fw.Write(c);

c = Next();

if (c == 'N') goto s20;

goto s19;

s20:

c = Next();

if (c == 'E') goto s21;

Fw.Write("N");

goto s19;

s21:

c = Next();

if (c == 'X') goto s22;

Fw.Write("NE");

goto s19;

s22:

c = Next();

if (c == 'T') goto s23;

Fw.Write("NEX");

goto s19;

s23:

c = Next();

if ((c == ' ') || (c == '\n') || (c == '\r'))

goto s24;

Fw.Write("NEXT");

goto s19;

s24:

c = Next();

if ((c == ' ') || (c == '\n') || (c == '\r'))

goto s24;

goto s25;

s25:

//Если идентификатор другой, это NEXT от вложенного цикла

if (c != ident.Trim().ToCharArray()[identpos])

{

Fw.Write("NEXT " + nident);

identpos = 0;

nident = "";

goto s19;

}

else

{

//И даже если его начало совпадает с идентификатором из нужного цикла, но он длиннее

if (identpos >= ident.Trim().Length)

{

Fw.Write("NEXT " + nident);

nident = "";

identpos = 0;

goto s19;

}

identpos++;

}

nident += c;

c = Next();

if ((c == ' ') || (c == '\r') || (c == '\n'))

{

if (stepval == "")

Fw.WriteLine(ident + " = " + ident + " + 1");

else

Fw.WriteLine(ident + " = " + ident + " + " + stepval);

Fw.WriteLine("Loop");

goto s26;

}

goto s25;

s26:

Fw.Write(c);

c = Next();

if (c != ' ') //Символ с кодом 255 - конец входного потока

goto s26;

goto s27;

s27:

Fw.Close();

}

}

}