#include #include #include "stable.h" #include "cgram.h" #include "tokens.h" int nspace; /* # of bytes left in block */ char *spacep; /* start of free space block */ SYMB *symbs; /* head offree symb list */ SYMB *symbols; char *calloc(int,int); SYMB * getsymb(char *str){ SYMB *sp; int i; if((sp=symbs)==0){ symbs=sp=(SYMB *)calloc(STSIZE,sizeof(SYMB)); for(i=STSIZE-1 ; i>0 ; i--){ sp->left= &sp[1]; /* initialize as a link list */ sp=sp->left; } sp=symbs; } symbs=symbs->left; sp->left=0; i=strlen(str); if(i>nspace){ spacep=calloc(1,1024); nspace=1024; } strcpy(spacep,str); sp->name=spacep; spacep+=i; nspace-=i; return(sp); } SYMB **symtp; SYMB * find(SYMB *p, char *cp){ int i; while(1){ i=strcmp(cp,p->name); if(i==0)return(p); symtp= (i<0 ? &p->left : &p->right); if(*symtp == (SYMB *)0)return(0); p= *symtp; } } char *kwords[] = { "if","int","char","float","else","continue","case", "return","while","break","for","switch","default","do",0}; int kwordn[] = { IF,INT,CHAR,FLOAT,ELSE,CONTINUE,CASE, RETURN,WHILE,BREAK,FOR,SWITCH,DEFAULT,DO,0}; char *ops="=<>+-&|!*/%^~?:,;()[]{}"; int retval[] = {ASG,LT,GT,PLUS,MINUS,BAND,BOR,LNOT,AST,DIV,MOD,BXOR, BNOT,QUEST,COLON,COMMA,SEMI,LPAR,RPAR,LBRK,RBRK,LBRC,RBRC}; int retdval[] = {EQU,SHL,SHR,INC,DEC,LAND,LOR}; int lineno=1; yylex(){ char c,*cp; int i; SYMB *sp; char temp[80]; int retv; while(isspace(c=getchar())) if(c=='\n')lineno++; if(c==EOF)return (EOF); i=((int)strchr(ops,c))-(int)ops; if(i>=0){ yylval=retval[i]; if(i>11)return(yylval); c=getchar(); if((c==ops[i]) && (i<7)){ yylval=retdval[i]; if(i!=1 && i!=2)return(yylval); c=getchar(); } if(c!='='){ ungetc(c,stdin); return(yylval); } return(++yylval); } if(isalpha(c)){ cp=temp; *cp++ =c; while(isalnum(c=getchar()) || c=='_') *cp++ = c; ungetc(c,stdin); *cp=0; for(i=0 ; kwords[i] ; i++) if(!strcmp(temp,kwords[i]))return(kwordn[i]); symtp= &symbols; sp=(SYMB *)0; if(*symtp)sp=find(*symtp,temp); if(sp==(SYMB *)0) *symtp=sp=getsymb(temp); yylval=(int)sp; return(ID); } } #if 0 int yylval; main(){ int i; while((i=yylex())!=EOF){ if(i==0)continue; printf("%s",tokens[i]); switch(i){ case CONST: printf(" - %d\n",yylval); break; case STR: case ID: printf(" - %s\n",((SYMB *)yylval)->name); break; default: printf("\n"); break; } } } yyerror(char *str){ fprintf(stderr,"Error: %s on line %d\n",str,lineno); } #endif