#ifndef NORSCID static char rcs_lex[] = "$Header$" ; #endif /* This file contains the new lexical analizer */ typedef struct { char *name; int token, classvalue,length; } Key; Key keywords [] ={ "abs", FUNCTION, ABSSYM, 0, "and", BOOLOP, ANDSYM, 0, "asc", FUNCTION, ASCSYM, 0, "as", ASSYM, 0, 0, "atn", FUNCTION, ATNSYM, 0, "auto", ILLEGAL, 0, 0, "base", BASESYM, 0, 0, "call", CALLSYM, 0, 0, "cdbl", FUNCTION, CDBLSYM, 0, "chain", ILLEGAL, 0, 0, "chr", FUNCTION, CHRSYM, 0, "cint", FUNCTION, CINTSYM, 0, "clear", CLEARSYM, 0, 0, "cload", ILLEGAL, 0, 0, "close", ILLEGAL, 0, 0, "common", ILLEGAL, 0, 0, "cont", ILLEGAL, 0, 0, "cos", FUNCTION, COSSYM, 0, "csng", FUNCTION, CSNGSYM, 0, "csave", ILLEGAL, 0, 0, "cvi", FUNCTION, CVISYM, 0, "cvs", FUNCTION, CVSSYM, 0, "cvd", FUNCTION, CVDSYM, 0, "data", DATASYM, 0, 0, "defint", DEFINTSYM, 0, 0, "defsng", DEFSNGSYM, 0, 0, "defdbl", DEFDBLSYM, 0, 0, "defstr", DEFSTRSYM, 0, 0, "def", DEFSYM, 0, 0, "delete", ILLEGAL, 0, 0, "dim", DIMSYM, 0, 0, "edit", ILLEGAL, 0, 0, "else", ELSESYM, 0, 0, "end", ENDSYM, 0, 0, "eof", FUNCTION, EOFSYM, 0, "eqv", BOOLOP, EQVSYM, 0, "erase", ILLEGAL, 0, 0, "error", ERRORSYM, 0, 0, "err", ERRSYM, 0, 0, "erl", ERLSYM, 0, 0, "exp", FUNCTION, EXPSYM, 0, "field", FIELDSYM, 0, 0, "fix", FUNCTION, FIXSYM, 0, "for", FORSYM, 0, 0, "fre", FUNCTION, FRESYM, 0, "get", GETSYM, 0, 0, "gosub", GOSUBSYM, 0, 0, "goto", GOTOSYM, 0, 0, "hex", FUNCTION, HEXSYM, 0, "if", IFSYM, 0, 0, "imp", BOOLOP, IMPSYM, 0, "inkey", INKEYSYM, 0, 0, "input", INPUTSYM, 0, 0, "inp", FUNCTION, INPSYM, 0, "instr", FUNCTION, INSTRSYM, 0, "int", FUNCTION, INTSYM, 0, "kill", ILLEGAL, 0, 0, "left", FUNCTION, LEFTSYM, 0, "len", FUNCTION, LENSYM, 0, "let", LETSYM, 0, 0, "line", LINESYM, 0, 0, "list", LISTSYM, 0, 0, "llist", ILLEGAL, 0, 0, "load", LOADSYM, 0, 0, "loc", FUNCTION, LOCSYM, 0, "log", FUNCTION, LOGSYM, 0, "lpos", FUNCTION, LPOSSYM, 0, "lprint", ILLEGAL, 0, 0, "lset", LSETSYM, 0, 0, "merge", MERGESYM, 0, 0, "mid", MIDSYM, 0, 0, "mki", FUNCTION, MKISYM, 0, "mks", FUNCTION, MKSSYM, 0, "mkd", FUNCTION, MKDSYM, 0, "mod", MODSYM, 0, 0, "name", ILLEGAL, 0, 0, "new", ILLEGAL, 0, 0, "next", NEXTSYM, 0, 0, "not", NOTSYM, 0, 0, "null", ILLEGAL, 0, 0, "on", ONSYM, 0, 0, "oct", FUNCTION, OCTSYM, 0, "open", OPENSYM, 0, 0, "option", OPTIONSYM, 0, 0, "or", BOOLOP, ORSYM, 0, "out", FUNCTION, OUTSYM, 0, "peek", PEEKSYM, 0, 0, "poke", POKESYM, 0, 0, "print", PRINTSYM, 0, 0, "pos", FUNCTION, POSSYM, 0, "put", PUTSYM, 0, 0, "randomi", RANDOMIZESYM, 0, 0, "read", READSYM, 0, 0, "rem", REMSYM, 0, 0, "renum", ILLEGAL, 0, 0, "ren", ILLEGAL, 0, 0, "restore", RESTORESYM, 0, 0, "resume", ILLEGAL, 0, 0, "return", RETURNSYM, 0, 0, "right", FUNCTION, RIGHTSYM, 0, "rnd", FUNCTION, RNDSYM, 0, "run", ILLEGAL, 0, 0, "save", ILLEGAL, 0, 0, "step", STEPSYM, 0, 0, "sgn", FUNCTION, SGNSYM, 0, "sin", FUNCTION, SINSYM, 0, "space", FUNCTION, SPACESYM, 0, "spc", FUNCTION, SPCSYM, 0, "sqr", FUNCTION, SQRSYM, 0, "stop", STOPSYM, 0, 0, "string", FUNCTION, STRINGSYM, 0, "str", FUNCTION, STRSYM, 0, "swap", SWAPSYM, 0, 0, "tab", FUNCTION, TABSYM, 0, "tan", FUNCTION, TANSYM, 0, "then", THENSYM, 0, 0, "to", TOSYM, 0, 0, "tron", TRONOFFSYM, TRONSYM, 0, "troff", TRONOFFSYM, TROFFSYM, 0, "using", USINGSYM, 0, 0, "usr", FUNCTION, USRSYM, 0, "val", FUNCTION, VALSYM, 0, "varptr", FUNCTION, VARPTRSYM, 0, "wait", ILLEGAL, 0, 0, "while", WHILESYM, 0, 0, "wend", WENDSYM, 0, 0, "width", ILLEGAL, 0, 0, "write", WRITESYM, 0, 0, "xor", BOOLOP, XORSYM, 0, 0, 0, 0, 0 }; /* Keyword index table */ int kex[27]; /* Initialize the keyword table */ fillkex() { Key *k; int i; for(k=keywords;k->name;k++) k->length= strlen(k->name); k=keywords; for(i=0;k->name && i<='z'-'a';i++) { for(;k->name && *k->namename!=i+'a') continue; kex[*k->name-'a']=k-keywords; for(;k->name && *k->name==i+'a';k++); kex[*(k-1)->name-'a'+1]=k-keywords; } if(debug) { for(i=0;i<27;i++) printf("%c:%d\n",'a'+i,kex[i]); } } #include /* Get each line separately into the buffer */ /* Lines too long are terminated and flagged illegal */ #define MAXLINELENGTH 1024 char inputline[MAXLINELENGTH]; /* current source line */ char *cptr; /* next character to decode */ int yylineno=0; /* source line counter */ getline() { /* get next input line */ if( fgets(inputline,MAXLINELENGTH,yyin) == NULL) return(FALSE); yylineno ++; if( index(inputline,'\n') == 0) error("source line too long"); inputline[MAXLINELENGTH-1]=0; if( listing) fputs(inputline,stdout); cptr= inputline; return(TRUE); } yyerror(str) char *str; { error("Syntax error"); } typechar() { switch(*cptr) { case '$': cptr++; return( STRINGTYPE); case '%': cptr++; return( INTTYPE); case '!': cptr++; return( FLOATTYPE); case '#': cptr++; return( DOUBLETYPE); } return(0); } /* symbols in Microsoft are significant for the first 40 characters */ #define SIGNIFICANT 40 char name[SIGNIFICANT+1]; lookup() { Key *k; Symbol *Sym; char *c; int i, typech; sval= name; for(c=cptr; *c && isalnum(*c);c++) if( isupper(*c) ) *c= tolower((*c)); for(k= keywords+kex[*cptr-'a']; k->name != 0 && *(k->name)== *cptr;k++) if( strncmp(cptr,k->name,k->length)==0) { /* check functions first*/ if( isalnum( *(cptr+k->length) ) && k->token==FUNCTION) continue; cptr += k->length; yylval.integer= k->classvalue; if(debug) printf("lookup:%d %d\n", k->classvalue,k->token); if( k->token == FUNCTION) { /* stripp type character */ typech=typechar(); } /* illegals + rem */ if( k->token == REMSYM || k->token==ILLEGAL) while( *cptr && *cptr!=':' && *cptr!='\n') cptr++; return( k->token); } /* Is it a function name ? */ c=cptr; /* Identifier found, update the symbol table */ i=0; while( isalnum(*c) || *c == '.') if( isymtype!=DEFAULTTYPE) { if(typech && typech!=Sym->symtype && wflag) warning("type re-declared,ignored"); } if( typech) Sym->symtype=typech; if(debug) printf("lookup:%d Identifier\n",Sym); if( (name[0]=='f' || name[0]=='F') && (name[1]=='n' || name[1]=='N') ) return(FUNCTID); return(IDENTIFIER); } /* Parsing unsigned numbers */ readconstant() { /* read HEX and OCTAL numbers */ char *c; cptr++; if( *cptr == 'H' || *cptr=='h') { /* HEX */ cptr++; c=cptr; while( isdigit(*cptr) || (*cptr>='a' && *cptr<='f' ) || (*cptr>='A' && *cptr<='F' ) )cptr++; sscanf(c,"%x",&ival); } else if( *cptr == 'O' || *cptr == 'o') { /* OCTAL */ cptr++; c=cptr; while( isdigit(*cptr) ) cptr++; sscanf(c,"%o",&ival); } else error("H or O expected"); return(INTVALUE); } number() { long i1; double atof(); register char *c; int overflow = 0; char cx; i1=0; c=cptr; while(isdigit(*c)){ i1= i1*10 + *c-'0'; if (i1 < 0) overflow = 1; c++; } if( *c != '.'){ if( i1> MAXINT || i1': if( *(c+1)=='='){ c++;c++;cptr=c; yylval.integer= GESYM;return(RELOP); } yylval.integer= '>'; cptr++; return(RELOP); case '<': if( *(c+1)=='='){ c++; c++; cptr=c; yylval.integer=LESYM; return(RELOP); } else if( *(c+1)=='>'){ c++; c++; cptr=c; yylval.integer=NESYM; return(RELOP); } yylval.integer= '<'; cptr++; return(RELOP); } return(*cptr++); }