void PridatPom(sRamec *ramec, string *nazev, int typ, double cisloh, string *stringh){ int koren=0; sRamec *novy; while (!koren){/*dokud nezjistime kam podle nazvu novou pomocnou zaradit, tak cyklime*/ if( key(nazev, &ramec->nazev) == 2) {/*rozhodne, zda mame jit do praveho podstromu*/ if(ramec->rptr != NULL) ramec = ramec->rptr;/*kdyz neni pravy podstrom prazdny, tak opakujeme dalsi cyklus pro novy ramec*/ else { if((novy = (sRamec*) malloc(sizeof(sRamec)))==NULL) error(NULL,OTHER_RUNN_ERR,NULL);/*kdyz je pravy podstrom prazdny, tak malokujeme novy prvek a nastavime pravy ukazatel aktualniho prvku na novy*/ strInit(&novy->nazev); strCopyString(&(novy->nazev),nazev); ramec->rptr = novy; PridatHodnotu(novy, typ, cisloh, stringh); /*pomoci funkce PridatHodnotu vyplnime hodnotu prvku*/ return; /*ukoncime funkci*/ } } if( key(nazev, &ramec->nazev) == 1){/*rozhodne, zda mame jit do leveho podstromu*/ if(ramec->lptr != NULL) ramec = ramec->lptr; /*kdyz neni levy podstrom prazdny, tak opakujeme dalsi cyklus pro novy ramec*/ else { if((novy = (sRamec*) malloc(sizeof(sRamec)))==NULL) error(NULL,OTHER_RUNN_ERR,NULL);/*kdyz je levy podstrom prazdny, tak malokujeme novy prvek a nastavime levy ukazatel aktualniho prvku na novy*/ strInit(&novy->nazev); strCopyString(&(novy->nazev),nazev); ramec->lptr = novy; PridatHodnotu(novy, typ, cisloh, stringh); /*pomoci funkce PridatHodnotu vyplnime hodnotu prvku*/ return; /*ukoncime funkci*/ } } if( key(nazev, &ramec->nazev) == 0){ /*v pripade, ze se prvek shoduje, tak pouze nahradime jeho hodnotu volanim funkce PridatHodnotu*/ PridatHodnotu(ramec, typ, cisloh, stringh); return; /*ukoncime funkci*/ } } }
void GlobItemInsert(tGlobSymbolTable *T,string *nazev, int typ,Tridic *ridic, sGlobTableItem **novy){ int koren=0; if (((*novy) = (sGlobTableItem*) malloc(sizeof(sGlobTableItem)))==NULL) error(T,OTHER_RUNN_ERR,ridic);/*alokovani mista pro novy globálni uzel*/ sGlobTableItem *pomglob; strInit(&((*novy)->data.nazev));/*plneni uzlu*/ strCopyString(&((*novy)->data.nazev), nazev); (*novy)->data.typ = typ; (*novy)->lptr=NULL; (*novy)->rptr=NULL; (*novy)->data.def=1; strInit(&((*novy)->arg)); //strInit(&((*novy)->hodnota->stringh)); ridic->aktivG=(*novy); ridic->aktivG->link=NULL; if (T->first==NULL){/*pokud je strom prazdny*/ T->first=(*novy);/*pridame novy uzel na vrchol stromu*/ }else{ pomglob=T->first;/*nastavime pomocny ukazatel na vrchol stromu*/ koren=tableSearchGlob(ridic,&pomglob,&((*novy)->data.nazev));/*projdeme strom*/ } if (koren==1){ pomglob->lptr=(*novy);/*uzel vlozime nalevo*/ }else if (koren==2) { pomglob->rptr=(*novy);/*uzel vlozime napravo*/ } }
void VytvorRamec(sLokTableItem *koren, sRamec *novy){ if(koren != NULL){ novy->lptr = NULL; /*nastavi defaultne kazdemu novemu prvku ukazatele na NULL*/ novy->rptr = NULL; sRamec *pom;/*vytvori si pomocnou promenou*/ strInit(&(novy->nazev)); strCopyString((&novy->nazev), (&koren->data.nazev));/*kopiruje informace z tabulky symbolu*/ novy->typ = koren->data.typ; novy->hodnota.def = 0; /*nastavi definovanost prvku na 0 (tzn. neobsahuje hodnotu)*/ novy->hodnota.porarg = koren->poradi_argumentu; if(koren->lptr != NULL){ /*kdyz ma ukazatel na levy podstrom, tak:*/ if((pom = (sRamec*) malloc(sizeof(sRamec)))==NULL) error(NULL,OTHER_RUNN_ERR,NULL); /*malokuje misto pro novy prvek ramce*/ novy->lptr = pom; /*a aktualnimu prvku nastavi ukazatel na novy levy podstrom*/ VytvorRamec(koren->lptr, novy->lptr); /*a dale rekurzivne vola funkci VytvorRamec*/ } else novy->lptr = NULL; /*kdyz nema levy podstrom, pta se na pravy podstrom u ktereho postupuje obdobne jako u leveho*/ if(koren->rptr != NULL){ if((pom = (sRamec*) malloc(sizeof(sRamec)))==NULL) error(NULL,OTHER_RUNN_ERR,NULL); novy->rptr = pom; VytvorRamec(koren->rptr, novy->rptr); } else novy->rptr = NULL; } /*v pripade, ze nema ani jeden podstrom, tak se funkce ukonci a vraci se do rekurzivni funkce, v ktere byla predtim volana*/ }
void ungetToken(tToken* token) { if (token == NULL) { return; } if (!TQueue) { TQInit(); } tToken newTok = (tToken)malloc(sizeof(struct stToken)); tTokenQueueElem elm = (tTokenQueueElem)malloc(sizeof(struct tTQelem)); if (!newTok || !elm) { FatalError(99, ERR_MESSAGES[ERR_ALLOC]); } newTok->typ = (*token)->typ; if ((*token)->typ == TYPE_IDENTIFICATOR || (*token)->typ == TYPE_STRING) { strInit(&newTok->value.stringVal); strCopyString(&newTok->value.stringVal, &(*token)->value.stringVal); } else { newTok->value = (*token)->value; } freeTokenMem(token); elm->token = newTok; elm->rptr = elm->lptr= NULL; if (!TQueue->First) {//ve fronte nikdo neni TQueue->First = TQueue->Last = elm; } else {//nekdo ceka TQueue->Last->rptr = elm; elm->lptr = TQueue->Last; TQueue->Last = elm; } }
void TQDequeue(tToken* token) { if (token == NULL) { return; } if (!TQueue || !TQueue->First) {//neexistuje fronta nebo je prazdna token = NULL; return; } (*token) = (tToken)malloc(sizeof(struct stToken)); (*token)->typ = TQueue->First->token->typ; if ((*token)->typ == TYPE_IDENTIFICATOR || (*token)->typ == TYPE_STRING) { strInit(&(*token)->value.stringVal); strCopyString(&(*token)->value.stringVal, &TQueue->First->token->value.stringVal); } else { (*token)->value = TQueue->First->token->value; } //navazu odkazy tTokenQueueElem elm = TQueue->First; if (TQueue->First == TQueue->Last) {//toto byl posledni prvek fronty TQueue->First = TQueue->Last = NULL; freeTokenQueue(); } else { TQueue->First = elm->rptr; TQueue->First->lptr = NULL; } //uvolnime po sobe pamet freeTokenMem(&elm->token); free(elm); }
E_CODE functionInsertSymbol(tFunction* function,tString symbolname){ tSymbol *symb=mmuMalloc(sizeof(tSymbol)); strCopyString(&symbolname,&(symb->key)); //symb->type=DT_UNKNOWN; symb->data=NULL; E_CODE err=BTInsert(&(function->symbols),&(symb->key),symb); if (err!=ERROR_OK){strFree(&(symb->key));mmuFree(symb);} return err; }
static inline int tmpstr(char *str) { string tmp; tmp.str = str; tmp.length = strlen(str); if (!strCopyString(&tmp_buffer, &tmp)) return ERR_INTERPRET; return OK; }
E_CODE symbolTableInsertFunction(tSymbolTable* symbolTable, tString functionName){ tFunction *func=mmuMalloc(sizeof(tFunction)); strCopyString(&functionName,&(func->name)); // jmeno fce btInit(&(func->symbols)); // symboly initList(&(func->instructions)); // instrukce initList(&(func->constants)); func->called=1; E_CODE err=BTInsert(&(symbolTable->functions),&(func->name),func); if (err!=ERROR_OK){strFree(&(func->name));mmuFree(func);} return err; }
void PridatHodnotu(sRamec *ramec, int typ, double cisloh, string *stringh){ ramec->typ = typ; /*priradi prvku v ramci typ*/ if(typ == TP_STRING) { /*kdyz je typ string, tak preda retezec*/ strInit(&ramec->hodnota.stringh);/*kdyz je bool, int, nebo real, tak pouze priradi double*/ strCopyString(&(ramec->hodnota.stringh),stringh);/*nastavi definovanost prvku na 1*/ } else { ramec->hodnota.cisloh = cisloh; } ramec->hodnota.def = 1; return; }
tSymbol * functionInsertConstant(tFunction *function,tString data,tKeyword type){ if(function==NULL)return NULL; tSymbol *symb=mmuMalloc(sizeof(tSymbol)); if (symb == NULL) return NULL; symb->data=mmuMalloc(sizeof(tSymbolData)); if (symb->data == NULL) return NULL; switch(type){ case LEX_STRING:{ symb->data->type = DT_STRING; if (strCopyString(&data,&(symb->data->data.sData)) != ERROR_OK) {return NULL;} } break; case LEX_NUMBER:{ char *endptr = NULL; symb->data->type = DT_NUMBER; symb->data->data.dData=strtod(data.data, &endptr); // ATOF SE NEPOUZIVA, je to HNUSNA fce if (*endptr != '\0' || strcmp(endptr, data.data) == 0) { //*err = ERROR_SYNTAX; // toto je nejspis neco jinyho, ty tu kua nemas err...a ani ho nemas jak vratit mmuFree(symb); return NULL; } } break; case KW_NIL:{ symb->data->type = DT_NIL; } break; case KW_TRUE:{ symb->data->type = DT_BOOL; symb->data->data.bData = TRUE; } break; case KW_FALSE:{ symb->data->type = DT_BOOL; symb->data->data.bData = FALSE; } break; case LEX_ID:{ //funkce pro TypeOf symb->data->type = DT_FUNCTION; } break; default: return NULL; } symb->key.data=NULL; listInsertLast(&(function->constants),symb); return symb; }
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 }
/////////////////////////////////////////////////////////////////////////////// /// @brief Sends device information announce packet /// @param in_transmit_buffer Buffer for data storage static void comUDPSendDeviceAnounce(uint8_t* in_transmit_buffer) { uint16_t crc; comPacketDeviceAnnounce* info = (comPacketDeviceAnnounce*)in_transmit_buffer; uint32_t ip_address = drvUDPGetLocalIPAddress(); // fill packet header comFillPacketHeader(&info->Header, comPT_DEVICE_ANNOUNCE, sizeof(comPacketDeviceAnnounce)); // fill packet data members strCopyString(info->Name, comDEVICE_NAME_LENGTH, 0, cfgGetStringValue(cfgVAL_SYS_NAME)); info->UniqueID = cfgGetUInt32Value(cfgVAL_SYS_UID); info->Address = ip_address; // calculate CRC crc = crc16CalculateForBlock(crc16_INIT_VALUE, in_transmit_buffer, sizeof(comPacketDeviceAnnounce)); in_transmit_buffer[sizeof(comPacketDeviceAnnounce)] = sysLOW(crc); in_transmit_buffer[sizeof(comPacketDeviceAnnounce) + 1] = sysHIGH(crc); // send packet (Broadcast) drvUDPTransmitData(sizeof(comPacketDeviceAnnounce) + comCRC_BYTE_COUNT, comUDP_MAKE_BROADCAST_ADDRESS(ip_address)); }
void VytvorRamecGlob(sGlobTableItem *koren, sRamec *novy){ if(koren != NULL){/*postup je zde obdobny, jako u funkce VytvorRamec pro lokalni tabulky symbolu, ktera se nachazi nad touto funkci*/ novy->lptr = NULL; novy->rptr = NULL; sRamec *pom; strInit(&(novy->nazev)); strCopyString((&novy->nazev), (&koren->data.nazev)); novy->typ = koren->data.typ; novy->hodnota.def = 0; novy->hodnota.porarg = 0; if(koren->lptr != NULL){ if((pom = (sRamec*) malloc(sizeof(sRamec)))==NULL) error(NULL,OTHER_RUNN_ERR,NULL); novy->lptr = pom; VytvorRamecGlob(koren->lptr, novy->lptr); } else novy->lptr = NULL; if(koren->rptr != NULL){ if((pom = (sRamec*) malloc(sizeof(sRamec)))==NULL) error(NULL,OTHER_RUNN_ERR,NULL); novy->rptr = pom; VytvorRamecGlob(koren->rptr, novy->rptr); } else novy->rptr = NULL; } }
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 GlobTableInsert(tGlobSymbolTable *T, string *nazev, int typ,Tridic *ridic){/*vlozeni noveho uzlu do glob table*/ if (typ==FUNCTION_END){/*pokud je konec tela funkce*/ ridic->aktivG->data.def=1;/*definuj danou funkci*/ ridic->aktiv=NULL;/*uzel ztraci aktivitu*/ ridic->pomlog = 0;/*vynulovani ridicich promennych*/ ridic->pocet_argumentu=0; ridic->deklaration=0; // ridic->aktivG->link=NULL; return 1; } if (typ==FUNCTION_FORWARD){/*pokud se jedna o doprednou deklaraci funkce*/ sGlobTableItem *pomg; pomg=ridic->aktivG; ridic->pomlog = 0;/*vynulování ridicich promennych*/ ridic->pocet_argumentu=0; ridic->deklaration=0; if (pomg->data.def==1){/*pokud j*z byla funkce definovana, plati i pro dvakrat deklarovanou funkci*/ error(T,TAB_ERR,ridic);/*chyba v ramci tabulky*/ } return 1; } int koren=0; struct GlobTabItem *novy; sGlobTableItem *pomglob; if ((novy = (sGlobTableItem*) malloc(sizeof(sGlobTableItem)))==NULL) error(T,OTHER_RUNN_ERR,ridic);/*alokovani mista pro novy globálni uzel*/ strInit(&(novy->data.nazev));/*plneni uzlu*/ strCopyString(&(novy->data.nazev), nazev); novy->data.typ = typ; pomglob=NULL; novy->lptr=NULL; novy->rptr=NULL; strInit(&(novy->arg)); // strInit(&(novy->hodnota->stringh)); ridic->aktivG=novy; ridic->aktivG->link=NULL; pomglob=T->first;/*nastavime pomocny ukazatel na vrchol stromu*/ koren=tableSearchGlob(ridic,&pomglob,&(novy->data.nazev));/*projdeme strom*/ if (koren==0){/*uzel se stejnym klicem j*z byl nalezen*/ if (typ==FUNCTION_HEADER){/*pridavany prvek je funkce*/ if (pomglob->data.typ==FUNCTION_HEADER){/*nalezeny prvek je funkce*/ if (pomglob->data.def==0){/*funkce jeste nebyla definována*/ pomglob->data.def=1;/*nadefinujeme funkci*/ ridic->aktivG=pomglob;/*nastavime aktivitu na nas prvek*/ ridic->aktiv=ridic->aktivG->link;/*jako aktivni lokalni tabulku nastavime ukazatel na lok tabulku aktivni globalni tabullky*/ ridic->deklaration=1;/*nastavime, že budeme cist první argument fce*/ ItemFreeAktu(novy,NULL);/*uvolnime pripravovany uzel glob. tabulky*/ return 1; }else {ItemFreeAktu(novy,NULL);error(T,TAB_ERR,ridic);}/*chyba v ramci tabulky*/ }else {ItemFreeAktu(novy,NULL);error(T,TAB_ERR,ridic);}/*chyba v ramci tabulky*/ }else {ItemFreeAktu(novy,NULL);error(T,TAB_ERR,ridic);}/*chyba v ramci tabulky*/ }else if (koren==1){ pomglob->lptr=novy;/*uzel vlozime nalevo*/ }else if (koren==2) { pomglob->rptr=novy;/*uzel vlozime napravo*/ } novy->link=NULL; novy->data.def=0;/*novy prvek neni definovany*/ if(typ == FUNCTION_HEADER) {/*pokud se jedna o funkci*/ ridic->aktivG=novy;/*nastavime jako aktivni*/ ridic->pomlog = 1;/*jsme v hlavicce fce*/ } else {novy->link = NULL;}/*neobsahuje lokalni tabulku*/ return 1; }
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; } } }