Littel example how work compiler
Delphi & Pascal (česká wiki)
Category: Programs in C, C++
Program: Compiler.c
File exe: Compiler.exe
need: Klavesy.h, Struct.h
Example: Prog.c
Program: Compiler.c
File exe: Compiler.exe
need: Klavesy.h, Struct.h
Example: Prog.c
Littel example how work compiler. It's a easy compiler. You only locate syntax error, don't translate to bin code. IDE is know from common work with C compiler.
// 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); }