Скачиваний:
7
Добавлен:
20.05.2014
Размер:
167.94 Кб
Скачать

5.8 Алгоритм обработки ключевого слова Include

нач

пропуск 8 символов

проверяем наличие ‘<’ , ‘>’ и допустимость имени файла

если подключаем stdio.h то InclFlg = правда все

если ошибка в синтаксисе то обработка ошибки с кодом 11

кон

5.9 Алгоритм обработки ключевого слова Union

нач

увеличиваем на 1 nstr2 и kstr2

un = правда

если не v_open то

выводим в вых поток ‘var’

увеличиваем на 1 nstr2 и kstr2

все

NUnStr = текущему номеру строки

увеличиваем на 1 nstr2 и kstr2

кон

5.10 Алгоритм обработки ключевого слова do

нач

увеличиваем на 1 nstr2 и kstr2

выводим в вых поток ‘repeat’

кон

5.10 Алгоритм обработки ключевого слова main

нач

mainflg = правда

проверка наличия ‘(‘ и ‘)’

если ошибка в синтаксисе то обработка ошибки с кодом 5

кон

5.11 Алгоритм обработки ключевого слова define

нач

увеличиваем на 1 nstr2 и kstr2

если это первый дефайн то

выводим в вых поток ‘const’

увеличиваем на 1 nstr2 и kstr2

иначе def = правда

все

выводим в вых поток все до пробела или до конца строки

выводим в вых поток “=’”

выводим в вых поток все до конца строки

выводим в вых поток “’”

кон

5.12 Алгоритм обработки ключевого слова while

нач

увеличиваем на 1 nstr2 и kstr2

проверяем на ‘(‘

проверяем на le2

проверяем на ‘)’

проверяем на ‘;’

если ошибка в синтаксисе то обработка ошибки с кодом 5

выход

наче

выводим в вых поток 'until not('+ostr+');'

все

кон

5.12 Алгоритм обработки открывающейся операторной скобки

нач

увеличиваем на 1 nstr2 и kstr2

выводим в вых поток 'begin’

кон

5.13Алгоритм обработки закрывающейся операторной скобки

нач

если не закрыт union то выход все

увеличиваем на 1 nstr2 и kstr2

выводим в вых поток 'end’

если это последняя строка то выводим вых поток '.’ иначе

выводим в вых поток ';’

все

кон

5.14 Алгоритм обработки ключевого слова printf

нач

если не подключена stdio.h то вывод сообщения и выход

все

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

проверка совпадения кол-ва переменных и кол-ва ‘%f’

если ошибка в синтаксисе то обработка ошибки с кодом 8

выход

все

запоминаем начало форматной строки и начало переменных

цикл от начала форматной строки до ‘”’ или конца строки

если ‘%f’ то вывод в вых поток ‘write(‘ +имя переменной+’);’

иначе

если \n то вывод ‘writeln;’

иначе

вывод ‘write(‘ + текущий символ+’);’

кц

кон

5.15 Алгоритм проверки ae2 приведен в методичке. Принцип алгоритма проверки le2 аналогичен принципу алгоритма проверки ae2;

Структура программы:

main

ReadFile

Trans

Writefile

fcomment

ferror

fwile

fPrisv

fOsk

fcSk

ffloat

fprintf

fdefine

fPrisv

fInclude

fUnion

fDo

fMain

le2

fae

Назначение основных подпрограмм

ReadFile чтение и запись в массивtext1 из исходного файла

Trans основная подпрограмма транслятор

WriteFile запись в выходной файл массиваtext2

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

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

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

CheckSk подсчет кол-ва открывающихся и закрывающихся фигурных скобок

Ffloat обработка ключевого слова float

FInclude обработка ключевого слова Include

FUnion обработка ключевого слова Union

Fdo обработка ключевого слова do

Fmain обработка ключевого слова main

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

Fdefine обработка ключевого слова define

Fwhile обработка ключевого словаwhile

FOSk обработка открывающейся операторной скобки

FCSk обработка закрывающейся операторной скобки

Fprintf обработка ключевого слова fprintf

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

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

Текст программы конвертора на ПАСКАЛЕ

{define debug}

{$M $4000,0,0}

uses crt;

Type

kwType=(kwNothing, kwOpSk, kwClSk, kwMain, kwDo, kwWhile, kwPrintf, kwDefine, kwUnion, kwInclude, kwFloat);

const

os='{Error:';

KWarray:array [kwOpSk..kwFloat] of string

=('{','}','main','do','while','printf','#define','union','#include','float');

MaxStr=100;

azbuki=['a'..'z','A'..'Z','_'];

oo=['<','>','=','!'];

signs=['+','-','/','*'];

zif=['0'..'9'];

var_symb:set of #0..#255=['a'..'z','A'..'Z','_','-','0'..'9'];

var

text1, text2:array [1..MaxStr] of string {вх и вых массивы};

kstr, kstr2{кол-во строк вх и вых},

Nstr,Npos {позиция во вх массиве},

Nstr2{Тек поз в вых мас},

kerr{к-во ошибок}:integer;

Fname1,Fname2:string; {имена файлов с путями}

f1,f2:text; {файловые переменные}

TypeComment:integer; {// - 1, /* ... */ - 2}

Ae:string[80]; {строка для ae и le}

Pf:integer; {позиция для ae и le}

Flag,def,v_open,mainflg,InclFlg,print,un:boolean; {всякие флаги}

ostr:string; {выходная строка для le}

qwe,l:integer; {еще позиция для le и длина строки}

fl:boolean; {флаг для le}

perem:array [1..20] of string; {массив переменных}

KolPer:integer; {кол-во переменных}

i:integer; {счетчик для циклов}

NUnStr:integer; {строка, в которой начинается union}

nfl:char; {номер переменной в union}

procedure CopyN(n:integer); Forward;

procedure OutStr(s:string); Forward;

procedure SkipSp; Forward;

procedure ferror(err:integer); Forward;

function IsComment:boolean; Forward;

function Fae:boolean;forward;

{=======================================================}

{=================== AE ===============}

{=======================================================}

{=======пропуск пустых символов============================}

procedure space(ert:string);

begin

while(ert[qwe]=' ')and(qwe<=length(ert))and(ert[qwe]<>';') do

inc(qwe);

end;

{=========== функция проверки знака ================}

function Znak:Boolean;

begin

Znak:=ae[pf]in ['+','-'];

end;

{======== функция проверки цифры============}

function IsDigit(ch:Char):Boolean;

begin

IsDigit:=Ch in ['0'..'9'];

end;

{=============функция проверки латинской буквы=============}

function IsAlpha(ch:char):Boolean;

begin

IsAlpha:=Ch in ['A'..'Z','a'..'z'];

end;

{===========проверка константы========================}

function Fconst:Boolean;

begin

Flag:=True;

while (pf<=Length(ae))and IsDigit(ae[pf]) do

begin

ostr:=ostr+ae[pf];

Inc(pf);

Flag:=False;

end;

if ae[pf]='.' then

begin

ostr:=ostr+ae[pf];

inc(pf);

while(pf<=length(ae)) and IsDigit(ae[pf]) do

begin

ostr:=ostr+ae[pf];

Inc(pf);

Flag:=False;

end;

end;

if Flag then

begin

Fconst:=True;

exit;

end;

if ae[pf]='E' then

begin

ostr:=ostr+ae[pf];

Inc(pf);

if Znak then

begin

ostr:=ostr+ae[pf];

Inc(pf);

end;

if not(IsDigit(ae[pf])) then

begin

Fconst:=True;

Exit;

end;

while (pf<=Length(ae)) and IsDigit(ae[pf]) do

begin

ostr:=ostr+ae[pf];

Inc(pf);

end;

end;

Fconst:=False;

end;

{=============== проверка идентификатора =================}

function Fid:Boolean;

begin

if (pf<=Length(ae)) and not IsAlpha(ae[pf]) then

begin

Fid:=True;

Exit;

end;

while (pf<=Length(ae)) and (IsAlpha(ae[pf]) or IsDigit(ae[pf])) do

begin

ostr:=ostr+ae[pf];

inc(pf);

end;

Fid:=False;

end;

{========== проверка переменной ===============}

function Fper:Boolean;

begin

if Fid then

begin

Fper:=True;

Exit;

end;

if ae[pf]='[' then

begin

repeat

ostr:=ostr+ae[pf];

inc(pf);

if Fae then

begin

Fper:=True;

Exit;

end;

until (ae[pf]<>',');

if ae[pf] <>']' then

begin

Fper:=True;

Exit;

end;

ostr:=ostr+ae[pf];

Inc(pf);

end;

Fper:=False;

end;

{============== проверка множителя =======================}

function Fmnog:Boolean;

begin

if ae[pf]='(' then

begin

ostr:=ostr+ae[pf];

Inc(pf);

if Fae then

begin

Fmnog:=True;

Exit;

end;

if ae[pf]=')' then

begin

ostr:=ostr+ae[pf];

inc(pf);

end

else

begin

Fmnog:=true;

exit;

end;

end

else

if Fper and Fconst then

begin

Fmnog:=True;

Exit;

end;

Fmnog:=False;

end;

{=========== проверка слагаемого ====================}

function Fslag:boolean;

begin

while True do

if Fmnog then

begin

Fslag:=True;

Exit;

end

else

if (ae[pf]='*')or (ae[pf]='/') then

begin

ostr:=ostr+ae[pf];

Inc(pf);

end

else

begin

Fslag:=False;

Exit;

end;

end;

{========= ae ====================}

function Fae:boolean;

begin

if Znak then

begin

ostr:=ostr+ae[pf];

Inc(pf);

end;

while True do

begin

qwe:=pf;

space(ae);

pf:=qwe;

if Fslag then

begin

Fae:=True;

Exit;

end;

if Znak then

begin

ostr:=ostr+ae[pf];

inc(pf);

end

else

begin

Fae:=False;

Exit;

end;

end;

end;

procedure go;

begin

if (pf<=l) then

begin

ostr:=ostr+ae[pf];

inc(pf);

end;

end;

function le2:boolean; forward;

{============ обработка ! ============}

function nots:boolean;

begin

if (ae[pf]='!')and(ae[pf+1]<>'=') then

begin

nots:=true;

ostr:=ostr+'not';

inc(pf);

qwe:=pf;

while(ae[qwe]=' ')and(qwe<=length(ae))and(ae[qwe]<>';') do inc(qwe);

pf:=qwe;

exit;

end

else

begin

nots:=false;

exit;

end;

end;

{============= обработка || ===========================}

function ors:boolean;

begin

qwe:=pf;

while(ae[qwe]=' ')and(qwe<=length(ae))and(ae[qwe]<>';') do inc(qwe);

pf:=qwe;

if ((ae[pf]='|')and(ae[pf+1]='|')) then

begin

pf:=pf+2;

qwe:=pf;

while(ae[qwe]=' ')and(qwe<=length(ae))and(ae[qwe]<>';') do inc(qwe);

pf:=qwe;

if (ae[pf]='(')or(ae[pf]in azbuki)or(ae[pf]='!') then

begin

ostr:=ostr+' or ';

ors:=true;

fl:=false;

qwe:=pf;

while(ae[qwe]=' ')and(qwe<=length(ae))and(ae[qwe]<>';') do inc(qwe);

pf:=qwe;

exit;

end

else

begin

ostr:=os+'нет 1 операнда для || : "'+ae+'"}';

ors:=false;

exit;

end;

end

else

ors:=false;

end;

{=========== обработка && ================}

function ands:boolean;

begin

qwe:=pf;

while(ae[qwe]=' ')and(qwe<=length(ae))and(ae[qwe]<>';') do inc(qwe);

pf:=qwe;

if ((ae[pf]='&') and (ae[pf+1]='&')) then

begin

inc(pf,2);

qwe:=pf;

while(ae[qwe]=' ')and(qwe<=length(ae))and(ae[qwe]<>';') do inc(qwe);

pf:=qwe;

if (ae[pf]='(')or(ae[pf]in azbuki)or(ae[pf]='!') then

begin

ostr:=ostr+' and ';

ands:=true;

qwe:=pf;

while(ae[qwe]=' ')and(qwe<=length(ae))and(ae[qwe]<>';') do inc(qwe);

pf:=qwe;

exit;

end

else

begin

ostr:=os+'нет 1 операнда для && : "'+ae+'"}';

ands:=false;

exit;

end;

end

else

ands:=false;

end;

{========== проверка знака сравнения ====================}

function ooo:boolean;

begin

qwe:=pf;

while(ae[qwe]=' ')and(qwe<=length(ae))and(ae[qwe]<>';') do inc(qwe);

pf:=qwe;

if (ae[pf] in oo) then

begin

ooo:=false;

if (ae[pf]='=') and (ae[pf+1]='=') then

begin

ostr:=ostr+'=';

inc(pf,2);

end

else

if ae[pf+1] in oo then

begin

if (ae[pf]='!')and(ae[pf+1]='=')then

begin ostr:=ostr+'<>'; inc(pf,2); end

else

begin

ostr:=ostr+ae[pf]+ae[pf+1];

inc(pf,2);

end

end

else

begin

go;

qwe:=pf;

while(ae[qwe]=' ')and(qwe<=length(ae))and(ae[qwe]<>';') do inc(qwe);

pf:=qwe;

exit;

end

end

else

ooo:=true;

end;

{=============== функция проверки:знак ли текущий символ ========}

function sign:boolean;

begin

if (pf<=l) then

begin

if (ae[pf] in signs) then sign:=true

else sign:=false;

end;

end;

{=========== проверка слагаемого ===========================}

function slag1:boolean;

begin

if ae[pf]='(' then

begin

go;

if fl then fl:=false;

while (ae[pf]<>')')and(pos(os,ostr)=0)do

begin

if (not le2) and (pf<l)then

begin

slag1:=false;

if (pos(os,ostr)=0) and (ae[pf]<>')')or (pf=l) then

begin write(ae[pf],pf);

ostr:=os+'нет ")" : "'+ae+'"}';

exit;

end

else if ae[pf]=')' then

begin

slag1:=true;

go;

exit;

end;

end

else

if pf=l then exit;

end;

end

else

begin

slag1:=false;

exit;

end;

end;

{============== функция проверки:цифра ли текущий символ ============}

function consta:boolean;

begin

if (pf<=l) then

begin

if (ae[pf]in zif)and not(ae[pf+1]in azbuki) then

begin

consta:=true;

go;

end

else if (ae[pf]in zif) then

begin

consta:=false;

ostr:=os+'идентификатор начинается с цифры:: "'+ae+'"}';

exit;

end;

end;

end;

{==========================================}

function es1:boolean;

begin

if (not ors and (pos(os,ostr)=0))and

(not ands and (pos(os,ostr)=0))and

(not nots and (pos(os,ostr)=0))then

begin

es1:=false;

exit;

end

else

es1:=true;

end;

{================= проверка на букву ===================}

function alpha:boolean;

begin

if (pf<=l) then

begin

if (ae[pf] in azbuki) then alpha:=true

else alpha:=false;

end;

end;

{========== le ====================}

function le2:boolean;

begin

l:=length(ae);

while (pos(os,ostr)=0) and(pf<=l)and (ae[pf]<>';')do{пока не ошибка и не `;`}

begin

if (slag1 or es1)and (pos(os,ostr)=0)then le2:=true

else if not(consta or sign) then go

else if not(ooo) then le2:=true

else

if Fae then

begin

le2:=false; {то ошибка и выход из функции}

exit;

end

else

le2:=true;

end;

end;

{======= проверка "(" ===== TRUE - OK ============}

function IsOSk:boolean;

begin

if text1[nstr,npos]='(' then

IsoSk:=true

else

IsoSk:=false;

end;

{======= проверка ")" ===== TRUE - OK ============}

function IsCSk:boolean;

begin

if text1[nstr,npos]=')' then

IscSk:=true

else

IscSk:=false;

end;

{======= проверка ";" ===== TRUE - OK ============}

function IsTz:boolean;

begin

if text1[nstr,npos]=';' then

Istz:=true

else

Istz:=false;

end;

{=========== Обработка откр фиг ск ===============}

Procedure fOpSk;

begin

if un then exit;

inc(nstr2);

inc(kstr2);

OutStr('Begin');

npos:=npos+1;

SkipSp;

if npos<=length(text1[nstr]) then

ferror(1);

end;

{=========== Обработка закр фиг ск ============}

Procedure fClSk;

begin

if un then exit;

inc(nstr2);

inc(kstr2);

OutStr('End');

npos:=npos+1;

if nstr=kstr then

OutStr('.')

else

OutStr(';');

SkipSp;

if npos<=length(text1[nstr]) then

ferror(1);

end;

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

function fPrisv:boolean;

var i,kol_prisv,kol_tz:integer;

begin

if pos('=',text1[nstr])>0 then

begin

fPrisv:=true;

inc(nstr2);

inc(kstr2);

i:=npos; kol_prisv:=0; kol_tz:=0;

while i<=length(text1[nstr]) do

begin

if text1[nstr,i]='=' then inc(kol_prisv);

if text1[nstr,i]=';' then inc(kol_tz);

inc(i);

end;

if (kol_prisv>1)or(kol_tz<>1) then begin

ferror(13);

exit;

end;

ae:=copy(text1[nstr],npos,pos('=',text1[nstr])-npos);

pf:=1;

if fper or (pf<=length(ae)) then

begin

ferror(13);

exit;

end;

copyn(pos('=',text1[nstr])-npos);

SkipSp;

inc(npos);

SkipSp;

ae:=copy(text1[nstr],npos,pos(';',text1[nstr])-npos);

pf:=1;

if fae or (pf<=length(ae)) then

begin

ferror(13);

exit;

end;

OutStr(':=');

copyn(pos(';',text1[nstr])-npos);

outstr(';');

inc(npos);

skipsp;

if npos<=length(text1[nstr]) then

ferror(1);

end

else

begin

fPrisv:=false;

exit;

end;

end;

{=========== Обработка "main" ===============}

Procedure fMain;

begin

mainflg:=true;

npos:=npos+4;

SkipSp;

if IsOSk then

npos:=npos+1

else

begin

inc(nstr2);

inc(kstr2);

fError(5);

exit;

end;

SkipSp;

if IsCSk then

npos:=npos+1

else

begin

inc(nstr2);

inc(kstr2);

fError(5);

exit;

end;

skipsp;

if npos<=length(text1[nstr]) then

begin

inc(nstr2);

inc(kstr2);

ferror(1);

end;

end;

{=========== Обработка "do" ===============}

Procedure fDo;

begin

inc(nstr2);

inc(kstr2);

Outstr('repeat');

npos:=npos+2;

skipsp;

if npos<=length(text1[nstr]) then

ferror(1);

end;

{=========== Обработка "while" ===============}

Procedure fWhile;

begin

inc(nstr2);

inc(kstr2);

npos:=npos+5;

skipsp;

if IsOSk then inc(npos) else

begin

ferror(7);

exit;

end;

SkipSp;

ae:=text1[nstr]; pf:=npos;

ostr:='';

if le2 then;

npos:=pf;

SkipSp;

if IsCSk then inc(npos) else

begin

ferror(7);

exit;

end;

SkipSp;

if not IsTz then

begin

ferror(7);

exit;

end;

OutStr('until not('+ostr+');');

inc(npos);

skipsp;

if npos<=length(text1[nstr]) then

ferror(1);

end;

{=========== Обработка "printf" ===============}

Procedure fPrintf;

var

np:integer;

begin

ostr:='';

inc(nstr2);

inc(kstr2);

if not InclFlg then

begin

inc(kerr);

OutStr('{Error: Function "printf" should have a prototype}');

exit;

end;

inc(npos,6);

skipsp;

if IsOSk then inc(npos) else

begin

ferror(8);

exit;

end;

skipsp;

if text1[nstr,npos]='"' then inc(npos) else

begin

ferror(8);

exit;

end;

while (text1[nstr,npos]<>'"') and

(npos<=length(text1[nstr])) do inc(npos);

if npos>length(text1[nstr]) then

begin

ferror(8);

exit;

end else inc(npos,2);

np:=npos;

repeat

skipsp;

while text1[nstr,npos] in var_symb do inc(npos);

skipsp;

if (text1[nstr,npos]=',') and (text1[nstr,npos+1]<>')') then inc (npos);

until IsCSk or (npos>length(text1[nstr]));

if (npos>length(text1[nstr]))or not(iscsk) then

begin

ferror(8);

exit;

end;

inc(npos);

skipsp;

if not istz then

begin

ferror(8);

exit;

end else inc(npos);

skipsp;

if npos<=length(text1[nstr]) then

ferror(1);

{========= обработка ==============}

npos:=pos('"',text1[nstr])+1;

print:=false;

while text1[nstr,npos]<>'"' do

begin

if pos('%f',copy(text1[nstr],npos,length(text1[nstr])-npos+1)) = 1 then

begin

if print then

begin

print:=false;

outstr(chr(39)+'); ');

end;

inc(npos,2);

ostr:='write(';

while (text1[nstr,np]<>',')

and(text1[nstr,np]<>')')

and (np<=length(text1[nstr]))

and (text1[nstr,np]<>';') do

begin

ostr:=ostr+text1[nstr,np];

inc(np);

end;

if length(ostr)=length('write(') then

begin

ferror(8);

exit;

end

else

ostr:=ostr+'); ';

inc(np);

end else

if pos('\n',copy(text1[nstr],npos,length(text1[nstr])-npos+1)) = 1 then

begin

if print then

begin

print:=false;

outstr(chr(39)+'); ');

end;

ostr:='writeln; ';

inc(npos,2);

end

else

begin

if not print then

begin

ostr:='write('+chr(39)+text1[nstr,npos];

inc(npos);

print:=true;

end else

begin

ostr:=text1[nstr,npos];

inc(npos);

end;

end;

Outstr(ostr);

end;

if text1[nstr,np] in var_symb then ferror(8);

end;

{=========== Обработка "#define" ===============}

Procedure fDefine;

begin

inc(nstr2);

inc(kstr2);

if not def then

begin

outstr('const');

inc(nstr2);

inc(kstr2);

end;

npos:=npos+7;

skipsp;

while text1[nstr,npos]<>' ' do copyn(1);

outstr(' = '+chr(39));

skipsp;

copyn(length(text1[nstr])-npos+1);

outstr(chr(39)+';');

def:=true;

end;

{=========== Обработка "union" ===============}

Procedure fUnion;

begin

un:=true;

inc(nstr2);

inc(kstr2);

if not v_open then

begin

outstr('var');

inc(nstr2);

inc(kstr2);

v_open:=true;

end;

NUnStr:=nstr2;

inc(nstr2);

inc(kstr2);

end;

{=========== Обработка "#include" ===============}

Procedure fInclude;

begin

npos:=npos+8;

SkipSp;

if text1[nstr,npos]='<' then inc(npos) else begin

ferror(11);

exit;

end;

if (pos('>',text1[nstr])>0)

and (pos('>',text1[nstr])-pos('<',text1[nstr])<=12) then

npos:=pos('>',text1[nstr])+1 else begin

ferror(11);

exit;

end;

SkipSp;

if npos<=length(text1[nstr]) then begin

ferror(11);

exit;

end;

if pos('stdio.h',text1[nstr])>0 then InclFlg:=true;

end;

{=========== Обработка "float" ===============}

Procedure fFloat;

var i,j:integer;

er:boolean;

str:string;

begin

er:=true;

inc(nstr2);

inc(kstr2);

if un then begin

outstr(nfl+':(');

inc(nfl);

end;

if not v_open then

begin

outstr('var');

inc(nstr2);

inc(kstr2);

end;

npos:=npos+5;

skipsp;

i:=npos;

while (npos<=length(text1[nstr])) and (text1[nstr,npos] in var_symb) do inc(npos);

skipsp;

if IsTz then

begin

npos:=i;

str:=copy(text1[nstr],npos,pos(';',text1[nstr])-npos);

j:=1;

while (j<=kolper)and(perem[j]<>str) do inc(j);

if j>KolPer then

begin

KolPer:=KolPer+1;

Perem[KolPer]:=Str;

copyn(pos(';',text1[nstr])-npos);

if not un then

Outstr(':real;')

else

Outstr(':real);');

er:=false;

end

end

else

if text1[nstr,npos]='[' then

begin

inc(npos);

skipsp;

while IsDigit(text1[nstr,npos]) do inc(npos);

skipsp;

if text1[nstr,npos]=']' then

begin

inc(npos);

if text1[nstr,npos]=';' then

begin

npos:=i;

str:='';

while (text1[nstr,npos] in var_symb) do

begin

str:=str+text1[nstr,npos];

inc(npos);

end;

j:=1;

while (j<=kolper)and(perem[j]<>str) do inc(j);

if j>KolPer then

begin

KolPer:=KolPer+1;

Perem[KolPer]:=Str;

npos:=pos('[',text1[nstr])+1;

OutStr(str);

outstr(':array [1..');

copyn(pos(']',text1[nstr])-npos);

if not un then

outstr('] of real;')

else

Outstr('] of real);');

if pos(']',text1[nstr])-pos('[',text1[nstr])<>1 then er:=false;

end;

end;

end;

end;

if er then ferror(12);

v_open:=true;

end;

{=========== проверка к-ва открывающихся и закрывающихся скобок

============= TRUE - ошибка ====================================}

function CheckSk:boolean;

var i,j, nopen, nclose:integer;

begin

nopen:=0; nclose:=0;

for nstr:=1 to kstr do

for j:=1 to length(text1[nstr]) do

if text1[nstr,j]='{' then

nopen:=nopen+1

else

if text1[nstr,j]='}' then

nclose:=nclose+1;

if nopen=nclose then

CheckSk:=false

else

CheckSk:=true;

nstr:=1;

end;

{===============================================================}

{===================== распознавание ключевого слова ===========}

{===============================================================}

function kw:kwType;

begin

kw:=kwNothing;

if (pos(kwArray[kwOpSk], text1[nstr])=npos) then

kw:=kwOpSk

else

if (pos(kwArray[kwClSk], text1[nstr])=npos) then

kw:=kwClSk

else

if (pos(kwArray[kwMain], text1[nstr])=npos)

then

begin

if (text1[nstr,npos+length(kwArray[kwMain])]=' ')

or

(text1[nstr,npos+length(kwArray[kwMain])]='(')

or

(text1[nstr,npos+length(kwArray[kwMain])]=chr(0)) then

kw:=kWMain;

end

else

if (pos(kwArray[kwDo], text1[nstr])=npos)

then

begin

if (text1[nstr,npos+length(kwArray[kwDo])]=' ') or

(text1[nstr,npos+length(kwArray[kwDo])]=chr(0)) then

kw:=kWDo;

end

else

if (pos(kwArray[kwWhile], text1[nstr])=npos)

then

begin

if (text1[nstr,npos+length(kwArray[kwWhile])]=' ')

or

(text1[nstr,npos+length(kwArray[kwWhile])]='(')

or

(text1[nstr,npos+length(kwArray[kwWhile])]=chr(0)) then

kw:=kWWhile;

end

else

if (pos(kwArray[kwprintf], text1[nstr])=npos)

then

begin

if (text1[nstr,npos+length(kwArray[kwprintf])]=' ')

or

(text1[nstr,npos+length(kwArray[kwprintf])]='(')

or

(text1[nstr,npos+length(kwArray[kwprintf])]=chr(0)) then

kw:=kWprintf;

end

else

if (pos(kwArray[kwdefine], text1[nstr])=npos)

then

begin

if (text1[nstr,npos+length(kwArray[kwdefine])]=' ')

or

(text1[nstr,npos+length(kwArray[kwdefine])]='(')

or

(text1[nstr,npos+length(kwArray[kwdefine])]=chr(0)) then

kw:=kWdefine;

end

else

if (pos(kwArray[kwUnion], text1[nstr])=npos)

then

begin

if (text1[nstr,npos+length(kwArray[kwUnion])]=' ')

or

(text1[nstr,npos+length(kwArray[kwUnion])]='(')

or

(text1[nstr,npos+length(kwArray[kwUnion])]=chr(0)) then

kw:=kWUnion;

end

else

if (pos(kwArray[kwInclude], text1[nstr])=npos)

then

begin

if (text1[nstr,npos+length(kwArray[kwInclude])]=' ')

or

(text1[nstr,npos+length(kwArray[kwInclude])]='(')

or

(text1[nstr,npos+length(kwArray[kwInclude])]=chr(0)) then

kw:=kWInclude;

end

else

if (pos(kwArray[kwFloat], text1[nstr])=npos)

then

if (text1[nstr,npos+length(kwArray[kwFloat])]=' ')

or

(text1[nstr,npos+length(kwArray[kwFloat])]='(')

or

(text1[nstr,npos+length(kwArray[kwFloat])]=chr(0)) then

kw:=kWFloat;

end;

{====================== проверка начала коментария ==============}

function IsComment:boolean;

begin

IsComment:=false;

if pos('/*', text1[nstr])=npos then

begin

IsComment:=true;

TypeComment:=2;

npos:=npos+2;

end

else

if pos('//', text1[nstr])=npos then

begin

IsComment:=true;

TypeComment:=1;

npos:=npos+2;

end;

end;

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

procedure fComment;

begin

inc(nstr2);

inc(kstr2);

outstr('{');

if TypeComment=1 then

begin

copyn(length(text1[nstr])-npos+1);

outstr('}');

end

else

begin

if pos('*/',text1[nstr])=0 then ferror(3);

copyn(pos('*/',text1[nstr])-npos);

npos:=pos('*/',text1[nstr])+2;

outstr('}');

skipsp;

if npos<=length(text1[nstr]) then ferror(1);

end;

end;

{===================================================}

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

{===================================================}

procedure ferror(err:integer);

begin

{Список ашипак:

1: после оператора есть символы

2: Количество открывающихся скобок не соответствует к-ву закрывающихся

3: На строке N',nstr,' не найден конец коментария!

4: неопознанный идентификатор и не присваивание

Ашипки в операторах:

5: MAIN

7: WHILE

8: PRINTF

10:UNION

11:#INCLUDE

12:FLOAT

13: Присваивание

}

case err of

1:begin

OutStr('{Error: После оператора есть символы "');

copyn(length(text1[nstr])-npos+1);

OutStr('"}');

end;

2:begin

writeln('Количество "{" не соответствует к-ву "}"');

writeln('Program aborted!!!');

halt;

end;

3:begin

writeln('На строке N',nstr,' не найден конец коментария!');

writeln('Program aborted!!!');

halt;

end;

4:begin

inc(nstr2);

inc(kstr2);

OutStr('{Error: неизвестный оператор "');

CopyN(length(text1[nstr]));

OutStr('"}');

end;

5:begin

OutStr('{Error: ошибка в main: "');

OutStr(text1[nstr]);

OutStr('"}');

end;

6:begin

end;

7:begin

OutStr('{Error: ошибка в while: "');

OutStr(text1[nstr]);

OutStr('"}');

end;

8:begin

text2[nstr2]:='{Error: ошибка в printf: "'+text1[nstr]+'"}';

end;

9:begin

end;

11:begin

inc(nstr2);

inc(kstr2);

text2[nstr2]:='{Ошибка в include: "'+text1[nstr]+'"}';

end;

12:begin

text2[nstr2]:='{Ошибка в float: "'+text1[nstr]+'"}';

end;

13:begin

text2[nstr2]:='{Ошибка в присваивании: "'+text1[nstr]+'"}';

end;

end;

kerr:=kerr+1;

end;

{======= запись в выходной поток строки s ============}

procedure OutStr(s:string);

begin

text2[nstr2]:=text2[nstr2]+s;

end;

{============ Копирование n символов и сдвиг курсора ================}

procedure CopyN(n:integer);

begin

text2[nstr2]:=text2[nstr2]+copy(text1[nstr],npos,n);

npos:=npos+n;

end;

{===================== пропуск пробелов ============================}

procedure SkipSp;

begin

while (text1[Nstr,Npos]=' ')

and

(npos<=length(text1[Nstr]))

do inc(npos);

end;

{===================== чтение файла в массив ============================}

procedure readfile;

var ch:char;

begin

{$ifndef debug}

writeln('Имя файла с путем: ');

readln(Fname1);

{$else}

Fname1:='F:\KURSOVIK\1.c';

{$endif}

assign(f1,FName1 );

{$i-}

reset(f1);

{$i+}

if IoResult<>0 then

begin

writeln('Файл '+fname1+' не найден.');

Writeln('Press any key to continue.');

ch:=readkey; Halt;

end;

kstr:=0;

while not eof(f1) do

begin

inc(kstr);readln(f1,text1[kstr]);

end;

close(f1);

end;

{================== запись массива в файл ============================}

procedure writefile;

var

i:integer;

ch:char;

begin

{$ifndef debug}

writeln('Укажите имя выходного файла:');

readln(Fname2);

{$else}

Fname2:='F:\KURSOVIK\1.PAS';

{$endif}

assign(f2,Fname2);

{$i-}

rewrite(f2);

{$i+}

if IoResult<>0 then

begin

writeln('Файл',Fname2,'не найден .Повторите ввод.');

ch:=readkey; Halt;

end;

for i:=1 to kstr2 do

begin

writeln(f2,Text2[i]);

end;

writeln ('Число ошибочных операторов: ',kerr);

writeln('Число строк в исходном файле: ',kstr);

writeln('Число строк в выходном файле: ', kstr2);

close(f2);

end;

{============================================================}

{===================== основная процедура ===================}

{============================================================}

procedure trans;

var i,j:integer;

begin

for i:=1 to kstr do text2[i]:='';

if CheckSk then ferror(2);

while nstr<=kstr do

begin

npos:=1;

SkipSp;

if npos<=length(text1[nstr]) then

if IsComment then

fComment

else

if Kw<>kwNothing then

case kw of

kwOpSk:fOpSk;

kwClSk:fClSk;

kwMain:fMain;

kwDo:fDo;

kwWhile:fWhile;

kwPrintf:fPrintf;

kwDefine:fDefine;

kwUnion:fUnion;

kwInclude:fInclude;

kwFloat:fFloat;

end

else

if not fPrisv then

if un then

begin

text2[NUnStr]:=copy(text1[nstr],npos,pos(';',text1[nstr])-npos);

text2[NUnStr]:=text2[NUnStr]+':record';

text2[NUnStr+1]:=' case integer of';

inc(nstr2);

inc(kstr2);

Outstr('end;');

un:=false;

end

else

fError(4);

inc(nstr);

end;

if not mainflg then

Writeln('В исходной программе на C нет функции main!!!');

end;

{main}

begin

clrscr;

kstr:=0; kerr:=0; Nstr:=1; Npos:=1; Nstr2:=0; Kstr2:=0;

def:=false; mainflg:=false; v_open:=false; InclFlg:=false;

KolPer:=0; un:=false; nfl:='0';

readfile;

trans;

writefile;

end.

  1. Распечатка тестового примера и его трансляции

#include <stdio.h>

#define test test_new

#define test2 test_new2

float mas[20];

float per;

float per1[8];

union

{

float cvar3;

float un_array[10];

}

var_union;

main()

{

per=4+34.8+1E-3;

mas[1]=2;

per1[3]=1.4;

//COMMENTS... zzzzzzzzz

/*comment2*/

do

{

per=per-2.3;

do

{

per=per+2;

printf("per= %f\n",per);

}

while (per<-1.2E12/(56*3));

}

while (!(per<7));

{

}

}

Соседние файлы в папке 20_var_kurs