void GlobVypis(tGlobSymbolTable *T,Tridic *ridic,sGlobTableItem *koren){ // printf(" a dany prvek **** %s\n",strGetStr((ptr->arg))); if (koren!=NULL){ printf("\n\nVYPIS - globalni tabulka\n"); printf("Pridany prvek ma nazev %s\n",strGetStr(&(koren->data.nazev))); printf(" a dany prvek ma typ %i\n",koren->data.typ); printf(" a dany prvek **** %s\n",strGetStr(&(koren->arg))); if (koren->link!=NULL){ LokVypis(T,ridic,koren->link); } GlobVypis(T,ridic,koren->lptr); GlobVypis(T,ridic,koren->rptr); } }
int main(int argc, char **argv) { if (argc == 2) { if (init_scanner(argv[1])) return EOF; } else { if (init_scanner(NULL)) return EOF; } int ret; do { ret = get_token(); #ifdef SCANNER_DEBUG if (token.type == TT_VALUE_INT) printf("\n%d Typ: %s %d\n", ret, token_name[token.type], token.value_int); else if (token.type == TT_VALUE_DOUBLE) printf("\n%d Typ: %s %lf\n", ret, token_name[token.type], token.value_double); else printf("\n%d Typ: %s %s\n", ret, token_name[token.type], strGetStr(buffer)); #endif // DEBUG } while (ret != ERR_SCANNER && ret != EOF); if(clean_scanner()) return EOF; return 0; }
//spoji dva retazce a vrati novy string * concat( string* s1, string* s2) { string * newstr = strNewFromConstChar(strGetStr(s1)); strAppendString(newstr, s2); return newstr; }
//zoradi retazec quicksortom string * sort ( string * src) //implementacia radenia quicksortom { if ( src == NULL ) return NULL; int len = strGetLength(src); srand( len ); string * srtd = strNewFromConstChar( strGetStr(src)); if ( len == 0) //prazdny netriedime return srtd; quicksort_c(strGetStr(srtd) , 0, len-1); //volame qs na pole return srtd; }
void VypisRamce(sRamec *ramec){ if(ramec != NULL){ printf("Vypis ramce********************************\n"); printf("RAMEC -jeho nazev je: %s\n",strGetStr(&(ramec->nazev))); if(ramec->lptr != NULL) VypisRamce(ramec->lptr); if(ramec->rptr != NULL) VypisRamce(ramec->rptr); } }
//podretazec na styl KMP int find ( string * in_this, string * what) { int m = 0; //namatchovany v zdrojovom int i = 0; //pozicia v hladanom int * pmtable = pm_table(what); //partial match table int len_in = strGetLength(in_this); int len_what = strGetLength(what); char * what_ptr = strGetStr(what); char * in_ptr = strGetStr(in_this); if ( pmtable == NULL ) { return 0; } //specialne pripady if ( (len_in == 0) && (len_what == 0) ) { return 0; } //algoritmus prehladavania while ( m + i < len_in ) //ukoncenie ak sa preslo celym retazcom a nenaslo sa { if ( what_ptr[i] == in_ptr[m+i] ) //zhoda { i++; //posunieme sa vo vzorke if ( i == len_what ) //ak sme namatchovali celu vzorku vratime zhodu return m; } else { m = m + i - pmtable[i]; //nezhoda posuniem sa o i dopredu a vratim sa o potrebny pocet miest ktore zistim z tabulky if ( i > 0) i = pmtable[i]; //v zhode sa posuniem na pocet o ktory som sa musel vratit } } free(pmtable); return -1; }
void LokVypis(tGlobSymbolTable *T,Tridic *ridic,sLokTableItem *koren){ if (koren!=NULL){ printf(" lokalni prvek ma nazev %s\n",strGetStr(&(koren->data.nazev))); printf(" argument je %i\n",koren->poradi_argumentu); printf(" lokalni typ je %i\n",koren->data.typ); LokVypis(T,ridic,koren->lptr); LokVypis(T,ridic,koren->rptr); } }
node_ptr //naalokuje a vrati nodu create_node (string *name) { node_ptr newnode = malloc (sizeof (struct node)); if ( newnode == NULL ) return NULL; newnode -> data.id_name = strNewFromConstChar( strGetStr(name) ); //skopiruje meno newnode -> data.value.str = NULL; //nastavy sa str na NULL koli freeovaniu return newnode; }
int parseNum ( string * src, int* retval, int base) { if (base == 0) return -1; //chybny zaklad else if ( base == 2) { return parseBin(src,retval); } *retval = strtol(strGetStr(src), NULL, base); return 0; }
int mara() { string stri; int type; double num; int error; type=-1; //*num=0; //*line=1; FILE *soubor; //stri=malloc(sizeof(string)); printf("*******************\n"); soubor = fopen(TEXT, "r"); while (type != 3) { if ((strInit(&stri))==1) { printf("nepovedlo se vytvořit řetězec\n"); } //int get_token(FILE *F, double *num, int *line, string *stri, int *error ) type=get_token(soubor,&num,&stri,&error); printf("\nJe to typ: %i\n",type); printf("Charnum je: %f a radek je:%i\n",num,line); printf("String je: %s\n",strGetStr(&stri)); printf("**************************************\n"); strFree(&stri); } fclose(soubor); }
//parsing binary number int parseBin( string * src, int *retval) { int len = strGetLength(src); int tmp = 0; for (int i = 0; i != len; i++) { char curr_char = strGetStr(src)[i]; if ( (curr_char == 'b') && (i == len-1)) { *retval = tmp; return 0; } else if ( curr_char > '1' || curr_char < '0') return -1; tmp = (tmp * 2) + ( curr_char - 48); } *retval = tmp; return 0; }
ptr_InstEntry emitInstr(ptr_IList ilist_ptr, int opcode, int op1type, void * op1, int op2type, void * op2,int op3type, void * op3) //Vlozenie instrukcie... { ptr_InstEntry newptr = malloc ( sizeof(InstEntry) ); //pametove miesto... if ( newptr == NULL ) return NULL; newptr->cont.opcode = opcode; //nastavenie operandu //na zaklade informacie o type ulozenej v instrukcii //prepis hodnotu z parametru do instrukcie //ak rertaec prekopiruj ho cely newptr->cont.op1type = op1type; if ( op1 != NULL) { if ( op1type == STR_OP_TYPE ) { //vlozenie konstanty malo by byt ok... newptr->cont.op1type = STR_OP_TYPE; newptr->cont.op1.str = strNewFromConstChar(strGetStr( *((string **)op1) )); } else { switch (op1type) { case ADDRESS_OP_TYPE : newptr->cont.op1.add = *((ptr_InstEntry *) op1); break; case TABLEENTRY_OP_TYPE : newptr->cont.op1.id = *((Table_Entry *) op1); break; case INT_OP_TYPE : newptr->cont.op1.i = *((int *) op1); break; case DBL_OP_TYPE : newptr->cont.op1.dbl = *((double *) op1); break; } } } else newptr->cont.op1.i = 0; newptr->cont.op2type = op2type; if ( op2 != NULL) { if ( op2type == STR_OP_TYPE ) { newptr->cont.op2type = STR_OP_TYPE; newptr->cont.op2.str = strNewFromConstChar(strGetStr( *((string **)op2) )); } else { switch (op2type) { case ADDRESS_OP_TYPE : newptr->cont.op2.add = *((ptr_InstEntry *) op2); break; case TABLEENTRY_OP_TYPE : newptr->cont.op2.id = *((Table_Entry *) op2); break; case INT_OP_TYPE : newptr->cont.op2.i = *((int *) op2); break; case DBL_OP_TYPE : newptr->cont.op2.dbl = *((double *) op2); break; } } } else newptr->cont.op2.i = 0; newptr->cont.op3type = op3type; if ( op3 != NULL) { if ( op3type == STR_OP_TYPE ) { newptr->cont.op3type = STR_OP_TYPE; newptr->cont.op3.str = strNewFromConstChar(strGetStr( *((string **)op3) )); } else { switch (op3type) { case ADDRESS_OP_TYPE : newptr->cont.op3.add = *((ptr_InstEntry *) op3); break; case TABLEENTRY_OP_TYPE : newptr->cont.op3.id = *((Table_Entry *) op3); break; case INT_OP_TYPE : newptr->cont.op3.i = *((int *) op3); break; case DBL_OP_TYPE : newptr->cont.op3.dbl = *((double *) op3); break; } } } else newptr->cont.op3.i = 0; if ( ilist_ptr == NULL) { return NULL; } newptr->next = NULL; if (ilist_ptr->tail == NULL) //prazdny zoznam prva = hlava aj koniec { ilist_ptr->head = newptr; ilist_ptr->tail = newptr; } else { ilist_ptr->tail->next = newptr;//iba koniec ilist_ptr->tail = newptr; } return newptr; }
//pomocne funkcie findu... //kalkulacia tabulky int * pm_table(string * s1) { if ( s1 == NULL ) return NULL; int len = strGetLength(s1); if ( len == 0) return NULL; int * tmp = malloc(len*sizeof(int)); //naalokuje miesto if (tmp == NULL) return NULL; int pos = 2; int cnd = 0; //staticke nastavenie prvych hodnot switch(len){ case 1: tmp[0] = -1; break; case 2: tmp[0] = -1; tmp[1] = 0; break; default: tmp[0] = -1; tmp[1] = 0; //generacia zvysnych miest //hladame "spravne" pripony retazca konciaceho na i-1 ktory je zaroven platnou "spravnou" predponou vzorky // while ( pos < len ) { // // --ak pokracuje p.suffix ktory je zaroven prefixom prradime hodnotu o 1 vecsiu if ( strGetStr(s1)[pos-1] == strGetStr(s1)[cnd] ) { tmp[pos]=cnd+1; pos++; cnd++; } else // podretazec nepokracuje a este sa mozeme vratit if (cnd > 0) { cnd = tmp[cnd]; } else //ziadne dalsie mozne podretazce dame 0 a posuvame sa { tmp[pos] = 0; pos++; } } } return tmp; }
//retazec na cislo //retazec sa nekontroluje za to je zodpovedny lexikalny analyzer double parseDbl( string * src ) { return strtod(strGetStr(src), NULL); }
int get_token(FILE *F, double *num, string *stri, int *error ) { int pom; int cha=0; int err_char=0; int next_state=ST_START; char c; char *chyba; char min; *num=0; c=fgetc(F); while (c != EOF) { switch(next_state) { case ST_START: if (c == '\n') { line++; next_state=ST_START; } if (isspace(c)) { break; //Tohle jsem přidával !!!!!!!! } else if (c == ';') { return TP_SEM; } else if (c == '/') { return TP_MOD; } else if (c == '.') { return TP_DOT; } else if (c == '(') { return TP_LBRA; } else if (c == '+') { return TP_PLUS; } else if (c == '-') { return TP_MINUS; } else if (c == ')') { return TP_RBRA; } else if (c == '*') { return TP_MUL; } else if (isdigit(c)) { next_state=ST_NUMBER; strAddChar(stri,c); } else if (isalpha(c)) { pom=0; next_state=ST_IDENT_KEY; strAddChar(stri,c); } else if (c == '{') { next_state=ST_KOMENT; } else if (c == 39) { next_state=ST_STRING; } else if (c == ':') { next_state=ST_COLONS; strAddChar(stri,c); } else if (c == '<') { next_state=ST_LESS; } else if (c == '>') { next_state=ST_MORE; } else if (c == ',') { return TP_COMMA; } else { *error=1; //nastala chyba. } break; case ST_KOMENT: if (c == '}') { next_state=ST_START; } break; case ST_IDENT_KEY: if ((!(isdigit(c))) && (!(isalpha(c)) && (c != '_'))) { ungetc(c,F); return TP_IDENT; } else { strAddChar(stri,c); } for (pom=0;pom<20;pom++) { if ((strCmpConstStr(stri,KeyWord[pom]))==0) { c=fgetc(F); if ((!(isdigit(c))) && (!(isalpha(c)))) { ungetc(c,F); return pom+51; } else { ungetc(c,F); } } } break; case ST_NUMBER: if(!(isdigit(c))) { if(c == '.') { next_state=ST_REAL; strAddChar(stri,c); } else if ((c == 'E') || (c == 'e')) { next_state=ST_REAL_EXP; strAddChar(stri,c); } else if ((c == '+') || (c == '-')) { if (c == '-') { min='-'; } c=fgetc(F); if ((c == 'E') || (c == 'e')) { next_state=ST_REAL_EXP; strAddChar(stri,c); if (min == '-') { strAddChar(stri,'-'); } } else { *error=1; next_state=ST_START; } } else if ((isspace(c)) || (c == ';') || (c == '\n')) { *num = strtod(strGetStr(stri),&chyba); return TP_INT; } else { *error=1; next_state=ST_START; } } else { strAddChar(stri,c); } break; case ST_LESS: if (c == '>') { return TP_NEQU; } else if (c == '=') { return TP_LESSEQ; } else { ungetc(c,F); return TP_LESS; } break; case ST_MORE: if (c == '=') { return TP_MOREEQ; } else { ungetc(c,F); return TP_MORE; } break; case ST_COLONS: if (c == '=') { return TP_SGNMNT; } else { ungetc(c,F); return TP_COL; } break; case ST_CHAR: if (c == 39) { if (err_char == 0) { strAddChar(stri,cha); } err_char=0; next_state=ST_STRING; break; } if ((!(isdigit(c)) && (c != 39)) || (err_char==1)) { printf("chyba\n"); } else { cha=cha*10+(c-48); if ((cha <1) && (cha >255)) { printf("chyba\n"); err_char=1; } } break; case ST_STRING: if (c == 39) { c=fgetc(F); if (c == '#') { next_state=ST_CHAR; break; } else { ungetc(c,F); return TP_STRING; } } else { strAddChar(stri,c); } break; case ST_REAL: if(!(isdigit(c))) { if ((c == 'E') || (c == 'e')) { next_state=ST_REAL_EXP; strAddChar(stri,c); } else if ((c == '+') || (c == '-')) { if (c == '-') { min='-'; } c=fgetc(F); if ((c == 'E') || (c == 'e')) { next_state=ST_REAL_EXP; strAddChar(stri,c); if (min == '-') { strAddChar(stri,'-'); } } else { *error=1; next_state=ST_START; } } else if ((isspace(c)) || (c == ';') || (c == '\n')) { *num = strtod(strGetStr(stri),&chyba); return TP_REAL; } else { *error=1; next_state=ST_START; } } else { strAddChar(stri,c); } break; case ST_REAL_EXP: if(!(isdigit(c))) { if ((isspace(c)) || (c == ';') || (c == '\n')) { *num = strtod(strGetStr(stri),&chyba); return TP_REAL_EXP; } else { *error=1; next_state=ST_START; } } else { strAddChar(stri,c); } break; } c=fgetc(F); } return TP_EOF; }
void gettoken() { strClear(&(T.s)); int x; char c; char h; int state=0; c=fgetc(f); if(c==EOF) { T.type=T_EOF; return; } while(1) { switch(state) { case 0: { if(c == '{') { if((x=jumpcomment()) == 1) { T.type=T_ERRORTOKEN; return; } c=fgetc(f); break; } else { if(isspace(c) != 0) { c=fgetc(f); break; } else { if(isalpha(c) != 0 || c=='_') { state=3; //T_ID if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } c=fgetc(f); break; } else{ if(isdigit(c) != 0) { state=4; //->T_INT/T_REAL if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } c=fgetc(f); break; } else{ if(c==EOF) { T.type=T_EOF; //T_EOF return; } else{ switch(c) //bude prepinat medzi dalsimi moznostami stale v pociatocnom stave { case '\'': { state=11;//->T_STRING c=fgetc(f); break; } case '(': { T.type=T_LB;//T_LB return; break; } case ')' : { T.type=T_RB;//T_RB return; break; } case ':' : { state=14;//T_COLON/T_ASSIGN c=fgetc(f); break; } case '*' : { T.type=T_MUL;//T_MUL return; break; } case '+' : { T.type=T_ADD;//T_ADD return; break; } case '-' : { T.type=T_SUB;//T_SUB return; break; } case '/' : { T.type=T_DIV;//T_DIV return; break; } case '<' : { state=12;//T_LESS/T_LESS_EQ if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } c=fgetc(f); break; } case '>' : { state=13;//T_MORE/T_MORE_EQ if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } c=fgetc(f); break; } case '=' : { T.type=T_EQUAL;//T_EQUAL return; break; } case '.' : { T.type=T_DOT;//T_DOT return; break; } case ',' : { T.type=T_COMMA;//T_COMMA return; break; } case ';' : { T.type=T_SEMICOLON;//T_SEMICOLON return; break; } default : //neplatny token { T.type=T_ERRORTOKEN; return; } } //switch c } // vylezie z else } } } } break; } case 3 : { if(isalpha(c) != 0 || isdigit(c) !=0 || c=='_') { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } c=fgetc(f); } else { ungetc(c,f); if(iskeyword(strGetStr(&(T.s)))==1){ T.type=T_KEYWORD; } else if (iskeyword(strGetStr(&(T.s)))==3){ T.type=T_DATATYPE; } else{ if(iskeyword(strGetStr(&(T.s)))==2) T.type=T_KONST; else{ T.type=T_ID; } } return; } break; } case 4 : { if(c == '.') { state=5; h=c; c=fgetc(f); } else{ if(c=='e' ||c=='E') { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } state=7; c=fgetc(f); break; } else{ if(isdigit(c)!=0) { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } c=fgetc(f); } else{ ungetc(c,f); T.type=T_INT; return; } } } break; } case 5 : { if(isdigit(c)!=0) { if(strAddChar(&(T.s),h)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } state=6; c=fgetc(f); } else{ ungetc(c,f); ungetc(h,f); T.type=T_INT; return; } break; } case 6 : { if(isdigit(c)!=0) { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } c=fgetc(f); } else{ if(c=='e' || c=='E') { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } state=7; c=fgetc(f); break; } else { ungetc(c,f); T.type=T_REAL; return; } } break; } case 7 : { if(isdigit(c)!=0) { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } state=9; c=fgetc(f); break; } else{ if(c=='+' || c=='-') { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } state=8; c=fgetc(f); break; } else{ T.type=T_ERRORTOKEN; return; } } break; } case 8 : { if(isdigit(c)!=0) { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } state=9; c=fgetc(f); break; } else { T.type=T_ERRORTOKEN; return; } break; } case 9 : { if(isdigit(c)!=0) { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } state=9; c=fgetc(f); break; } else { T.type=T_REAL; ungetc(c,f); return; } break; } case 11 : { if ( c == '\'') { c=fgetc(f); if ( c == '\''){ if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } c=fgetc(f); break;} if ( c == '#'){ if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } c=fgetc(f); if(isdigit(c)!=0) { if(c == '0'){ while (c == '0') { c=fgetc(f); } if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } } } else { T.type = T_ERRORTOKEN; return; break; } c=fgetc(f); if(isdigit(c)!=0) { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } } else { T.type = T_ERRORTOKEN; return; break; } c=fgetc(f); if(isdigit(c)!=0) { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } } else { ungetc(c,f); } c=fgetc(f); if ( c != '\'') { T.type = T_ERRORTOKEN; return; } c=fgetc(f); break; } else { ungetc(c,f); T.type = T_STRING; return; } } else { while (c != '\'') { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } c=fgetc(f); if(c==EOF) { T.type=T_ERRORTOKEN; return; } } state = 11; break; } } case 12: { if(c=='=') { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } T.type=T_LESS_EQ; return; } else if (c=='>') { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } T.type=T_NOT_EQ; return; } else { ungetc(c,f); T.type=T_LESS; return; } break; } case 13: { if(c=='=') { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } T.type=T_MORE_EQ; return; } else { ungetc(c,f); T.type=T_MORE; return; } break; } case 14: //:= { if(c=='=') { if(strAddChar(&(T.s),c)== STR_ERROR) { T.type=T_ERRORSYSTEM; return; } T.type=T_ASSIGN; return; } else { ungetc(c,f); T.type=T_COLON; return; } break; } } } }
int get_token() { typedef enum { INIT, OPERATOR, SLASH, STRING, STRING_BACKSLASH, STRING_HEXA, STRING_BINARY, STRING_OCTA, NUMBER, FLOAT, FLOAT_EXP, ID, ID_KEYWORD, LINE_COMMENT, BLOCK_COMMENT, BLOCK_COMMENT_END, BASE_EXT, BINARY, OCTA, HEXA } Tstate; Tstate state = INIT; int c; int j = 0; int ret_val = 0; int escape_seq = 0; //char *check; strClear(buffer); token.type = TT_ERR; while ((c = fgetc(in))) { if (c == '\n') { row++; col = 0; } else col++; if (c == EOF) { token.type = TT_EOF; return EOF; } #ifdef SCANNER_DEBUG fprintf(stderr, "%s (%s)", fsm_states[state], strGetStr(buffer)); if (strFirst(buffer) == '\0') fprintf(stderr, "\n"); else fprintf(stderr, " -> "); #endif // DEBUG switch(state) { case INIT: if (c == '/') // comment or operator { state = SLASH; strAddChar(buffer, c); } else if (is_operator(c)) { state = OPERATOR; strAddChar(buffer, c); } else if (c == '"') // string literal { state = STRING; } else if (c == '\\') // x, b, 0 literals supported - BASE { state = BASE_EXT; } else if (isdigit(c)) // number -> integer or double literal { state = NUMBER; strAddChar(buffer, c); } else if (c == '_') // id { state = ID; strAddChar(buffer, c); } else if (isalpha(c)) // alphabetic char -> id or keyword { state = ID_KEYWORD; strAddChar(buffer, c); } else if ((ret_val = is_delimiter(c))) { token.type = TYPE_DELIMITER + ret_val - 1; #ifdef SCANNER_DEBUG fprintf(stderr, "%s\n", token_name[token.type]); #endif return OK; } else if (!isspace(c)) // non valid character { lex_error("Unknown character: '%c'.\n", c); } break; case BASE_EXT: if (c == 'b') { state = BINARY; } else if (c == '0') { state = OCTA; } else if (c == 'x') { state = HEXA; } else lex_error("Unknown character in literal '\\%c'.\n", c); break; case HEXA: if (isxdigit(c)) { if (j < 8) // 8 hexadecimal digits are max int value { literal[j] = c; j++; } else lex_error("Hexadecimal literal too long -> int overflow!\n"); } else { ungetc(c, in); token.type = TT_VALUE_INT; literal[j] = '\0'; token.value_int = (int) strtol(literal, NULL, 16); // cannot fail if (token.value_int < 0) lex_warning("Hexadecimal literal '\\x%s' overflow to negative number %d\n", literal, token.value_int); return OK; } break; case OCTA: if (c >= '0' && c <= '7') { if (j < 12) // max int = \0 7777 7777 7777 { literal[j] = c; j++; } else lex_error("Octal literal too long -> int overflow!\n"); } else { ungetc(c, in); token.type = TT_VALUE_INT; literal[j] = '\0'; token.value_int = (int) strtol(literal, NULL, 8); if (token.value_int < 0) lex_warning("Octal literal '\\0%s' overflow to negative number %d\n", literal, token.value_int); return OK; } break; case BINARY: if ((c == '0' || c == '1')) { if (j < 32) { literal[j] = c; j++; } else lex_error("Binary literal too long -> int overflow!\n"); } else { ungetc(c, in); token.type = TT_VALUE_INT; literal[j] = '\0'; token.value_int = (int) strtol(literal, NULL, 2); if (token.value_int < 0) lex_warning("Binary literal '\\b%s' overflow to negative number %d\n", literal, token.value_int); return OK; } break; case ID_KEYWORD: if (isalpha(c)) // add another char into buffer { strAddChar(buffer, c); } else if (c == '_' || isdigit(c)) // id - these chars are not in any keyword { state = ID; strAddChar(buffer, c); } else // end of id or keyword { ungetc(c, in); // return last read char to buffer ret_val = is_keyword(strGetStr(buffer)); if (ret_val) { token.type = TYPE_KEYWORD + ret_val - 1; // magic #ifdef SCANNER_DEBUG fprintf(stderr, "%s\n", token_name[token.type]); #endif return OK; } else { token.type = TT_ID; token.p_string = strGetStr(buffer); #ifdef SCANNER_DEBUG fprintf(stderr, "%s\n", token_name[token.type]); #endif return OK; } } break; case ID: if (isalnum(c) || c == '_') { strAddChar(buffer, c); } else { ungetc(c, in); token.type = TT_ID; token.p_string = strGetStr(buffer); #ifdef SCANNER_DEBUG fprintf(stderr, "%s\n", token_name[token.type]); #endif return OK; } break; case SLASH: if (c == '/') { state = LINE_COMMENT; } else if (c == '*') { state = BLOCK_COMMENT; } else // it was division { ungetc(c, in); token.type = TT_DIVIDE; #ifdef SCANNER_DEBUG fprintf(stderr, "%s\n", token_name[token.type]); #endif return OK; } break; case OPERATOR: // not precisely "normal" fsm, but easily extensible (just add operator to operators[] and Ttoken_type) if (is_operator(c)) // c is one of valid chars, that can be in operator { strAddChar(buffer, c); ret_val = determine_operator(strGetStr(buffer)); // check if we still have valid operator in buffer if (!ret_val) // if it's not valid operator { ungetc(c, in); // return last char, it was not part of operator strDelChar(buffer); // delete wrong char from buffer ret_val = determine_operator(strGetStr(buffer)); // determine which operator we have token.type = TYPE_OPERATOR + ret_val - 1; // return token #ifdef SCANNER_DEBUG fprintf(stderr, "%s\n", token_name[token.type]); #endif return OK; } // continue with loading chars if it's valid } else // another char is not operator -> end { ungetc(c, in); ret_val = determine_operator(strGetStr(buffer)); if (ret_val) { token.type = TYPE_OPERATOR + ret_val - 1; #ifdef SCANNER_DEBUG fprintf(stderr, "%s\n", token_name[token.type]); #endif return OK; } else // shouldn't occur, just to be sure.. { lex_error("Unknown operator: '%s'.\n", strGetStr(buffer)); } } break; case LINE_COMMENT: if (c == '\n') // end of line comment { state = INIT; strClear(buffer); } break; case BLOCK_COMMENT: if (c == '*') // possible end of comment state = BLOCK_COMMENT_END; break; case BLOCK_COMMENT_END: if (c == '/') // comment ended { state = INIT; strClear(buffer); } else // false alarm - comment continues state = BLOCK_COMMENT; break; case NUMBER: if (isdigit(c)) { strAddChar(buffer, c); } else if (c == '.') { strAddChar(buffer, c); state = FLOAT; } else if (tolower(c) == 'e') { strAddChar(buffer, c); state = FLOAT_EXP; } else { ungetc(c, in); token.type = TT_VALUE_INT; token.value_int = (int) strtol(strGetStr(buffer), NULL, 10); #ifdef SCANNER_DEBUG fprintf(stderr, "%s\n", token_name[token.type]); #endif return OK; } break; case FLOAT: // aspoň jedna číslice! if (isdigit(c)) { strAddChar(buffer, c); } else if (tolower(c) == 'e') { strAddChar(buffer, c); state = FLOAT_EXP; } else { ungetc(c, in); token.type = TT_VALUE_DOUBLE; token.value_double = strtod(strGetStr(buffer), NULL); //&check); #ifdef SCANNER_DEBUG fprintf(stderr, "%s\n", token_name[token.type]); #endif return OK; } break; case FLOAT_EXP: if (isdigit(c)) { strAddChar(buffer, c); } else if (tolower(strLast(buffer)) == 'e' && (c == '+' || c == '-')) // optional +/- after e/E { strAddChar(buffer, c); } else { ungetc(c, in); token.type = TT_VALUE_DOUBLE; token.value_double = strtod(strGetStr(buffer), NULL); //&check); #ifdef SCANNER_DEBUG fprintf(stderr, "%s\n", token_name[token.type]); #endif return OK; } break; case STRING: if (c == '"') // end of string literal { token.type = TT_VALUE_STRING; token.p_string = strGetStr(buffer); #ifdef SCANNER_DEBUG fprintf(stderr, "%s\n", token_name[token.type]); #endif return OK; } else if (c == '\\') // string literal continues on another line or character constant state = STRING_BACKSLASH; else if (c != '\n') { strAddChar(buffer, c); } else { lex_error("String literal not closed.\n"); } break; case STRING_BACKSLASH: state = STRING; if (c == '\\') { strAddChar(buffer, '\\'); } else if (c == 'n') { strAddChar(buffer, '\n'); } else if (c == 't') { strAddChar(buffer, '\t'); } else if (c == '"') { strAddChar(buffer, '"'); } else if (c == 'x') { state = STRING_HEXA; } else if (c == 'b') { state = STRING_BINARY; } else if (c == '0') { state = STRING_OCTA; } else if (c == '\n') { // do nothing, string continues on next line - TODO: zdokumentovat upravu } else { lex_error("Escape sequence '\\%c' unknown.\n", c); } break; case STRING_HEXA: if (j < 2 && isxdigit(c)) // 2 is max hexadecimal escape length { literal[j] = c; j++; } else if (j == 0) // no valid hexadecimal digit after \x -> error { lex_error("'\\x%c' is not valid hexadecimal escape sequence.\n", c); } else // end of hexadecimal escape { literal[j] = '\0'; escape_seq = strtol(literal, NULL, 16); // will always be successful if (escape_seq == 0) { lex_error("\\x00 is not allowed hexadecimal escape sequence.\n"); } strAddChar(buffer, escape_seq); ungetc(c, in); // return currently read char j = 0; state = STRING; } break; case STRING_BINARY: if (j < 8 && (c == '0' || c == '1')) // 8 is max binary escape length { literal[j] = c; j++; } else if (j == 0) // no valid binary digit after \b -> error { lex_error("'\\b%c' is not valid binary escape sequence.\n", c); } else // end of binary escape { literal[j] = '\0'; escape_seq = strtol(literal, NULL, 2); // will always be successful if (escape_seq == 0) { lex_error("\\b00000000 is not allowed binary escape sequence.\n"); } strAddChar(buffer, escape_seq); ungetc(c, in); // return currently read char j = 0; state = STRING; } break; case STRING_OCTA: if (j < 3 && c >= '0' && c <= '7') // 3 is max octal escape length { literal[j] = c; j++; } else if (j == 0) // no valid octal digit after \0 -> error { lex_error("'\\0%c' is not valid octal escape sequence.\n", c); } else // end of octal escape { literal[j] = '\0'; escape_seq = strtol(literal, NULL, 8); // will always be successful if (escape_seq == 0) { lex_error("\\000 is not allowed octal escape sequence.\n"); } else if (escape_seq > 255) { lex_error("Octal escape '\\0%s' bigger than 255.\n", literal); } strAddChar(buffer, escape_seq); ungetc(c, in); // return currently read char j = 0; state = STRING; } break; default: lex_error("Scanner panic!!!\n"); break; } // end_switch } // end_while return 0; }
//------------------------------------------------------------------------------ //pomocna funkcia vypise obsah zoznamu void printList(ptr_IList ilist_ptr) { ptr_InstEntry newptr = ilist_ptr->head; while( newptr != NULL) { printf("---------------------------\n"); printf("Opcode %d\n",newptr->cont.opcode); printf("Op1type %d\n",newptr->cont.op1type); switch (newptr->cont.op1type) { case ADDRESS_OP_TYPE : printf("Pointer: %p\n",(void *)newptr->cont.op1.add ); break; case TABLEENTRY_OP_TYPE : printf("Premenna meno: %s\n",strGetStr(newptr->cont.op1.id->id_name)); break; case INT_OP_TYPE : printf("Cislo cele %d\n",newptr->cont.op1.i); break; case DBL_OP_TYPE : printf("Cislo desatinne %lf\n",newptr->cont.op1.dbl); break; case STR_OP_TYPE : if (newptr->cont.op1.str == NULL) break; printf("Retazec: %s\n",strGetStr(newptr->cont.op1.str)); break; } printf("Op2type %d\n",newptr->cont.op2type); switch (newptr->cont.op2type) { case ADDRESS_OP_TYPE : printf("Pointer: %p\n",(void *)newptr->cont.op2.add ); break; case TABLEENTRY_OP_TYPE : printf("Premenna meno: %s\n",strGetStr(newptr->cont.op2.id->id_name)); break; case INT_OP_TYPE : printf("Cislo cele %d\n",newptr->cont.op2.i); break; case DBL_OP_TYPE : printf("Cislo desatinne %lf\n",newptr->cont.op2.dbl); break; case STR_OP_TYPE : if (newptr->cont.op2.str == NULL) break; printf("Retazec: %s\n",strGetStr(newptr->cont.op2.str)); break; } printf("Op3type %d\n",newptr->cont.op3type); switch (newptr->cont.op3type) { case ADDRESS_OP_TYPE : printf("Pointer: %p\n",(void *)newptr->cont.op3.add ); break; case TABLEENTRY_OP_TYPE : printf("Premenna meno: %s\n",strGetStr(newptr->cont.op3.id->id_name)); break; case INT_OP_TYPE : printf("Cislo cele %d\n",newptr->cont.op3.i); break; case DBL_OP_TYPE : printf("Cislo desatinne %lf\n",newptr->cont.op3.dbl); break; case STR_OP_TYPE : if (newptr->cont.op3.str == NULL) break; printf("Retazec: %s\n",strGetStr(newptr->cont.op3.str)); break; } printf("---------------------------\n"); newptr=newptr->next; } }