Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка по курсовой по программированию.DOC
Скачиваний:
42
Добавлен:
20.05.2014
Размер:
586.75 Кб
Скачать

9. Структура программы

В данном разделе описывается структура программы в виде диаграммы, определяющей вызовы подпрограмм. Указывается назначение каждой подпрограммы. Например:

Назначение подпрограмм:

fcomment

обработка комментария

fif

обработка условного оператора

fkw

выделение ключевого слова

fassign

обработка оператора присваивания

ferror

обработка ошибки

ffind

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

fae1

обработка арифметического выражения

fcopy

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

fform

формирование строки с полным текстом оператора без пробелов

foperand

обработка операнда

fvar

обработка переменной

10. Синтаксические диаграммы арифметических и логических выражений

Ниже приведены синтаксические диаграммы трёх видов арифметических выражений (ae1,ae2,ae3) и двух видов логических выражений (le1,le2), которые используются в описании вариантов индивидуальных заданий на курсовую работу. В данной работе принимается, что синтаксические диаграммы одинаковы для языков Паскаль и Си. В логических выражениях следует использовать то арифметическое выражение (ae1, ae2 или ae3), которое указано виндивидуальном задании.

Арифметическое выражение ae3

Арифметическое выражение ae2

Арифметическое выражение ae1

Логическое выражение le2

Логическое выражение le1

11. Пример программы мини-транслятора на Паскале

В данном разделе дан пример программы мини-транслятора на Паскале, который иллюстрирует её оформление. Пример отражает некоторый этап разработки программы, так как в нём почти все подпрограммы обработки синтаксических элементов представлены в виде “заглушек”, которые имитируют работу реальных подпрограмм. Использование “заглушек” отражает реальный процесс разработки программы методом пошаговой детализации и позволяет приступить к отладке программы до её полного написания (приведённая программа, хотя и не выполняет всех требуемых функций, но является работающей программой). Следует отметить, что каждая подпрограмма составляется после разработки текста соответствующего алгоритма на псевдокоде, который вносится в текст подпрограммы в виде комментариев (это иллюстрирует подпрограмма обработки комментария fComment). Представленная программа является некоторой основой, на базе которой можно разработать реальный мини-транслятора в соответствии с заданным вариантом.

programMini_Translator_Pascal_C;

{***********************************************************************

Мини-транслятор конвертирует программу на Паскале, содержащую

следующие операторы:

  • присваивание v:=ae3

  • if le2 then

  • for

  • while le2 do

  • комментарии,

в программу на Си

***********************************************************************}

usesCrt;

Type

kwType = (kwNothing, kwFor, kwWhile, kwIf);

Const

KWArray : array [kwFor..kwIf] of string = ( 'FOR', 'WHILE', 'IF');

MaxStr1 = 50;

MaxStr2 = 50;

MaxLen = 80;

FName1 = 'Text1.pas'; { имя входного файла с текстом программы на Паскале }

FName2 = 'Text2.c'; { имя выходного файла с текстом программы на Си }

var

KStr1, KStr2, NStr1, NStr2,

NPos1, NPos2, KindComment, i : integer;

Text1 : array [1..MaxStr1] of string[MaxLen];

Text2 : array [1..MaxStr2] of string[MaxLen];

Err : boolean;

F1 : Text;

ch : char;

NomKW : kwType;

{-----------------------------------------OutText -------------------------------------------------

Выдача в выходной массив Text2 подстроки S.}

procedureOutText(S : string);

begin

Text2[NStr2] := Text2[NStr2] + S;

Inc(NPos2, Length(S));

end;

{-----------------------------------------UpperCase -------------------------------------------------

Преобразование символов строки S в символы верхнего регистра.}

function UpperCase (S : string) : string;

var

i : integer;

begin

for i := 1 to Length(S) do S[i] := UpCase(S[i]);

UpperCase := S;

end;

{-----------------------------------------GetText1----------------------------------------------------

Ввод исходного текста программы из файла в массив Text1}

procedureGetText1;

begin

Assign ( F1, FName1 );

{$I-}

Reset ( F1 );

{$I+}

if IOResult <> 0 then

begin

writeln ( 'Файл ' + FName1 + ' не найден! Нажмите любую клавишу...');

ch := ReadKey; halt;

end;

KStr1:=0;

while not eof(F1) do

begin

inc(KStr1);

readln(F1,Text1[KStr1]);

end;

Close(F1);

end;

{-------------------------------------------- PutText2 ------------------------------------------------

Вывод полученного текста программы на Си из массива Text2 в файл FName2}

procedurePutText2;

var

i : integer;

begin

Assign(F1, FName2);

{$I-}

Rewrite(F1);

{$I+}

for i:=1 to NStr2-1 do

begin

writeln(F1, Text2[i]); { вывод в файл }

writeln(Text2[i]); { вывод на экран }

end;

Close(F1);

end;

{-----------------------------------------OutText -------------------------------------------------

Выдача в выходной массив Text2 подстроки S.}

procedureOutText(S : string);

begin

Text2[NPos2] := Text2[NPos2] + S;

Inc(NPos2, Length(S));

end;

{------------------------------------------ OutTextFromTo ---------------------------------------------

Копирование в текущую строку NStr2 массива Text2, начиная с позиции NPos2, символов строки S, расположенных в ней в позициях с NPosBeg по NPosEnd}

procedure OutTextFromTo (S : string; NPosBeg : integer; NPosEnd : integer);

var

i : integer;

cnt : integer;

begin

{ копирование (NPosEnd - NPosBeg + 1) символов из области памяти S[NPosBeg] в память Text2[NStr2, NPos2] }

Cnt := NPosEnd - NPosBeg + 1;

move(Text2[NStr2, NPos2], S[NPosBeg], Cnt);

Inc (NPos2,Cnt); { сдвигаем указатель на текущий выходной символ }

Inc(Text2[NStr2, 0],Cnt); { увеличиваем размерность строки }

{ for i := NPosBeg to NPosEnd do

begin

Text2[NStr2,NPos2] := S[i];

Inc(NPos2);

end;}

end;

{-----------------------------------------------isComment--------------------------------------------

Проверка наличия скобки комментария'{' или '/*' в текущей позиции NPos1 текущей строки NStr1 массива Text1. Вид скобки комментария запоминается в глобальной переменной KindComment.}

function isComment : boolean;

begin

if Text1[NStr1,NPos1]='{' then

begin

isComment:=true; KindComment:=1; inc(NPos1);

end

else

if Copy(Text1[NStr1], NPos1, 2) = '(*' then

begin

isComment:=true; KindComment:=2; inc(NPos1,2);

end

else

isComment:=false;

end;

{---------------------------------------------- fComment --------------------------------------------

Обработка комментария}

procedurefComment;

var

EndComment : string;

NPosEnd, NStrBeg : integer;

NomPos : Byte;

begin

NStrBeg:=NStr1;

{Запись в текущую строку Text2 символов ‘/*’}

{Text2[NStr2,NPos2] := '/'; Text2[NStr2,NPos2+1] := '*'; inc(NPos2, 2);}

OutText(‘/*’);

{Определение символов конца комментария в исходном тексте в зависимости от символов начала комментария }

if KindComment = 1 then EndComment := '}'

elseEndComment := '*)';

{Копирование текста комментария из Text1 в текущую строку Text2 пока не встретятся символы конца комментария или не будет достигнут конец массива Text1. При каждом переходе на следующую строку Text1 происходит увеличение на 1 счётчика nstr1.}

repeat

NomPos := Pos(EndComment, Text1[NStr1]);

if NomPos = 0 then

NPosEnd := Length(Text1[NStr1])

else

NPosEnd := NomPos-1;

{OutText(Copy(Text1[NStr1], NPos1, NPosEnd - NPos1 + 1));}

OutTextFromTo(Text1[NStr1], NPos1, NPosEnd);}

inc(NStr1);

NPos1 := 1;

until (NomPos<>0) or (NStr1>KStr1);

{Если символы конца комментария не найдены, то печать диагностического сообщения и аварийное завершение программы.}

if NomPos = 0 then

begin

writeln('Нет конца комментария, начинающегося в строке ', NStrBeg);

exit;

end;

{Запись в Text2 символов */}

OutText(‘*/’);

{Text2[NStr2,NPos2]:='*'; Text2[NStr2,NPos2+1]:='/'; inc(NPos2);}

{Text2[NStr2,0] := Chr(NPos2); {конец строки}

NStr2 := NStr2 + 1;

end;

{-------------------------------------------------- fKW------------------------------------------------

Выделение одного из ключевых слов, указанных в массиве KWArray, в текущей строке NStr1 массива Text1, начиная с позиции NPos1. Вид ключевого слова запоминается в глобальной переменной NomKW.}

function fKW :boolean;

var

i, LenKW : integer;

currWord : string;

begin

fKW := false; NomKW := kwNothing;

if (NPos1 <= Length(Text1[NStr1])) and

(Text1[NStr1, NPos1] in [‘a’..’z’,’A’..’Z’] then { возможно ключевое слово }

begin

i := NPos1;

repeat

Inc(i);

until (i <= Length(Text1[NStr1])) and (Text1[NStr1, i] in [‘a’..’z’,’A’..’Z’, ‘0’..’9’]);

{ такое условие позволяет не путать ключевое слово и идентификатор вида ‘while00023’ или ‘ifYetMore09Another’ }

currWord := Copy(Text1[NStr1], NPos1, i ‑ NPos1);

end

else

Exit;

for NomKW := kwFor to kwIf do

begin

{LenKW:=Length(KWArray[NomKW]);}

{if UpperCase(Copy(Text1[NStr1], 1, LenKW)) = KWArray[NomKW] then}

if UpperCase(currWord) = KWArray[NomKW] then

begin

inc(NPos1,LenKW); fKW := true; Exit;

end;

end;

end;

{------------------------------------------------- Zaglushka ------------------------------------------

Копирует в текущую строку массива Text2 символы текущей строки массива Text1 со вставкой перед ними комментария из строки S}

procedure Zaglushka ( S : string );

begin

S:='/*'+S+': '+Text1[NStr1]+'*/';

OutText(S)

inc(NStr1);inc(NStr2);

end;

{--------------------------------- Обработка оператора For -----------------------------------}

function fFor :boolean;

begin

Zaglushka('fFor');

fFor:=false;

end;

{------------------------------- Обработка оператора While ----------------------------------}

function fWhile :boolean;

begin

Zaglushka('fWhile');

fWhile:=false;

end;

{-------------------------------- Обработка оператора If ---------------------------------------}

function fIf :boolean;

begin

Zaglushka('fIf');

fIf:=false;

end;

{------------------------- Обработка оператора присваивания ------------------------------}

function fAssign :boolean;

begin

if Pos( ':=' , Text1[NStr1] ) > 0 then

begin

fAssign:=false; Zaglushka('fAssign');

end

else fAssign:=true;

end;

{--------------------- Обработка оператора с ключевым словом---------------------------}

procedurefStatKey;

begin

case NomKW of

kwFor: Err:=fFor; { Обработка оператора For }

kwWhile: Err:=fWhile; { Обработка оператора While }

kwIf: Err:=fIf; { Обработка оператора If }

end;

end;

{---------------------------------- Обработка ошибки ------------------------------------------}

procedurefError;

begin

Zaglushka('fError');

end;

{---------------------------------------- Трансляция -----------------------------------------------}

procedureTranslator;

begin

fillchar(Text2, sizeof (Text2), 0);

{ обнуляем массив Text2 }

NStr1:=1; NStr2:=1;

while NStr1 <= KStr1 do

{ цикл просмотра строк исходной программы

}

Begin

NPos1:=1; NPos2:=1;

if isComment then

{ если комментарий то

}

fComment

{ обработка комментария

}

Else

{ иначе

}

begin

}

if fKW then

{ если есть ключевое слово то

}

fStatKey

{ обработка оператора с ключевым словом

}

else

{ иначе

}

Err:=fAssign;

{ обработка оператора присваивания

}

if Err then

{ если ошибка то

}

fError;

{ обработка ошибки

}

end;

end;

end;

begin {--------------------начало основной программы------------------------------------}

ClrScr;

GetText1; { ввод исходного текста программы из файла }

Translator; { конвертирование программы на Паскале в программу на Си }

PutText2; { вывод результата в файл }

end.