//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; }
//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; }
int concateStrings(string *s1, string *s2, string *s3) // Funkce zkopíruje øetìzec s1 do s3 a pøidá za nìj øetìzec s2 { int delka, index; // Promìnné pro pøidávání if(strCopyString(s3,s1) == STR_ERROR) // Zkopíruji s1 do s3 a kontrola return STR_ERROR; delka = strGetLength(s2); // Ulo¾ím si délku druhého for(index = 0; index < delka; index++) // Kopíruji do s3 znaky z s2 { if(strAddChar(s3, s2->str[index]) == STR_ERROR) // Pøidám znak na konec øetìzce a kontrola return STR_ERROR; } return STR_SUCCESS; // Úspì¹né slouèení øetìzcù s1 a s2 do øetìzce s3 }
//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; }
int LokTableInsert(tGlobSymbolTable *T, string *nazev, int typ,Tridic *ridic){/*vlození noveho uzlu do lok table*/ sLokTableItem *novy; sLokTableItem *pomloka; int koren=0; if ((novy = (sLokTableItem*) malloc(sizeof(sLokTableItem)))==NULL) error(T,OTHER_RUNN_ERR,ridic);/*alokace mista na novy lokalni prvek*/ ridic->aktiv=novy;/*nastaveni aktivity na novy prvek*/ novy->data.def=1;/*plneni prvku*/ strInit(&(novy->data.nazev)); novy->data.typ=typ; novy->lptr=NULL; novy->rptr=NULL; if ( ridic->pomlog || ridic->deklaration){/*pokud se jedna o hlavicku fce*/ ridic->pocet_argumentu++; novy->data.def=1;/*argument je inicialyzovany*/ novy->poradi_argumentu=ridic->pocet_argumentu;/*poradí argumentu*/ }else { novy->data.def=0;/*lokalni promenna neni inicializovana*/ novy->poradi_argumentu=0;/*nejedna se o argument funkce*/ } if (nazev!=NULL){/*pokud se nejedna o navratovy typ*/ strCopyString((&novy->data.nazev), nazev);/*naplnim nazev*/ }else { strCopyString((&novy->data.nazev), &(ridic->nazev_func));/*jinak ziskam nazev z globalni tabulky z aktualniho prvku*/ novy->data.def=3; } sGlobTableItem *pomgl; koren=0; pomgl = T->first;/*nastavime koren stromu*/ koren= tableSearchGlob(ridic,&pomgl,&(novy->data.nazev));/*prohledame glob tabulku kvuli shodnym nazvum fci*/ if (koren==0 && nazev!=NULL){/*pokud byl prvek nalezen a lok promenna neni navratovy typ*/ if (pomgl->data.typ==FUNCTION_HEADER){/*pokud byla nalezena glob uzel ktery je funkce*/ ItemFreeAktu(NULL, novy);/*uvolni pridavany prvek*/ error(T,TAB_ERR,ridic);/*chyba v ramci tabulky*/ } } if (ridic->deklaration>0){/*pokud jsme v hlavicce funkce*/ sLokTableItem *poml; sGlobTableItem *pomgl; pomgl = ridic->aktivG;/*jako pomocný glob uzel nastavime aktivni glob uzel*/ poml=pomgl->link;/*jako pomocnou lok. tabulku nastavime odkaz z aktivniho glob uzlu*/ koren=0; koren=tableSearchLok(ridic,&poml,&(novy->data.nazev)); if (koren){ ItemFreeAktu(NULL, novy);/*uvolnime pridávany prvek*/ error(T,TAB_ERR,ridic);/*chyba v ramci tabulky*/ } ridic->deklaration++;/*kontrola poctu argumentu*/ if (ridic->deklaration==strGetLength(&(pomgl->arg))+1) {ridic->deklaration=0;}/*pocet prvku deklrovane a definovane funkce je jiny*/ if (poml->data.typ==typ){/*pokud sedi typ argumentu deklarovane a definovane funkce*/ if (poml->poradi_argumentu==novy->poradi_argumentu){/*pokud je na stejnem miste*/ if (nazev!=NULL){/*pokud se nejedna o navratovy parametr*/ if ((strCmpString(&(poml->data.nazev), nazev)==0)) {/*pokud sedi nazvy*/ ItemFreeAktu(NULL, novy);/*uvolnime vkladany argument*/ return 1;/*agrumnet je totozny*/ }else { ItemFreeAktu(NULL, novy);/*uvolnime vkladany argument*/ error(T,TAB_ERR,ridic);/*error v ramci tabulky*/ } }else{/*pokud se jedna o navratovy parametr*/ if (ridic->deklaration==strGetLength(&(ridic->aktivG->arg))) {/*pokud neni stejny pocet argumentu*/ ItemFreeAktu(NULL, novy);/*uvolnime vkladany argument*/ error(T,TAB_ERR,ridic);/*error v ramci tabulky*/ } ridic->aktivG=pomgl;/*uvolnime vkládaný argument*/ ItemFreeAktu(NULL,novy);/*error v ramci tabulky*/ return 1;/*agrumnet je totozny*/ } }else {/*nejedna se o stejny typ*/ ItemFreeAktu(NULL, novy);/*uvolníme vkladany argument*/ error(T,TAB_ERR,ridic);/*error v ramci tabulky*/ } } } else{/*pokud pridavame lokalni promennou*/ if (ridic->aktivG->link==NULL){/*pokud je strom prazdny*/ ridic->aktivG->link=novy;/*pridame jako koren*/ }else{ pomloka=ridic->aktivG->link; koren=0; koren=tableSearchLok(ridic,&pomloka,&(novy->data.nazev)); if (koren==0){/*pokud j*z prvek se stejnym klicem existuje*/ ItemFreeAktu(NULL, novy);/*uvolnime vkladany argument*/ error(T,TAB_ERR,ridic);/*error v ramci tabulky*/ } if (koren==1){/*pridame do leveho podstromu*/ pomloka->lptr=novy; }else if (koren==2) {pomloka->rptr=novy;}/*pridáme do praveho podstromu*/ } if ( (ridic->pomlog ) || (nazev==NULL) ){/*pokud jsme v hlavicce funkce*/ switch(typ){/*pridame typ argumnetu do glob tabulky*/ case TP_INT: if (strAddChar(&(ridic->aktivG->arg),'i')); break; case TP_REAL: if (strAddChar(&(ridic->aktivG->arg),'r')); break; case TP_STRING: if (strAddChar(&(ridic->aktivG->arg),'s')); break; case BOOLEAN: if (strAddChar(&(ridic->aktivG->arg),'b')); break; } } if (nazev==NULL) {/*pokud uz byl predan i navratovy typ*/ ridic->pocet_argumentu=0; /*nasleduji lok promenne*/ ridic->pomlog=0;/*nejsme j*z v hlavicce funkce*/ } return 1; } return 0; }
int getToken(tToken *Token, FILE* source) { //prvne zkontroluji frontu tokenu if (TQueue != NULL) {//nema cenu si neco na frontu zkouset kdyz je NULL TQDequeue(Token); if (Token != NULL) {//token byl ve fronte return 1; } } //alokace pameti pro cteny token tToken tok = (tToken)malloc(sizeof(struct stToken)); *Token = tok; /* @var c int actual character*/ int c = -1; /* @var prevRest int poslední načtený znak (Zbytek posledního průchodu) */ static int pom = -1; /* @var string s Uklada aktualne cteny string pokud je treba, pri kazdem * konci teto funkce musi byt volano strFree. */ string s; //strInit vraci 1 při chybe if (strInit(&s)) { FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } //string kam se ukladaji sekvence pro escape sekvence string escape; //nastavime vychozi stav int state = START; while (1) { if (pom > 0) {//pozustatek z minuleho cteni c = pom; pom = -1;//-1 je jedina hodnota kterou by nemela pomocna promenna nabyt pokud v ni opravdu je pozustatek //pokud je v ni opravdu EOF tak pomoci getc() ho stejne dostanu znovu } else { c = getc(source); character++; if (c == '\n') {//pokud ctu dalsi radek tak vynuluji citadlo znaku a inkrementuji citadlo radku line++; character = 0; } } switch (state) { case START: //pocatecni bile znaky nic nezmeni if (isspace(c)) { state = START; } //zacatek identifikatoru else if (isalpha(c) || c == '_') { state = IDENTIFICATOR; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } //ulozi prvni nulu v cisle else if (c == '0') { state = FLOAT_OR_INT; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } //platna cislice na zacatku retezce znamena celou cast cisla else if (c >= '1' && c <= '9') { state = INT_PART; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } //strednik ulozi token strednik else if (c == ';') { tok->typ = SEMICOLON; strFree(&s); return 1; } //zacatek escape sekvenci rozsireni BASE else if (c == '\\') { state = ESCAPE; } //string zacina uvozovkami else if (c == '\"') { state = STRING; } //lomeno muze byt operatro nebo zacatek komentare else if (c == '/') { state = DIVISION_COMMENT; } //unarni minus, odcitani nebo dekremenrace else if (c == '-') { //jsem schopny rozlisit jen dekrementaci a minus //unarni minus ani rozdil mezi postfix/prefix neurcim state = DECREMENT_OPERATOR; } //scitani nebo inkrementace else if (c == '+') { state = INCREMENT_OPERATOR; } //nasobeni znamena jedine nasobeni else if (c == '*') { tok->typ = MULTIPLY; strFree(&s); return 1; } //toto mohou byt opertary se dvema znaky i jednim else if (c == '!' || c == '<' || c == '>' || c == '=') { state = TWO_CHAR_OPER; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } //zaovrky ihned ulozime jako token else if (c == ')') { tok->typ = PARENTHESIS_CLOSING; strFree(&s); return 1; } else if (c == '(') { tok->typ = PARENTHESIS_OPENING; strFree(&s); return 1; } else if (c == '}') { tok->typ = BRACES_CLOSING; strFree(&s); return 1; } else if (c == '{') { tok->typ = BRACES_OPENING; strFree(&s); return 1; } //logicky or else if (c == '|') { state = LOGICAL_OR; } //logicky and else if (c == '&') { state = LOGICAL_AND; } //carka (comma) operator ulozime do tokenu else if (c == ',') { tok->typ = COMMA; strFree(&s); return 1; } //konec souboru cas vyhlasit chyby pokud nastaly jinak ulozit do tokenu EOF else if (c==EOF) { tok->typ = END_OF_FILE; strFree(&s); if (errorFlag) { freeTokenMem(&tok); return 42; } return 1; } else {//pokud na zacatku tokenu prislo cokoli jineho tak scanner nevi co se deje errorFlag = 1; Warning("%sLine - %d:%d\t- Unknown symbol.\n", ERR_MESSAGES[ERR_LEX], line, character); strFree(&s); freeTokenMem(&tok); return 42; } break; case INT_PART: //cteni cele casti cisla //cislice ukladam if (c >= '0' && c <= '9') { state = INT_PART; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } //zacatek exponentu else if (c == 'e' || c == 'E') { state = EXPONENT_CHECK; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } //zacatek desetine casti else if (c == '.') { //vlozen testovaci stav pro podminku ze za des. teckou musi byt cislice state = FLOAT_CHECK; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } //uloz cele cislo else { int val; if (!strToInt(&s, &val)) { freeTokenMem(&tok); strFree(&s); FatalError(99, "%s-%d: Chyba pri nacteni celeho cisla.", ERR_MESSAGES[ERR_ALLOC], line); return 42; } pom = c; tok->typ = TYPE_INTEGER; tok->value.intVal = val; strFree(&s); return 1; } break; case FLOAT_OR_INT: //prvni nula byla ulozena pocatecnim stavu ted je necham byt if (c == '0') { state = FLOAT_OR_INT; } else if (c >= '1' && c<='9') {//pokud nasleduje cislice ctu cele cislo state = INT_PART; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else if (c == '.') { //zacatek desetine casti state = FLOAT_CHECK; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else if (c == 'e' || c == 'E') { //zacatek exponentu state = EXPONENT_CHECK; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else { //konec celeho cisla int val; if (!strToInt(&s, &val)) { errorFlag = 1; Warning("%sLine - %d:%d\t- Nepodarilo se nacist ciselny literal.\n",ERR_MESSAGES[ERR_LEX], line, character); strFree(&s); freeTokenMem(&tok); return 42; } tok->typ = TYPE_INTEGER; tok->value.intVal = val; strFree(&s); pom = c; return 1; } break; case FLOAT_CHECK: //tento stav slouzi ke kontrole neprazdnosti desetine casti if (c >= '0' && c <= '9') { state = FLOAT_PART; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } //pokud za teckou neni cislice je to chyba else { pom = c; errorFlag = 1; Warning("%sLine - %d:%d\t- Nepodarilo se nacist ciselny literal. Desetina cast nesmi byt prazdna.\n", ERR_MESSAGES[ERR_LEX], line, character); strFree(&s); freeTokenMem(&tok); return 42; } break; case FLOAT_PART: if (c >= '0' && c <= '9') { //ulozi cislo a pokracuje ve cteni state = FLOAT_PART; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else if (c == 'e' || c == 'E') { //zacatek exponentu state = EXPONENT_CHECK; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else { //konec desetineho cisla, ulozme jej double val; if (!strToDouble(&s, &val)) { errorFlag = 1; Warning("%sLine - %d:%d\t- Nepodarilo se nacist ciselny literal.\n",ERR_MESSAGES[ERR_LEX], line, character); strFree(&s); freeTokenMem(&tok); return 42; } tok->typ = TYPE_DOUBLE; tok->value.doubleVal = val; strFree(&s); pom = c; return 1; } break; case EXPONENT_CHECK: if (c >= '0' && c <= '9') { //prislo cislo, ulozi jej a pokracuje j*z ve cteni exponentu state = EXPONENT; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else if (c == '+' || c == '-') { //znamenko na zacatku exponentu state = EXPONENT_PLUS_MINUS_CHECK; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } //nemuzeme napsat exponent a neudat ho else{ errorFlag = 1; Warning("%sLine - %d:%d\t- Exponent musi obsahovat validni cislici.\n",ERR_MESSAGES[ERR_LEX], line, character); pom = c; strFree(&s); freeTokenMem(&tok); return 42; } break; case EXPONENT_PLUS_MINUS_CHECK: if (c >= '0' && c <= '9') { //spravne bylo za znamenkem exponentu cislo //pokracuji ve cteni expoenntu state = EXPONENT; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else { //nemuzem napsat znamenko exponentu a neudat jeho hodnotu errorFlag = 1; Warning("%sLine - %d:%d\t- Exponent musi obsahovat validni cislici.\n",ERR_MESSAGES[ERR_LEX], line, character); pom = c; strFree(&s); freeTokenMem(&tok); return 42; } break; case EXPONENT: if (c >= '0' && c <= '9') { //cte cisla dokud prichazi state = EXPONENT; if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else { //prislo cokoli jineho nez cislo double val = 42; if (!strToDouble(&s, &val)) { errorFlag = 1; Warning("%sLine - %d:%d\t- Nepodarilo se nacist ciselny literal.\n",ERR_MESSAGES[ERR_LEX], line, character); strFree(&s); freeTokenMem(&tok); return 42; } tok->typ = TYPE_DOUBLE; tok->value.doubleVal = val; pom = c;//dalsi znak patri dalsimu tokenu strFree(&s); return 1; } break; case ESCAPE: //escape sekvence celociselne konstanty switch (c) { //binarni escape sekvence case 'b': case 'B': state = BINARY_NUMBER; break; //oktalova escape sekvence case '0': state = OCTAL_NUMBER; break; //hexadecimalni escape sekvence case 'x': case 'X': state = HEX_DEC_NUMBER; break; //cokoli jineho je chybou default: errorFlag = 1; Warning("%sLine - %d:%d\t- Ocekavan symbol pro ciselnou soustavu.\n",ERR_MESSAGES[ERR_LEX], line, character); strFree(&s); freeTokenMem(&tok); return 42; break; } break; case BINARY_NUMBER: //escape sekvence obsahujici binarni cislo if (c == '0' || c == '1') { //zahazuji nevyznamne nuly if (!(c == '0' && strGetLength(&s) == 0)) { if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } } else { pom = c; int val = 0; if (!strBinToInt(&s, &val)) { strFree(&s); freeTokenMem(&tok); return 42; } tok->typ = TYPE_INTEGER; tok->value.intVal = val; strFree(&s); return 1; } break; case OCTAL_NUMBER: //escape sekvence obsahujici oktalove cislo if (c >= '0' && c <= '7') { //zahazuji nevyznamne nuly if (!(c == '0' && strGetLength(&s) == 0)) { if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } } else { pom = c; int val = 0; if (!strOctToInt(&s, &val)) { strFree(&s); freeTokenMem(&tok); return 42; } tok->typ = TYPE_INTEGER; tok->value.intVal = val; strFree(&s); return 1; } break; case HEX_DEC_NUMBER: //escape sekvence obsahujici hexadecimalni cislo if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { //zahazuji nevyznamne nuly if (!(c == '0' && strGetLength(&s)==0)) { if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } } else { pom = c; int val = 0; if (!strHexToInt(&s, &val)) { strFree(&s); freeTokenMem(&tok); return 42; } tok->typ = TYPE_INTEGER; tok->value.intVal = val; strFree(&s); return 1; } break; case LOGICAL_AND: //logicky and //v IFJ2015 neexistuje binarni and proto jediny prijatelny znak //v tuto chvili je & if (c == '&') { tok->typ = LOG_AND_OPER; strFree(&s); return 1; } else { pom = c; errorFlag = 1; Warning("%sLine - %d:%d\t- Binarni and neni podporovan v IFJ2015.\n",ERR_MESSAGES[ERR_LEX], line, character-1); strFree(&s); freeTokenMem(&tok); return 42; } break; case LOGICAL_OR: //logicky or //v IFJ2015 neexistuje binarni or proto jediny prijatelny znak //v tuto chvili je | if (c == '|') { tok->typ = LOG_OR_OPER; strFree(&s); return 1; } else { /*Abych se zotavil po teto chybe a docetl soubor*/ errorFlag = 1; Warning("%sLine - %d:%d\t- Binarni or neni podporovan v IFJ2015.\n",ERR_MESSAGES[ERR_LEX], line, character - 1); pom = c; strFree(&s); freeTokenMem(&tok); return 42; } break; case STRING: if (c == EOF) { errorFlag = 1; Warning("%sLine - %d:%d\t- Necekany konec souboru.\n",ERR_MESSAGES[ERR_LEX], line, character); strFree(&s); freeTokenMem(&tok); return 42; } else if (c == '\\') { state = STRING_ESCAPE; } else if (c == '"') {//konec retezce uloz ho tok->typ = TYPE_STRING; if (strInit(&tok->value.stringVal)) { //return stringval } if (strCopyString(&tok->value.stringVal, &s)) { //return error; } strFree(&s); return 1; } else if (c < 1 || c>255) {//nejaky znak mimo ASCII chyba } else {//uloz si znak if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } break; case STRING_ESCAPE: //escape sekvence ve stringu switch (c) { //binarni escape sekvence case 'b': case 'B': if (strInit(&escape)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } state = STRING_BINARY_NUMBER; break; //oktalova escape sekvence case '0': if (strInit(&escape)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } state = STRING_OCTAL_NUMBER; break; case 'x': case 'X': //hexadecimalni escape sekvence if (strInit(&escape)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } state = STRING_HEX_DEC_NUMBER; break; case '\\': //escape sekvence backslash if (strAddChar(&s, '\\')) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } state = STRING; break; case 'n': //escape sekvence noveho radku if (strAddChar(&s, '\n')) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } state = STRING; break; case 't': //escape sekvence tabulatoru if (strAddChar(&s, '\t')) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } state = STRING; break; case '\"': //escape sekvence uvozovek if (strAddChar(&s, '\"')) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } state = STRING; break; default: //cokoliv jineho je chybnym zapsani escape sekvence errorFlag = 1; Warning("%sLine - %d:%d\t- Ocekavana escape sekvence\n", ERR_MESSAGES[ERR_LEX], line, character); strFree(&s); freeTokenMem(&tok); return 42; break; } break; case STRING_BINARY_NUMBER: if ((c == '0' || c == '1')) {//ctu validni vstup if (strGetLength(&escape) < 8) {//jeste nemam 8 cislic tak ctu dal if (strAddChar(&escape, c)) { freeTokenMem(&tok); strFree(&escape); strFree(&s); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else {//mam 8 cislic pom = c; int val; if (strBinToInt(&escape, &val) && val >= 1 && val <= 255) { if (strAddChar(&s, (char)val)) {//precteny znak pridam do stringu freeTokenMem(&tok); strFree(&escape); strFree(&s); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else {//nepodarilo se prevest escape na string errorFlag = 1; Warning("%sLine - %d:%d\t- Retezec \"%s\" neni platnou escape sekvenci.\n", ERR_MESSAGES[ERR_LEX], line, character, escape.str); } strFree(&escape); state = STRING; } } else { if (strGetLength(&escape) < 8) { errorFlag = 1; Warning("%sLine - %d:%d\t- Retezec \"%s\" neni platnou escape sekvenci.\n", ERR_MESSAGES[ERR_LEX], line, character, escape.str); } if (strGetLength(&escape) == 8) { int val; if (strBinToInt(&escape, &val) && val >= 1 && val <= 255) { if (strAddChar(&s, (char)val)) { freeTokenMem(&tok); strFree(&escape); strFree(&s); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else { errorFlag = 1; Warning("%sLine - %d:%d\t- Retezec \"%s\" neni platnou escape sekvenci.\n", ERR_MESSAGES[ERR_LEX], line, character, escape.str); } } pom = c; strFree(&escape); state = STRING; } break; case STRING_OCTAL_NUMBER: if ((c >= '0' && c <= '7')) {//ctu validni vstup if (strGetLength(&escape) < 3) { if (strAddChar(&escape, c)) { freeTokenMem(&tok); strFree(&escape); strFree(&s); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else { pom = c; int val; if (strOctToInt(&escape, &val) && val >= 1 && val <= 255) { if (strAddChar(&s, (char)val)) { freeTokenMem(&tok); strFree(&escape); strFree(&s); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else { errorFlag = 1; Warning("%sLine - %d:%d\t- Retezec \"%s\" neni platnou escape sekvenci.\n", ERR_MESSAGES[ERR_LEX], line, character, escape.str); } strFree(&escape); state = STRING; } } else { if (strGetLength(&escape) < 3) { errorFlag = 1; Warning("%sLine - %d:%d\t- Retezec \"%s\" neni platnou escape sekvenci.\n", ERR_MESSAGES[ERR_LEX], line, character, escape.str); } if (strGetLength(&escape) == 3) { int val; if (strOctToInt(&escape, &val) && val >= 1 && val <= 255) { if (strAddChar(&s, (char)val)) { freeTokenMem(&tok); strFree(&escape); strFree(&s); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else { errorFlag = 1; Warning("%sLine - %d:%d\t- Retezec \"%s\" neni platnou escape sekvenci.\n", ERR_MESSAGES[ERR_LEX], line, character, escape.str); } } pom = c; strFree(&escape); state = STRING; } break; case STRING_HEX_DEC_NUMBER: if ((c >= '0' && c <= '9')||(c >= 'a' && c <= 'f')|| (c >= 'A' && c <= 'F')) {//ctu validni vstup if (strGetLength(&escape) < 2) { if (strAddChar(&escape, c)) { freeTokenMem(&tok); strFree(&escape); strFree(&s); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else { int val; pom = c; if (strHexToInt(&escape, &val) && val >= 1 && val <= 255) { if (strAddChar(&s, (char)val)) { freeTokenMem(&tok); strFree(&escape); strFree(&s); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else { errorFlag = 1; Warning("%sLine - %d:%d\t- Retezec \"%s\" neni platnou escape sekvenci.\n", ERR_MESSAGES[ERR_LEX], line, character, escape.str); } strFree(&escape); state = STRING; } } else { if (strGetLength(&escape) < 2) { errorFlag = 1; Warning("%sLine - %d:%d\t- Retezec \"%s\" neni platnou escape sekvenci.\n", ERR_MESSAGES[ERR_LEX], line, character, escape.str); } if (strGetLength(&escape) == 2) { int val; if (strHexToInt(&escape, &val) && val >= 1 && val <= 255) { if (strAddChar(&s, (char)val)) { freeTokenMem(&tok); strFree(&escape); strFree(&s); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } else { errorFlag = 1; Warning("%sLine - %d:%d\t- Retezec \"%s\" neni platnou escape sekvenci.\n", ERR_MESSAGES[ERR_LEX], line, character, escape.str); } } pom = c; strFree(&escape); state = STRING; } break; case IDENTIFICATOR: //ctu cislice, pismena nebo podtrzitka if (isalnum(c) || c == '_') { if (strAddChar(&s, c)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } //konec identifikatoru else { pom = c; int isIdent = isKeyWord(&s); tok->typ = isIdent; if (isIdent == TYPE_IDENTIFICATOR) { if (strInit(&(tok->value.stringVal))) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } if (strCopyString(&(tok->value.stringVal), &s)) { strFree(&s); freeTokenMem(&tok); FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } } if (isIdent == KEYW_FALSE) { tok->typ = TYPE_BOOL; tok->value.boolVal = false; } if (isIdent == KEYW_TRUE) { tok->typ = TYPE_BOOL; tok->value.boolVal = true; } strFree(&s); return 1; } break; case DIVISION_COMMENT: if (c == '*') { state = BLOCK_COMMENT; } else if (c == '/') { state = LINE_COMMENT; } else {//jednoznakovy operator deleni tok->typ = DIVISION; pom = c; strFree(&s); return 1; } break; case LINE_COMMENT: if (c == '\n') {//konec radkoveho komentare hledame dalsi lexem state = START; } else if (c == EOF) {//nemusi byt lf pred koncem souboru pom = c; state = START; } else {//komentar pokracuje //reflection nepodporujeme takže komentáře zahodíme } break; case BLOCK_COMMENT: if (c == EOF) { Warning("%sLine - %d:%d\t- Necekany konec souboru.\n", ERR_MESSAGES[ERR_LEX], line, character); strFree(&s); freeTokenMem(&tok); return 42; } /*else if (c=='/') { state = NESTED_BLOCK_COMMENT_CHECK; }*/ else if (c=='*') { state = END_BLOCK_COMMENT; } break; case END_BLOCK_COMMENT: if (c == '*') { //zůstaneme tady komentář může končit x hvězdičkama } else if (c == EOF) { Warning("%sLine - %d:%d\t- Necekany konec souboru.\n", ERR_MESSAGES[ERR_LEX], line, character); strFree(&s); freeTokenMem(&tok); return 42; } else if (c == '/') {//konec blokového komentáře jdeme hledat další lexém state = START; } else { state = BLOCK_COMMENT; } break; //dvouznakove operatry case TWO_CHAR_OPER: //jako druhy znak muze jen rovna se //dle prvniho znaku rozhodneme co ulozime if (c == '=') { switch (s.str[0]) { case '!': tok->typ = NOT_EQUAL_OPER; break; case '<': tok->typ = LESS_EQUAL; break; case '>': tok->typ = GREATER_EQUAL; break; case '=': tok->typ = EQUAL; break; default: break; } } //pokud prislo cokoli jineho tak dle prvniho znaku rozhodneme co ulozime else { pom = c; switch (s.str[0]) { case '!': tok->typ = LOG_NOT_OPER; break; case '<': tok->typ = LESS; break; case '>': tok->typ = GREATER; break; case '=': tok->typ = SET_OPER; break; default: break; } } strFree(&s); return 1; break; case DECREMENT_OPERATOR: //druhe minus v rade znamena dekrementaci if (c == '-') { tok->typ = DECREMENTATION; strFree(&s); return 1; } //cokoli jineho znamena pouze minus else { pom = c; tok->typ = MINUS; strFree(&s); return 1; } break; case INCREMENT_OPERATOR: //druhe plus v rade je inkrementace if (c == '+') { tok->typ = INCREMENTATION; strFree(&s); return 1; } //pouze scitani else { pom = c; tok->typ = PLUS; strFree(&s); return 1; } break; default: break; } } }
//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; }
//vrati dlzku retazca int length( string * s1) { return strGetLength(s1); }