Program ktorý demoštruje ako funguje compiler
Delphi & Pascal (česká wiki)
Kategória: Programy v C, C++
Program: Compiler.c
Súbor exe: Compiler.exe
Potrebné: Klavesy.h, Struct.h
Príklady: Prog.c
Program: Compiler.c
Súbor exe: Compiler.exe
Potrebné: Klavesy.h, Struct.h
Príklady: Prog.c
Program ktorý demoštruje ako funguje compiler. Má IDE prostredie so všetkými potrebnými funkciami. Program vie odhaliť syntaktické chyby programu nevie kompilovať do exe tvaru. Zdrojový kód ktorý kompiluje je akási obdoba Pascalu.
// COMPILER.C Copyright (c) TrSek alias Zdeno Sekerak // Program je pokusom o vlastny compiler s podobnou syntaxou // ako ma Pascal. // // Datum:22.04.96 http://www.trsek.com #define maxx 78 #define maxz 21 #include "klavesy.h" #include <stdio.h> #include <conio.h> #include <dos.h> #include <bios.h> #include <string.h> #include <dir.h> #include <errno.h> #include <alloc.h> #define maxx 78 #define maxy 21 #define maxs 128 #define maxznak 128 #define maxsyn 14 #define maxerr 30 #define maxkl 17 #define maxpocs 256 #include "struct.h" char klslov[maxkl+1][maxsyn] = { {"DECL"} , {"INTEGER"} , {"START"} , {"WHILE"} , {"ENDWHILE"} , {"INTEGERREAD"} , {"INTEGERWRITE"} , {"STOP"} , {" "} , {";"} , {":="} , {"("} , {")"} , {"<"} , {">"} , {"+"} , {":"} }; void okno (int, int, int, int, int, int ); /* Definuj okno posledne dve su farby */ /* podklad, pismo */ void editor ( void ); /* Uvodna obrazovka */ void tprintf( char text[]); /* Specialny prvy riadok */ void farba(int x,int y); /* nastavi naraz farbu pisma aj podkladu */ void posunx ( int ); /* Posun text v smere osi x */ void posuny ( int ); /* Posun text v smere osi y */ void deletuj ( int, int ); /* Zmaz znak z poziciou */ void novyr ( int ); /* Novy riadok */ int posledny ( int ); /* Posledny znak v riadku */ void strana ( int, int ); /* Vykresli stranu */ void help ( void ); /* No comment */ void save ( char meno[] ); /* Uloz subor pod menom */ int vypis_sub( char mena[][13], int dlzok ); /* Vypis suborov do okna */ int load ( void ); /* Najdi subor */ int from_disk( char subor[]); /* Precitaj subor z disku */ void run ( void ); /* Spusti program */ void outwin ( void ); /* Pozri OUTPUT obrazovku */ void compile ( void ); /* Skompiluj program */ void option ( void ); /* Opsns */ def_riadok *zaradr( def_riadok *pointer, char text[] ); /* Zaradi text do pola */ def_riadok *vyhodr( def_riadok *pointer ); /* Vyhodi text z pola */ int otazka ( char text[], char pr[], char dr[], char tr[] ); /* Otazka , pr-prva volba, dr-druha volba */ int kluc_slova ( def_syntax * (* syntax) ); /* Doplni klucove slova */ int patri ( char s[] , int x , int *v_rade , void *prvys , int caka ); /* Porovnava dve retazce */ int podmienka ( char s[] , int x , def_syntax *prvys); int aritmetika ( char s[] , int x , void *prvys); /* Je to aritmetika ??? Nie !!!*/ int premenne (int *x, char s[], def_syntax *syntax); /* doplni premenne do syntax */ int comp,pocr; /* pocet riadkov suboru */ char subor[maxs]; /* Meno suboru */ void *prvy,*teraz; /* Pameta pointer na prvy riadok */ // main tu to vsetko zacne void main(int arg, char *args[]) { int key,i; int x=1,y=1,xr=1,yr=1; unsigned insert=0,ulozene=0; editor(); prvy=NULL; pocr=0; comp=0; if (arg>0) { strcpy(subor,args[1]); from_disk(subor); strana(1,1); } gotoxy(x,y); do { key=getch(); if (key==BACKSPACE) {} // nereaguje if (key==0) { key=getch(); switch (key) { case LEFT: x=x-1; if (x<1) { xr--;x=1; if (xr<1) xr=1; else strana(xr,yr); } break; case RIGHT: x=x+1; if (x>maxx) { xr++;x=maxx-3; if ((xr+x)>maxznak) xr=maxznak-x; strana(xr,yr); } break; case UP: y=y-1; if (y<1) { y=1; yr--; if (yr<1) yr=1; strana(xr,yr); } break; case DOWN: y=y+1; if (y>maxy) { y=maxy; yr=yr+1; if ((yr+y)>pocr) { yr=pocr-maxy-y-1; if (yr<1) yr=1; } strana(xr,yr); } break; case ENTER: x=1;y=y+1;novyr(y);posunx(0); break; case DEL: deletuj(x,y); break; case INSERT:insert=!insert; break; case HOME: x=1; break; case END: x=posledny(yr+y-1); xr=1; if (x>maxx) { xr=x-maxx; x=maxx-3; strana(xr,yr); } break; case PGDN: yr=yr+maxy; if ((yr+y)>pocr) { for (i=pocr;i<=(yr+y);i++) novyr(i); yr=pocr-20; } strana(xr,yr); break; case PGUP: yr=yr-maxy; if (yr<1) yr=1; strana(xr,yr); break; case F1: help(); break; case F2: save(subor); break; case F3: load(); window(2,3,79,23); clrscr(); strana(1,1); break; case F4: save(""); break; case F5: if (!comp) compile(); run(); break; case F6: outwin(); break; case F7: break; case F8: option(); break; case F9: compile(); break; case F10: if (!ulozene) { if (otazka("Ulozit prave editovany subor ?"," ^Ano "," ^Nie ","")==1) save(subor); else key=0; } if (key==0) if (otazka(" Chces skoncit ? "," ^Ano "," ^Nie ","")==1) key=F10; break; default: break; } gotoxy(x,y); } } while (key!=F10); clrscr(); } // zobrazi okno v ktorom sa budeme pohybovat void okno (int x1, int y1, int x2, int y2, int col1, int col2 ) { int x,y; window(x1,y1,x1+x2,y1+y2); farba(col2,col1); clrscr(); gotoxy(1,y2);cprintf("Č"); gotoxy(x2+1,y2);cprintf("ź"); gotoxy(1,1);insline(); gotoxy(1,1);cprintf("É"); gotoxy(x2+1,1);cprintf("ť"); for (x=2;x<=x2;x++) { gotoxy(x,1);cprintf("Í"); gotoxy(x,y2+1);cprintf("Í"); } for (y=2;y<=y2;y++) { gotoxy(1,y);cprintf("ş"); gotoxy(x2+1,y);cprintf("ş"); } window(x1+1,y1+1,x1+x2-1,y1+y2-1); } // nakresli prostredie editora void editor( void ) { okno(1,2,79,22,BLUE,YELLOW); window(1,1,80,25); gotoxy(1,1); textbackground(LIGHTGRAY); tprintf("^F^1Help ^F^2Save ^F^3LOAD ^F^4SAVE_AS ^F^5RUN ^F^6OUTWIN ^F^7STEP ^F^8OPTION ^F^9COMPILE ^F^1^0EXIT"); window(2,3,79,24); } // vypise text s tym ze pismena zacinajuce ^ vyfarby inou farbou void tprintf( char text[]) { int i; textcolor(DARKGRAY); for (i=0; i<strlen(text); i++) { if (text[i]!='^') { if (text[i-1]=='^') textcolor(RED); else textcolor(BLACK); cprintf("%c",text[i]); } } textcolor(YELLOW); } // nastavi naraz farbu pisma aj podkladu void farba(int x,int y) { textcolor(x); textbackground(y); } void posunx ( int xp ) { xp=xp; } void posuny ( int yp ) { yp=yp; } void deletuj ( int xd, int yd ) { xd=xd; yd=yd; } void novyr ( int yr ) { yr=yr; } // najde posledny znak v retazci int posledny ( int yp ) { int xp=1; int y=1; def_riadok *priadok; if (prvy==NULL) return(0); priadok=prvy; while(( priadok != NULL ) && (y<yp)) { priadok=( * priadok).zani; y=y+1; } // je mimo text if (priadok == NULL ) return(xp); // najde koniec riadku while ((( * priadok).znaky[xp]!='\0') && (xp<maxznak)) xp++; return(xp); } // zobrazi subor od x,y suradnic void strana ( int xs, int ys ) { int x,y; def_riadok *priadok; textbackground(BLUE); priadok=prvy; // prechod na poziciu for (y=1; y<ys; y++) if (priadok!=NULL) priadok= (*priadok).zani; window(2,3,79,23); clrscr(); // for (y=0; y<21 && priadok!=NULL; y++) { for (x=xs; x<xs+78 && x<strlen((*priadok).znaky) ;x++) { gotoxy(x-xs+1,y+1); cprintf("%c",(*priadok).znaky[x]); } priadok = (*priadok).zani; } } void help ( void ) { } // ulozi subor void save ( char meno[] ) { meno=meno; } // vypise obsah adresara // dlzok znamena od akeho suboru sa ma zacat int vypis_sub(char mena[][13], int dlzok) { struct ffblk subory; int yp=-1; int i; errno=0; findfirst("*.*",&subory,FA_ARCH|FA_DIREC|FA_RDONLY|FA_HIDDEN); // najprv vsetky vyhlada while ((errno==0) && (yp<maxpocs)) { strcpy(mena[++yp],subory.ff_name); // subory prekonvertujem na male pismena if ((subory.ff_attrib & FA_DIREC) == 0) for (i=0; i<strlen(mena[yp]); i++) if (mena[yp][i]!='.') mena[yp][i]=mena[yp][i]+32; findnext(&subory); } // teraz ich vsetky vypisem for( i=0; i<dlzok && i<yp; i++ ) { gotoxy(3,i+1); cprintf("%s",mena[i]); } return(yp); } // precita program zo suboru int load ( void ) { int dlzok=12; int y=0, yr=0, yp=0; char mena[maxpocs+1][13]; char key; yp=0; yp=yp; yr=0; yr=yr; /* Potom ma zrus */ okno(15,3,18,dlzok+1,LIGHTGRAY,DARKGRAY); yp=vypis_sub(mena,dlzok); farba(YELLOW,BLUE); gotoxy(3,1); cprintf("%s",mena[0]); y=0; key=32; do { key=getch(); farba(DARKGRAY,LIGHTGRAY); gotoxy(3,y+1); cprintf("%s",mena[y+yr]); switch (key) { case 0: key=getch(); switch (key) { case UP: y=y-1; if (y<0) { y=0; yr=yr-1; if (yr<0) yr=0; else { gotoxy(1,1); insline(); } } break; case DOWN: y=y+1; if (y>yp) y=yp; if (y>(dlzok-1)) { y=dlzok-1; yr=yr+1; if ((yr+y)>yp) yr=yp-y; else { gotoxy(1,1); delline(); } } break; } break; case ENTER: if ((mena[y+yr][0]=='.') || ((mena[y+yr][0]>='A') && (mena[y+yr][0]<='Z'))) { chdir(mena[y+yr]); clrscr(); yp=vypis_sub(mena,dlzok); y=1; yr=0; key=32; } break; } farba(YELLOW,BLUE); gotoxy(3,y+1); cprintf("%s",mena[y+yr]); } while ((key!=ESC) && (key!=ENTER)); if (key==ENTER) strcpy(subor,mena[y+yr]); if (key==ESC) return(0); // precitaj subor return( from_disk(subor)); } // precita z disku int from_disk( char subor[] ) { FILE *fopen(),*f; int y,err=0; char text[maxznak]; riadok=prvy; prvy=NULL; while ( riadok!=NULL) riadok=vyhodr(riadok); pocr=0; f=fopen(subor,"r"); do { pocr++; y=0; text[y]=' '; do { err=fscanf(f,"%c",&text[++y]); } while ((text[y]!='\n') && (err==1) && (y<maxznak-2) && (text[y]!='\0')); text[y]='\0';text[y+1]='\n'; riadok=zaradr(riadok,text); if (prvy==NULL) prvy=riadok; } while ((err==1) && (riadok!=NULL)); fclose(f); if (riadok==NULL) { y=otazka(" Nemas dost pamete na editaciu suboru !!! "," ^ENTER ","",""); while ( riadok!=NULL) riadok=vyhodr(riadok); return(0); } return(1); } void run ( void ) { } void outwin ( void ) { } int patri ( char s[] , int x , int *v_rade , void * prvys , int caka ) { def_syntax *syntax; int i,x1; syntax=prvys; i=0;*v_rade=0; if (caka!=-1) while (*v_rade<caka) { *v_rade=*v_rade+1; syntax=(*syntax).zani; } while ( (s[x+i]==' ') && (s[x+i]!='\0')) i++; x1=x+i;i=0; if (x1>=strlen(s)) { *v_rade=-1; return(x1); } if (caka==-1) while ( (i<strlen((*syntax).znaky) ) && ( (*syntax).zani!=NULL) ) { i=0; *v_rade=*v_rade+1; if (*v_rade!=1) syntax=(*syntax).zani; while ( (i<strlen((*syntax).znaky)) && ((*syntax).znaky[i]==s[x1+i])) i=i+1; if ((s[x1+i]!=' ') && (s[x1+i]!='\0') && (*v_rade<8)) i=0; } else { while ((i<strlen((*syntax).znaky)) && ((*syntax).znaky[i]==s[x1+i])) i=i+1; } if (i==strlen((*syntax).znaky)) { while ( (s[x1+i]==' ') && (s[x1+i]!='\0')) i++; return(x1+i-1); } else { *v_rade=0; return(x1); } } int aritmetika ( char s[] , int x , void *prvys ) { def_syntax *syntax; syntax=prvys; x=x;s=s; return(0); } // odskusane funguje OK int premenne (int *x, char s[], def_syntax *syntax) { int i; char prem[10]; i=0; while ((s[*x+i]!=';') && (strlen(s)>*x+i) ) { while (s[*x+i]==' ') i++; *x=*x+i; i=0; while ( (s[*x+i]>='A') && (s[*x+i]<='z') ) { prem[i]=s[*x+i];i++; } prem[i]='\0'; syntax=zarads(syntax,prem); while ( (s[*x+i]==',') || (s[*x+i]==' ') ) i++; } *x=*x+i; if (s[*x]==';') return(0); else return(1); } int podmienka ( char s[] , int x , def_syntax *prvys ) { def_syntax *syntax; syntax=prvys; x=x;s=s; return(0); } void compile ( void ) { def_riadok *riadok; def_syntax *posled; def_error *error; void *prvys; int poc,x,y,caka,i,v_rade,oldi; char chyba[maxerr]; syntax=NULL; error =NULL; riadok=prvy; for (poc=0; poc<maxkl; poc++) { syntax=zarads(syntax,klslov[poc]); if (poc==0) prvys=syntax; } posled=syntax; syntax=prvys; v_rade=-1; caka=0; oldi=0; for (y=1;y<=pocr;y++) { x=1; if ((i=patri( (*riadok).znaky,x,&v_rade,prvys,caka)) >x) x=i; else { if (caka==-1) error=zarade(error,"Nepoznam",y); else error=zarade(error,klslov[caka],y); v_rade=caka; } if ((caka==-1) && (v_rade>maxkl)) caka=10; if (v_rade==9) caka=-1; if (v_rade==10) if ((i=aritmetika( (*riadok).znaky,x,posled)) >x) { x=i;caka=9; } else error=zarade(error,klslov[caka],y); if (v_rade==11) if ((i=podmienka( (*riadok).znaky,x,posled)) >x) { x=i;caka=12; } else error=zarade(error,klslov[caka],y); if ((v_rade==6) || (v_rade==7)) if ((i=patri( (*riadok).znaky,x,&v_rade,posled,caka))>x) { x=i;caka=9; } else error=zarade(error,klslov[caka],y); if (v_rade==3) caka=11; if (v_rade==2) caka=-1; if (v_rade==1) { i=premenne( &x,(*riadok).znaky,posled); if (i!=0) error=zarade(error,"Zle definovanie premennych.",y); i=oldi+1; caka=2; } if (v_rade==0) caka=1; if (x>=strlen( (*riadok).znaky)-1 ) { riadok=(*riadok).zani;oldi=-1; } if (i==oldi) y=pocr; oldi=i; } if (v_rade!=7) error=zarade(error,klslov[7],y); if (error==NULL) comp=1; } // nastavenia void option ( void ) { } // polozi otazku a caka odpoved Ano/Nie int otazka ( char text[], char pr[], char dr[], char tr[]) { int vo=0,odx,i,x; char pdt[3][10]; int cpdt[3]; char ch; strcpy(pdt[0],pr); strcpy(pdt[1],dr); strcpy(pdt[2],tr); if ((strlen(text)/2)!=(1.00*strlen(text)/2)) text=strcat(text," "); odx=(80-strlen(text))/2-4; okno(odx,10,strlen(text)+8,6,LIGHTGRAY,DARKGRAY); gotoxy(5,2);cprintf("%s",text); cpdt[0]=(strlen(text)-odx-strlen(pdt[0])+strlen(pdt[1])+strlen(pdt[2])+8)/2+4; cpdt[1]=cpdt[0]+strlen(pdt[0])+2; cpdt[2]=cpdt[0]+strlen(pdt[0])+strlen(pdt[1])+4; for (i=0;i<=2;i++) { gotoxy(cpdt[i],4); tprintf(pdt[i]); } textbackground(GREEN); gotoxy(cpdt[0],4);tprintf(pdt[0]); odx=0; vo=-1; do { ch=getch(); textbackground(LIGHTGRAY); gotoxy(cpdt[odx],4);tprintf(pdt[odx]); switch (ch) { case 0: ch=getch(); switch (ch) { case LEFT : odx=odx-1; if (odx<0) odx=2;break; case RIGHT: odx=odx+1; if (odx>2) odx=0;break; } if ((odx==2) && (strcmp(pdt[2],"")==0)) odx=0; if ((odx==1) && (strcmp(pdt[1],"")==0)) odx=0; break; case ESC: vo=0; break; case ENTER: vo=odx+1; break; default : for (i=0;i<=2;i++) for (x=1;x<=strlen(pdt[i]);x++) if ((pdt[i-1][x]=='^') && (pdt[i][x]==ch)) vo=i; break; } textbackground(GREEN); gotoxy(cpdt[odx],4);tprintf(pdt[odx]); } while (vo==-1); return(vo); }