/* ignores character case */ a [aA] b [bB] c [cC] d [dD] e [eE] f [fF] g [gG] h [hH] i [iI] j [jJ] k [kK] l [lL] m [mM] n [nN] o [oO] p [pP] q [qQ] r [rR] s [sS] t [tT] u [uU] v [vV] w [wW] x [xX] y [yY] z [zZ] %{ #include "token.h" #define MAX_LENGTH 20000 #define PRIME 997 struct hash_item { int index; struct hash_item *next; }; struct hash_item *hash_table[PRIME]; char string_buff[MAX_LENGTH]; int string_index; %} int yycolumn=1; int yyline=1; int yyval; %% ";" {yycolumn+=yyleng; return(SEMInumber); } ":"/[^=] {yycolumn+=yyleng; return(COLONnumber); } "," {yycolumn+=yyleng; return(COMMAnumber); } "."/[^.] {yycolumn+=yyleng; return(DOTnumber); } "("/[^*] {yycolumn+=yyleng; return(LPARENnumber); } ")" {yycolumn+=yyleng; return(RPARENnumber); } "<"/[^=>] {yycolumn+=yyleng; return(LTnumber); } ">"/[^=] {yycolumn+=yyleng; return(GTnumber); } "=" {yycolumn+=yyleng; return(EQnumber); } "-" {yycolumn+=yyleng; return(MINUSnumber); } "+" {yycolumn+=yyleng; return(PLUSnumber); } "*" {yycolumn+=yyleng; return(TIMESnumber); } ".." {yycolumn+=yyleng; return(DOTDOTnumber); } ":=" {yycolumn+=yyleng; return(COLEQnumber); } "<=" {yycolumn+=yyleng; return(LEnumber); } ">=" {yycolumn+=yyleng; return(GEnumber); } "<>" {yycolumn+=yyleng; return(NEnumber); } {a}{n}{d} {yycolumn+=yyleng; return(ANDnumber); } {a}{r}{r}{a}{y} {yycolumn+=yyleng; return(ARRAYnumber); } {b}{e}{g}{i}{n} {yycolumn+=yyleng; return(BEGINnumber); } {c}{o}{n}{s}{t}{a}{n}{t} {yycolumn+=yyleng; return(CONSTnumber); } {d}{i}{v} {yycolumn+=yyleng; return(DIVIDEnumber); } {d}{o}{w}{n}{t}{o} {yycolumn+=yyleng; return(DOWNTOnumber); } {e}{l}{s}{e} {yycolumn+=yyleng; return(ELSEnumber); } {e}{l}{s}{i}{f} {yycolumn+=yyleng; return(ELSIFnumber); } {e}{n}{d} {yycolumn+=yyleng; return(ENDnumber); } {e}{n}{d}{i}{f} {yycolumn+=yyleng; return(ENDIFnumber); } {e}{n}{d}{l}{o}{o}{p} {yycolumn+=yyleng; return(ENDLOOPnumber); } {e}{n}{d}{r}{e}{c} {yycolumn+=yyleng; return(ENDRECnumber); } {e}{x}{i}{t} {yycolumn+=yyleng; return(EXITnumber); } {f}{o}{r} {yycolumn+=yyleng; return(FORnumber); } {f}{o}{r}{w}{a}{r}{d} {yycolumn+=yyleng; return(FORWARDnumber); } {f}{u}{n}{c}{t}{i}{o}{n} {yycolumn+=yyleng; return(FUNCTIONnumber); } {i}{f} {yycolumn+=yyleng; return(IFnumber); } {i}{s} {yycolumn+=yyleng; return(ISnumber); } {l}{o}{o}{p} {yycolumn+=yyleng; return(LOOPnumber); } {n}{o}{t} {yycolumn+=yyleng; return(NOTnumber); } {o}{f} {yycolumn+=yyleng; return(OFnumber); } {o}{r} {yycolumn+=yyleng; return(ORnumber); } {p}{r}{o}{c}{e}{d}{u}{r}{e} {yycolumn+=yyleng; return(PROCEDUREnumber); } {p}{r}{o}{g}{r}{a}{m} {yycolumn+=yyleng; return(PROGRAMnumber); } {r}{e}{c}{o}{r}{d} {yycolumn+=yyleng; return(RECORDnumber); } {r}{e}{p}{e}{a}{t} {yycolumn+=yyleng; return(REPEATnumber); } {r}{e}{t}{u}{r}{n} {yycolumn+=yyleng; return(RETURNnumber); } {t}{h}{e}{n} {yycolumn+=yyleng; return(THENnumber); } {t}{o} {yycolumn+=yyleng; return(TOnumber); } {t}{y}{p}{e} {yycolumn+=yyleng; return(TYPEnumber); } {u}{n}{t}{i}{l} {yycolumn+=yyleng; return(UNTILnumber); } {v}{a}{r} {yycolumn+=yyleng; return(VARnumber); } {w}{h}{i}{l}{e} {yycolumn+=yyleng; return(WHILEnumber); } [a-zA-Z][a-zA-Z0-9]* { yycolumn+=yyleng; yyval=hash_insert(yytext); return(IDnumber); } [0-9]+ {yycolumn+=yyleng; sscanf(yytext,"%d",&yyval); return(ICONSTnumber); } '[^'\n]* { int i,j; char c, temp[1000]; c=input(); if (c!='\'') { ReportError("unclosed string",yyline, yycolumn); unput(c); } else { unput(c); if (yytext[yyleng-1] == '\\') { yycolumn+=yyleng; i=yyleng-1; j=0; while(yytext[i]=='\\'){ i--;j++;} if (j%2 != 0) yymore(); else { input(); yycolumn+=1; if (yyleng==2) ReportError("invalid character '\'", yyline,yycolumn-2); else if (yyleng==3) { if(yytext[1]=='\\') { yyval='\\'; return(CCONSTnumber); } else { string_convert(yytext+1, temp); yyval=put_string(temp); free(temp); return(SCONSTnumber); } } else { string_convert(yytext+1, temp); yyval=put_string(temp); free(temp); return(SCONSTnumber); } } } else { input();yycolumn+=yyleng+1; if (yyleng==2) { yyval=yytext[1]; return(CCONSTnumber); } else if (yyleng==3) { if (yytext[1]=='\\') { switch(yytext[2]) { case 'n' : yyval='\n'; return(CCONSTnumber); case 't' : yyval='\t'; return(CCONSTnumber); case '\'' : yyval='\''; return(CCONSTnumber); default : string_convert(yytext+1, temp); yyval=put_string(temp); free(temp); return(SCONSTnumber); } } else { string_convert(yytext+1, temp); yyval=put_string(temp); free(temp); return(SCONSTnumber); } } else { string_convert(yytext+1, temp); yyval=put_string(temp); free(temp); return(SCONSTnumber); } } } } "(*" { char c; int column,line; column=yycolumn;line=yyline; yycolumn+=yyleng; c=input(); do{ while(((c)!='*') && (c!=0)) { if (c=='\n') { yycolumn=0;yyline++; }else if (c=='\t') { yycolumn+=8; }else yycolumn+=1; c=input(); } c=input(); }while((c!=0) && (c!=')')); yycolumn+=1; if (c==0) ReportError("unclosed comment",line,column); } \n { yyline++;yycolumn=0; } \t yycolumn+=8; " " yycolumn+=1; . {char temp[80]; yycolumn+=1; sprintf(temp, "invalid character '%s'",yytext); ReportError(temp,yyline,yycolumn); } %% ReportError(message,line,column) char *message; int line, column; { printf("\nError: %s \tline %d column %d\n\n",message,line,column); } string_convert(s,s1) char *s, *s1; { char *t1,*t2; t1=s; t2=s1; while (*t1 != '\0') { if (*t1 != '\\') { *t2=*t1; } else { switch (*(t1+1)) { case 'n' : t1++; *t2='\n'; break; case 't' : t1++; *t2='\t'; break; case '\\' : t1++; *t2='\\'; break; case '\'' : t1++; *t2='\''; break; default : *t2=*t1; } } t1++;t2++; } *t2='\0'; } /* hash function */ int hashf(s) char *s; { char *p; unsigned h=0,g; for(p=s; *p!='\0'; p++) { h = (h << 4) + (*p); if (g=h&0xf0000000) { h = h ^ (g >>24); h = h^g; } } return(h % PRIME); } /* change the string to uppercase */ toupper(s,s1) char *s,*s1; { char *p,*p1; p=s; p1=s1; while(*p!='\0') { if ((*p>='a') && (*p<='z')) *p1= *p+'A'-'a'; else *p1= *p; p++; p1++; } *p1='\0'; } /* init all data type */ lex_init() { int i,j,k; for(i=0; iindex, temp) == 0) i=0; else p1=p1->next; } if (p1==NULL) { /* new item */ p1=(struct hash_item *)malloc(sizeof(struct hash_item)); p1->index=string_index; strcpy(string_buff+string_index,temp); string_index+=strlen(temp)+1; p1->next=hash_table[index]; hash_table[index]=p1; } free(temp); return(p1->index); } int find_index(s) char *s; /* string to be find */ { int i,j,k; int index; char *temp; struct hash_item *p1; temp=(char *)malloc(strlen(s)+1); toupper(s,temp); index=hashf(temp); p1=hash_table[index]; i=1; while ((p1!=NULL) && i) { if (strcmp(string_buff+p1->index, temp) == 0) i=0; else p1=p1->next; } free(temp); if (p1 == NULL) return(-1); else return(p1->index); } int put_string(s) char *s; { strcpy(string_buff+string_index,s); string_index+=strlen(s)+1; return(string_index-strlen(s)-1); }