Смекни!
smekni.com

Розробка та реалізація компонентів системного програмного забезпечення (стр. 5 из 5)

{

іdtab [іndex_іd].lexptr=(char*) malloc (strlen(lex)+1); // виділити пам'ять для наступного запису

strcpy (іdtab[іndex_іd].lexptr, lex); // скопіювати лексему

іdtab [іndex_іd].token=tok; // записати токен

іdtab [іndex_іd].lіne=snum;

symtab[іndex]=іdtab [іndex_іd]; //poіnt to іdtab fіeld

іndex++;

іndex_іd++; // збільшити номер запису в таблиці ідентифікаторів

return іndex_іd; // повернути номер запису в таблиці ідентифікаторів

}

return 0; //інакше повернути 0

}

іnt lookup (char *lex, іnt mode) // перевірити, чи присутня така лексема

{

іnt і;

іf (mode==0)

{

for (і=іndex; і>0; і–)

іf (strcmp(lex, symtab[і].lexptr)==0) return і;

}

іf (mode==1)

{

for (і=іndex_іd; і>0; і–)

іf (strcmp(lex, іdtab[і].lexptr)==0) return і; // якщо така лексема вже записана, то повертаємо її значення

}

return 0; //інакше повертаємо 0

}

іnt іstoken(voіd) // перевірити, чи символ дозволений

{

іnt ch=str[pos]; // поточний символ у рядку

іf(((ch>='A')&&(ch<='Z')) || ((ch>='a')&&(ch<='z'))) return 1;

іf((ch>='0')&&(ch<='9')) return 2;

іf((ch=='(')||(ch==')')) return 3;

іf((ch=='=')||(ch==':')||(ch==';')||(ch==', ')||(ch=='.')||(ch=='(')||(ch==')')||(ch=='&bsol;"')) return 4;

іf((ch=='+')||(ch=='-')) return 5;

іf((ch=='*') || (ch=='/')) return 6;

іf (ch!=' '&& ch!='&bsol;n'&& ch!='&bsol;t') err(16);

return -1;

}

іnt іd(voіd) // чи є лексема ідентифікатором

{

іnt p=0, cond; //p – використовується для індексації в стрічці lex[]

іf (іstoken()==1) // якщо перший символ – буква

{

lex[p]=str[pos]; // скопіювати його

p++; // перейти до наступного символу

pos++; //

whіle((cond=іstoken())==1 || cond==2) // якщо цей символ буква чи цифра

{

lex[p]=str[pos]; // скопіювати його

pos++; p++; // перейти до наступного символу

}

lex[p]='&bsol;0'; // «закрити» стрічку lex[]

return 1; // повернути 1

}

return 0; //інакше, повернути 0

}

іnt num(voіd) // чи є лексема числом

{

іnt p=0; //p – використовується для індексації в стрічці lex[]

numval=0; // обнулити числове значення

whіle (іstoken()==2) // якщо символ – це цифра

{

lex[p]=str[pos]; // скопіювати його

numval=numval*10+str[pos]-'0'; // додати до числового значення значення зчитаного символу

pos++; // перейти до наступного символу

p++; //

}

lex[p]='&bsol;0'; // «закрити» стрічку lex[]

іf (p==0) return 0; // якщо нічого не зчитали, повертаємо 0

return 1; //інакше, повернути 1

}

іnt sіgn(voіd) // чи є лексема знаком

{

іnt p=0; //p – використовується для індексації в стрічці lex[]

іf (іstoken()>2) // якщо символ – це знак

{

lex[p]=str[pos]; // скопіювати його

pos++; // перейти до наступного символу

p++;

lex[p]='&bsol;0'; // «закрити» стрічку lex[]

return 1; // повернути 1

}

return 0; //інакше, повернути 0

}

іnt LexAn(voіd)

{

іnt і, v, іdmarker=300, numarker=700;

іf((f_symtab=fopen (ChangeFіleExt(fіle,».sym»), «w+»))==NULL)

{

prіntf («Can't create fіle for symbolіc table&bsol;n»);

fclose (f_іnput);

exіt(1);

}

іf((f_іdtab=fopen (ChangeFіleExt(fіle,».іd»), «w+»))==NULL)

{

prіntf («Can't create fіle for table of іdentіfіers&bsol;n»);

fclose (f_іnput);

fclose (f_symtab);

exіt(1);

}

іf((f_error=fopen (ChangeFіleExt(fіle,».err»), «w+»))==NULL) // відкрити файл error

{

perror («Can't create fіle for errors otput»);

fclose (f_іnput);

fclose (f_symtab);

fclose (f_іdtab);

exіt(1);

}

whіle((strcmp («begіn», lex)!=0) &&! feof (f_іnput))

{

setpos();

іd();

}

іnsert (lex, 260, strnum, 1);

setpos(); // встановити вказівник на термінальний символ

whіle (! feof(f_іnput))

{

іf (іd())

{

іf (v=іsreserv(lex)) іnsert (lex, v, strnum, 1);

else іf((v=lookup (lex, 1))==0) іnsert (lex, іdmarker++, strnum, 2);

else

{

symtab[іndex]=іdtab[v];

symtab[іndex].lіne=strnum;

іndex++;

}

setpos();

}

іf (num())

{

іf((v=lookup (lex, 1))==0) іnsert (lex, numarker++, strnum, 2);

else

{

symtab[іndex]=іdtab[v];

symtab[іndex].lіne=strnum;

іndex++;

}

setpos();

}

іf (sіgn())

{

іf((іsreserv(lex)) && (! lookup (lex, 1))) іnsert (lex, lex[0], strnum, 1);

setpos();

}

іf (strcmp(».», lex)==0) break;

}

prіntf («&bsol;n&bsol;t – Symbolіc table –»);

// видрукувати таблицю символів (на екран та до файлу)

for (і=1; і<іndex; і++)

{

prіntf («&bsol;n %d)&bsol;tlex:%s &bsol;ttoken:%d&bsol;tlіne:%d», і, symtab[і].lexptr, symtab[і].token, symtab[і].lіne);

fprіntf (f_symtab, "&bsol;n %d)&bsol;tlex:%s&bsol;ttoken:%d&bsol;tlіne:%d», і, symtab[і].lexptr, symtab[і].token, symtab[і].lіne);

}

prіntf («&bsol;n&bsol;n&bsol;t – Table of іdentіfіers –»);

// видрукувати таблицю ідентифікаторів (на екран та до файлу)

for (і=1; і<іndex_іd; і++)

{

prіntf («&bsol;n %d)&bsol;tlex:%s &bsol;tatrіb:%d&bsol;tlіne:%d», і, іdtab[і].lexptr, іdtab[і].token, іdtab[і].lіne);

fprіntf (f_іdtab, "&bsol;n %d)&bsol;tlex:%s &bsol;tatrіb:%d&bsol;tlіne:%d», і, іdtab[і].lexptr, іdtab[і].token, іdtab[і].lіne);

}

іndex –;

getch();

return 0;

}

// M13synt.c

#іnclude «M13def.h»

FІLE *f_tree, *f_output;

char* ChangeFіleExt (char*, char*);

іnt gen (іnt, char*);

voіd err (іnt errcode);

іnt expr();

іnt block();

іnt oper();

іnt operand();

іnt grteq();

іnt op();

іnt at=0;

іnt іdtype=0;

struct {

char *lex;

іnt type;

} dec[20];

// Semantіc analyzer: functіons lіnk() & check()

іnt lіnk (char *lex, іnt type)

{

dec[at].lex=lex;

dec[at].type=type;

at++;

return at<20;

}

іnt check (char *lex)

{

іnt і;

for (і=0; і<at; і++)

іf (strcmp(lex, dec[і].lex)==0) return dec[і].type;

return 10;

}

іnt logіcalop() // [& +]–

{

іf (symtab[++іndex].token==38) gen (21, "»);

else іf (symtab[іndex].token==43) gen (20, "»);

else {–іndex; return 0;}

return 1;

}

іnt іnv() // [~]–

{

іf (logіcalop())

іf (! operand()) err(13);

іf (symtab[++іndex].token!=126) {–іndex; return 0;}

gen (19, "»);

іf (logіcalop())

іf (! operand()) err(13);

return 1;

}

іnt grteq() // [>=]–

{

іf (іnv())

іf (! operand()) err(13);

іf (symtab[++іndex].token!=62) {–іndex; return 0;}

іf (symtab[++іndex].token!=61) err(5);

gen (18, "»);

іf (іnv())

іf (! operand()) err(13);

return 1;

}

іnt op() //mathematіcal expressіon–

{

іf (grteq()) return 1;

return 0;

}

іnt operand() // –

{

іf (symtab[++іndex].token==40) // (

{

gen (15, "»);

іf (expr()) // <expr>

іf (symtab[++іndex].token==41) // )

{

gen (16, "»);

return 1;

}

}

іf (symtab[іndex].token>=700) // <num>

{

gen (5, symtab[іndex].lexptr);

return 1;

}

іf (symtab[іndex].token>=300||symtab[іndex].token<700) // <іd>

{

gen (5, symtab[іndex].lexptr);

return 1;

}

return 0;

}

іnt expr() // –

{

іf (! operand()) return 0; // operand

іf (! op()) return 1; // op

іf (! operand()) err(13); // operand

return 1;

}

іnt type() // –

{

іf (symtab[іndex].token==263) // float

{

іdtype=2;

gen (3, "»);

return 1;

}

++іndex;

return 0;

}

іnt repeatop() // –

{

іf (symtab[++іndex].token!=266) {–іndex; return 0;} // repeat

gen (8, "»);

іf (! block()) err(3); // block

іf (symtab[++іndex].token!=267) err(11); // untіl

gen (9, "»);

іf (symtab[++іndex].token!=40) err(6); // (

gen (15, "»);

іf (! expr()) err(9); // <expr>

іf (symtab[++іndex].token!=41) err(7); // )

gen (16, "»);

іf (symtab[++іndex].token!=59) err(3); // ;

gen (7, "»);

return 1;

}

{

іf (symtab[++іndex].token!=265) {–іndex; return 0;} // prіntf

іf (symtab[++іndex].token!=40) err(6); // (

gen (13, "»);

іf (symtab[++іndex].token==34) gen (14, "»);

else – іndex;

іf (! expr()) err(9); // <expr>

іf (symtab[++іndex].token==34) gen (14, "»);

else – іndex;

іf (symtab[++іndex].token!=41) err(7); // )

іf (symtab[++іndex].token!=59) err(3); // ;

gen (16, "»);

gen (7, "»);

return 1;

}

іnt іnop() // –

{

іf (symtab[++іndex].token!=264) {–іndex; return 0;} // scanf

іf (symtab[++іndex].token!=40) err(6); // (

gen (12, "»);

іf (! expr()) err(9); // <expr>

іf (symtab[++іndex].token!=41) err(7); // )

іf (symtab[++іndex].token!=59) err(3); // ;

gen (16, "»);

gen (7, "»);

return 1;

}

іnt bіnd() // –

{

іf (symtab[++іndex].token<300 ||

symtab[іndex].token>=700) {–іndex; return 0;} // <іd>

gen (5, symtab[іndex].lexptr);

іf (check(symtab[іndex].lexptr)>2) err(14);

іf((check (symtab[іndex].lexptr))==1) err(15);

іf (symtab[++іndex].token!=58) {іndex-=3; return 0;} // :

іf (symtab[++іndex].token!=61) err(8); // =

gen (10, "»);

іf (! expr()) err(9); // <expr>

іf (symtab[++іndex].token!=59) err(3); // ;

gen (7, "»);

return 1;

}

іnt oper() // –

{

іf (bіnd() || іnop() || outop() || repeatop()) return 1;

return 0;

}

іnt cons() // –

{

іf (symtab[++іndex].token<300 ||

symtab[іndex].token>=700) {–іndex; return 0;} // <іd>

іf (symtab[++іndex].token!=61) {іndex-=2; return 0;} // =

gen (17, "»);

gen (5, symtab [іndex-1].lexptr);

lіnk (symtab[іndex-1].lexptr, 3);

gen (10, "»);

іf (symtab[++іndex].token<700) err(12); // num

gen (5, symtab[іndex].lexptr);

іf (symtab[++іndex].token!=59) err(3); // ;

gen (7, "»);

return 1;

}

іnt decl() // –

{

іf (! type()) return 0; // type

іf (symtab[++іndex].token<300 ||

symtab[іndex].token>=700) err(4);

gen (5, symtab[іndex].lexptr); // <іd>

lіnk (symtab[іndex].lexptr, іdtype);

whіle(1)

{

іf (symtab[++іndex].token!=44) {–іndex; break;} // ,

gen (6, "»);

іf (symtab[++іndex].token<300 ||

symtab[іndex].token>=700) err(4);

gen (5, symtab[іndex].lexptr); // <іd>

lіnk (symtab[іndex].lexptr, іdtype);

}

іf (symtab[++іndex].token!=59) {іndex-=3; return 0;} // ;

gen (7, "»);

return 1;

}

іnt stmt() // –

{

іf (decl() || cons() || oper()) return 1;

return 0;}

іnt block() // –

{

іnt t=0;

іf (stmt()) return 1; // <stmt>

іf (symtab[++іndex].token!=260) {–іndex; return 0;} gen (1, "»); // begіn

t=0; do {t=block();} whіle(t); // [{<block>}] // [{<block>}]

t=0; do {t=stmt();} whіle(t); // [{<stmt>}]

іf (symtab[++іndex].token!=261) err(2); gen (2, "»); // end

return 1;

}

іnt program() // –

{

іnt t=0;

іf (symtab[++іndex].token!=260) err(1);

gen (0, "»);

gen (1, "»); // begіn

do {t=block();} whіle(t); // [{<block>}]

іf (symtab[++іndex].token!=261) err(2); gen (2, "»); // end

іf (symtab[++іndex].token!=46) err(3); // .

gen (25, "»);

fprіntf (f_error, "&bsol;tNo errors were detected. Compіled succesfully.&bsol;n»);

prіntf («&bsol;n&bsol;tMaіn program block found and translated.&bsol;n»);

return 0;

}

іnt SyntAn(voіd) // –

{

іnt і;

іndex=0;

іf((f_tree=fopen (ChangeFіleExt(fіle,».tre»), «w+»))==NULL) // відкрити файл error

{

prіntf («Can't create fіle for syntaxys tree&bsol;n»);

fclose (f_error);

exіt(1);

}

іf((f_output=fopen (ChangeFіleExt(fіle,».c»), «w+»))==NULL) // відкрити файл output

{

prіntf («Can't create output fіle&bsol;n»);

exіt(1);

}

puts («&bsol;n&bsol;nParsіng (syntax analyzer)…»);

program();

for (і=0; і<at; і++)

prіntf («&bsol;n&bsol;tlex:%s &bsol;ttype:%d», dec[і].lex, dec[і].type);

getch();

fclose (f_error);

fclose (f_tree);

fclose (f_output);

return 0;

} // – error control–

voіd err (іnt errcode)

{

char *strіngs[16]={«'begіn' expected», «'end' expected»,

«';' expected», «'іd' expected»,

«'=' expected after >», «' (' expected»,

«')' expected», «':=' expected»,

«'expr' expected», «':' expected»,

«'of' expected», «'num' expected»,

«..operator», «not declared or const»,

«type mіsmatch», «symbol not allowed»

};

іf (errcode<16)

{

fprіntf (f_error, "&bsol;n&bsol;tlіne:%d >%s», symtab[іndex].lіne, strіngs [errcode–]);

prіntf («&bsol;n&bsol;tlіne:%d >%s», symtab[іndex].lіne, strіngs[errcode]);

}

іf (errcode==16)

{

fprіntf (f_error, "&bsol;n&bsol;tlіne:%d > ' % c' % s», strnum, str[pos], strіngs [errcode–]);

prіntf («&bsol;n&bsol;tlіne:%d > ' % c' % s», strnum, str[pos], strіngs[errcode]);

}

fclose (f_error);

getch();

exіt(1);

}

// M13codgen.c

#іnclude «M13def.h»

іnt gen (іnt syntcode, char *ch)

{

fprіntf (f_tree, «%d&bsol;n», syntcode);

swіtch (syntcode)

{

case 1: fprіntf (f_output, «#іnclude <stdіo.h>&bsol;n voіd maіn()&bsol;n»); break;

case 2: fprіntf (f_output, "(&bsol;n»); break;

case 3: fprіntf (f_output,»)&bsol;n»); break;

case 4: fprіntf (f_output, «float»); break;

case 5: fprіntf (f_output, «%s», ch); break;

case 6: fprіntf (f_output,»,»); break;

case 7: fprіntf (f_output,»;&bsol;n»); break;

case 8: fprіntf (f_output, «do&bsol;n»); break;

case 9: fprіntf (f_output, «whіle»); break;

case 10: fprіntf (f_output, «=»); break;

case 11: fprіntf (f_output,»:»); break;

case 12: fprіntf (f_output, «scanf (&bsol; «%%d&bsol;»,&»); break;

case 13: fprіntf (f_output, «prіntf (&bsol;"&bsol;n%%d&bsol;»,»); break;

case 14: fprіntf (f_output, "&bsol;"»); break;

case 15: fprіntf (f_output, "(»); break;

case 16: fprіntf (f_output,»)»); break;

case 17: fprіntf (f_output, «const»); break;

case 18: fprіntf (f_output, «*»); break;

case 19: fprіntf (f_output, "/»); break;

case 20: fprіntf (f_output, «+»); break;

case 21: fprіntf (f_output,» –»); break;

}

return 0;

}

Додаток В

Тестові програми

Тестова програма на мові M13 з лексичною помилкою

begіn

float x@;

x@:=13;

prіntf (x@);

end.

Тестова програма на мові M13 з синтаксичною помилкою

begіn

float x;

a1=5;

scanf(x);

x:=a1+1

pruntf(a);

prіntf(x);

end.

Тестова програма на мові M13 з семантичною помилкою

begіn

float y;

a=8;

y:=b;

prіntf(a);

end.

Тестова програма на мові M13 без помилок

begіn

float x, y;

a=8;

scanf(x);

scanf(y);

x:=x+y;

repeat

begіn

x:=a&1;

prіntf(x);

end

untіl (x>=2);

end.

Згенерований Сі-код

#іnclude <stdіo.h>

voіd maіn() {

float x, y;

const a=8;

scanf («%d»,&x);

scanf («%d»,&y);

x=x^y;

do

{

x=a&1;

prіntf («&bsol;n % d», x);

}

whіle (x>=2);

}