Пример #1
0
tChyba addArgument( char *key )
{
	//kopirovani argumentu
	//nalezeni funkce v globalce
	TItem *item = htSearch( ptrhtGlobal, porovnani );
	if(!item){
		return S_SEMANTICKA_CHYBA_NEDEF;
	}
	//projiti parametru funkce v jeji deklaraci
	for (int i = 0; i < item->data->param.numParam; ++i){
		//nalezeni paramtru ve funkci
		TItem *item2 = htSearch( ptrhtLocal, item->data->param.param[i] );
		if( item2 ){
			//nalezeni data argumentu v predchozi funkci
			TItem *item3 = searchFrames(key, ptrhtLastLocal, ptrhtGlobal );
			if( item3 ){
				item2->data = item3->data;
			}
			else{
				item2->data = createData( token.stav, key ); //nenalezeno, zadana raw hodnota
			}
			item2->init = true;
			return S_BEZ_CHYB;
		}
	}
	return S_SEMANTICKA_CHYBA_NEDEF;
}
Пример #2
0
TItem* searchFrames( char *key, tHTable *ptrLocal, tHTable *ptrGlobal )
{
	TItem *tmp = htSearch( ptrLocal, key );
	if( !tmp ){
		tmp = htSearch( ptrGlobal, key );
	}
	return tmp;
}
Пример #3
0
tChyba ROZHODNI() {
	
	int analyza2;
	int analyza;
	int analyza1;
	TItem *pt;
	//ROZHODNI->DTYPE	
	if((analyza = DTYPE()) == S_BEZ_CHYB) {
		token = getNextToken();
		if(token.stav == s_lex_error) {
			return S_LEXIKALNI_CHYBA;
		}	
		return S_BEZ_CHYB;
	}
	//ROZHODNI->PROM VESTAV EXPR
	else {
		//volani funkce na vestavene funkce	
		analyza2 = VESTAV();
		if(analyza2 != S_BEZ_CHYB && analyza2 != S_EPS) {
			return analyza2;
		}
		//pokud je epsilon pokracujeme dal
		if(analyza2 == S_BEZ_CHYB) {
			return S_BEZ_CHYB;
		}
				
		if((porovnani = malloc(strlen(token.data)+1)) == NULL) {
			return S_INTERNI_CHYBA;
		}
		//ulozeni hodnoty token.data do globalni promenne porovnani
		strcpy(porovnani, token.data);
		pt = htSearch(ptrhtGlobal, token.data);		
		//kontrola jestli id je v tabulce globalni	
		if(pt != NULL && pt->druh == ID_FUNCTION) {		
			//pokud ano a je to funkce vola se prom
			analyza1 = PROM();
			if(analyza1 != S_BEZ_CHYB) {
				return analyza1;
			}
				
			free(porovnani);
			return S_BEZ_CHYB;	
		}
		else {//jinak se vola precedencni	
			analyza2 = precedencniSA();
			if(analyza2 != S_BEZ_CHYB) {
				return analyza2;
			}
			
			//instrukce pro prirazeni, tmp1 je vysledek precedencni, tmp3 cilove id
			generateInstruction( OC_PRIRAZENI, searchFrames(neterminal.polozkaTS.key, ptrhtLocal, ptrhtGlobal), NULL, searchFrames(id, ptrhtLocal, ptrhtGlobal) );
				
			return S_BEZ_CHYB;
				
		}
	}
}
Пример #4
0
tChyba DOPREDNE() {
	int ret;
	TItem *nasel;
	//DOPREDNE->forward
	if(!strcmp(token.data, "forward") && token.stav == s_klicove) {			
		//neinicializovana pokud se jedna o doprednou deklaraci
		init = false;						
		token = getNextToken();
		if(token.stav == s_lex_error) {
			return S_LEXIKALNI_CHYBA;
		}
		return S_BEZ_CHYB;
	}
	//DOPREDNE->ACT_LIST
	else {
		//initla, pokud se nejedna o doprednou
		init = true;
		// check velikost tabulky
		if( currFuncSize == funcSize ){
			ret = resizeFuncField();
			if(ret != S_BEZ_CHYB) {
				return ret;
			}
		}	

		
		//nastaveni klice funkce
		func[currFuncSize].key = allocString(funkce);

		//inicializace tabulky
		ret = htInit(&func[currFuncSize].table );
		if(ret != S_BEZ_CHYB) {
			return ret;
		}
		//vytovreni listu instrukci
		InitList( &(func[currFuncSize].instrList) );
		//nastaveni ukazatele na prave vytvoreny list instrukci
		listIntrukci = &(func[currFuncSize].instrList);
		//nastaveni ukazatele na aktualni tabulku symbolu
		ptrhtLocal = func[currFuncSize].table;
		//inkrementace indexu 
		currFuncSize++;
		
		nasel = htSearch(ptrhtGlobal, funkce);		
		if(nasel != NULL) {
			//nakopirovani parametru do lokalniho ramce
			for(int i=0; i < nasel->data->param.numParam; i++) {
				htDeclInsert(ptrhtLocal, nasel->data->param.param[i], nasel->data->param.typeParam[i], ID_PARAM);	
			}
		}	
		return ACT_LIST();
	}
}
Пример #5
0
tChyba copyTable( TFunction *source )
{
	TItem *tmp;
	int ret;
	for (int i = 0; i < MAX_HTSIZE; ++i){
		tmp = (*(source->table))[i];
		if( tmp ){
			//dmnce karlova
			if( tmp->druh == ID_FUNCTION ){
				ret = htInsert( ptrhtLocal, tmp->key, copyData( tmp->druh, tmp->data), tmp->type, tmp->druh );
			}
			else if( tmp->druh == ID_PARAM ){
				ret = htInsert( ptrhtLocal, tmp->key, NULL, tmp->type, tmp->druh );
			}
			else ret = htInsert( ptrhtLocal, tmp->key, copyData( tmp->type, tmp->data), tmp->type, tmp->druh );

			if(ret != S_BEZ_CHYB) {
				return ret;
			}
			//ret = htCompleteInsert(ptrhtLocal, tmp->key, tmp->druh, tmp->type, tmp->init);
			//if(ret != S_BEZ_CHYB) {
			//	return ret;
			//}
		}
	}
	//zkopiruje cely list instrukci
	ret = CopyList( &(source->instrList) );
	if(ret != S_BEZ_CHYB) {
		return ret;
	}
	//ustanoveni dat
	tItemPtr ptr = listIntrukci->First;
	while(ptr){
		TItem *item;
		if( ptr->instruction.instructionType == OC_COLL ){
			ptr->instruction.instructionType = OC_CALL;
			//nastaveni navratovky
			item = (TItem*)ptr->instruction.address1;
			ptr->instruction.address3 = htSearch( ptrhtLocal, item->key );
		}
		else if( ptr->instruction.instructionType == OC_NEPRIRAZENI ){
			ptr->instruction.instructionType = OC_PRIRAZENI;
			//navratovka je zdroj
			ptr->instruction.address1 = item;
			//htSearch( ptrhtLastLocal, id )
			//dodelat nalezeni cile ulozeni
		}
		else{
			if( ptr->instruction.address1 ){
				TItem *tmp1 = (TItem*)ptr->instruction.address1;
				//write
				if( tmp1->druh != PRINTSTR ){
					ptr->instruction.address1 = htSearch( ptrhtLocal, tmp1->key );
				}
			}
			if( ptr->instruction.address2 ){
	        	TItem *tmp2 = (TItem*)ptr->instruction.address2;
				ptr->instruction.address2 = htSearch( ptrhtLocal, tmp2->key );
			}
			if( ptr->instruction.address3 ){
	        	TItem *tmp3 = (TItem*)ptr->instruction.address3;
				ptr->instruction.address3 = htSearch( ptrhtLocal, tmp3->key );
			}
		}
		ptr = ptr->nextItem;
	}
	return S_BEZ_CHYB;
}
	tHTItem* item = (*ptrht)[index];

	while(item != NULL)
	{
		if(strcmp(item->key, key) == 0) return item;
		item = item->ptrnext;
	}


	return NULL;
}


void htInsert ( tHTable* ptrht, tKey key, tData data ) {

	tHTItem *new, *item = htSearch(ptrht, key);

	if(item == NULL)
	{
		int index = hashCode(key);
		item = (*ptrht)[index];
		new = malloc(sizeof(tHTItem));

		if(new == NULL)
		{
			//TODO
		}

		new->ptrnext = item;
		new->data = data;
		new->key = malloc(strlen(key)+1);
Пример #7
0
tChyba TERM2() {
	int analyza;
	TItem *pt2;
	TItem *pt;
	bool nasel = false;
	//TERM2->( DRUH TERM2
	if(token.stav == s_leva_zavorka) {
			token = getNextToken();
			if(token.stav == s_lex_error) {
				return S_LEXIKALNI_CHYBA;
			}
		if(token.stav == s_cele_cislo || token.stav == s_desetinne_cislo || token.stav == s_logicka_hodnota || token.stav == s_string || token.stav == s_identifikator) {
			analyza = DRUH();
			if(analyza != S_BEZ_CHYB) {
				return analyza;
			}//pokud nejsme v definici funkce, pridej do nove vznikleho ramce zadany argument
			if(byla_funkce == false) {
				int ret = addArgument(token.data);
				if( ret != S_BEZ_CHYB ){
					return ret;
				}
			}
			//vyhledani volane funkce
			pt = htSearch(ptrhtGlobal, porovnani);
			//vyhledani funkce, ve ktere se vola funkce
			pt2 = htSearch(ptrhtGlobal, funkce); 
			if(token.stav == s_identifikator) {
					//pokud to bylo id
				if(pt != NULL) {
					for (int i = 0; i < pt2->data->param.numParam; ++i){			//prochazime pole parametru
						if(!strcmp(token.data, pt2->data->param.param[i])) {		//pokud najdeme parametr tak nastavime na true
							if(pt->data->param.typeParam[i] != pt2->data->param.typeParam[i]) { //kontrolujeme jestli datove typy parametru jsou stejne
								return S_SEMANTICKA_CHYBA_TYPOVA;
							}

							nasel = true;
							break;
						}				
					}

					if(nasel != true) { //POKUD NENI PARAMETR PROJDEME 
						pt2 = searchFrames(token.data, ptrhtLocal, ptrhtGlobal); 
						if(pt2 != NULL) {
							//kontrola datovych typu parametru funkce a argumentu		
							if(pt->data->param.typeParam[pocitadlo] != pt2->type) {
								return S_SEMANTICKA_CHYBA_TYPOVA;
							}		
						}	
						else {
							return S_SEMANTICKA_CHYBA_NEDEF;
						}
					}		
				}	
				else {
					return S_SEMANTICKA_CHYBA_NEDEF;
				}			

				nasel = false;
			}
			else {
				if(pt != NULL) {
					if(token.stav != pt->data->param.typeParam[pocitadlo]) {
						return S_SEMANTICKA_CHYBA_TYPOVA;
					}
				}
				else {
					return S_SEMANTICKA_CHYBA_NEDEF;
				}	
			}

			token = getNextToken();
			if(token.stav == s_lex_error) {
				return S_LEXIKALNI_CHYBA;
			}
			pocitadlo++;
			return TERM2();
		}	
	}
	//TERM2->, DRUH TERM2
	else if(token.stav == s_carka) {
		token = getNextToken();
		if(token.stav == s_lex_error) {
			return S_LEXIKALNI_CHYBA;
		}
		//pridani argumentu do vznikle tabulky
		if(byla_funkce == false) {
			int ret = addArgument(token.data);
			if( ret != S_BEZ_CHYB ){
				return ret;
			}
		}
		if(token.stav == s_cele_cislo || token.stav == s_desetinne_cislo || token.stav == s_logicka_hodnota || token.stav == s_string || token.stav == s_identifikator) {
			analyza = DRUH();
			if(analyza != S_BEZ_CHYB) {
				return analyza;
			}
			//vyhledani volane funkce
			pt = htSearch(ptrhtGlobal, porovnani);
			//vyhledani funkce, ve ktere se vola funkce
			pt2 = htSearch(ptrhtGlobal, funkce); 
			if(token.stav == s_identifikator) {
				if(pt != NULL) {	
					for (int i = 0; i < pt2->data->param.numParam; ++i){
						if(!strcmp(token.data, pt2->data->param.param[i])) {
							//kontrola zda souhlasi datove typy parametru 2 funkci
							if(pt->data->param.typeParam[i] != pt2->data->param.typeParam[i]) {
								return S_SEMANTICKA_CHYBA_TYPOVA;
							}

							nasel = true;
							break;
						}				
					}
					//pokud to neni parametr, kontrola jestli je id v tabulkach
					if(nasel != true) {
						pt2 = searchFrames(token.data, ptrhtLocal, ptrhtGlobal);
						if(pt2 != NULL) {			
							if(pt->data->param.typeParam[pocitadlo] != pt2->type) {
								return S_SEMANTICKA_CHYBA_TYPOVA;
							}	
						}
						else {
							return S_SEMANTICKA_CHYBA_NEDEF;
						}
					}		
				}	
				else {
					return S_SEMANTICKA_CHYBA_NEDEF;
				}			
				
				nasel = false;
			}
			else {//kontrola datovych typu
				if(token.stav != pt->data->param.typeParam[pocitadlo]) {
					return S_SEMANTICKA_CHYBA_TYPOVA;
				}
			}	

		}

		token = getNextToken();
		if(token.stav == s_lex_error) {
			return S_LEXIKALNI_CHYBA;
		}

		pocitadlo++;
		return TERM2();
		
	}
	else if(token.stav == s_prava_zavorka) {
		pt = htSearch(ptrhtGlobal, porovnani);			
		//zjistime, zda pocet zadanych parametru odpovida poctu parametru pri deklaraci funkce
		if(pocitadlo != pt->data->param.numParam) {
			return S_SEMANTICKA_CHYBA_TYPOVA;
		}
		
		if(byla_funkce == true) {//pokud jsme v definici funkce
			//generovani instrukce fake call
			generateInstruction(OC_COLL, htSearch(ptrhtGlobal, porovnani ), NULL, NULL );
			generateInstruction(OC_NEPRIRAZENI, NULL, NULL, NULL );
		}
		else{
			//vygenerovani instrukci InsertFirst
			for (int i = 0; i < MAX_HTSIZE; ++i){
				if( (*ptrhtLocal)[i] ){
					if( (*ptrhtLocal)[i]->druh == ID_FUNCTION  ){
						generateCopyInstr(OC_CPY, (*ptrhtLocal)[i], NULL, NULL );
					}
				}
			}
			//predchozi list instrukci, protoze se volal push
			listIntrukci = &(ptrStack->top->lower->field);
			//htPrintTable(ptrhtGlobal);
			//param CALL, Funkce v GLOBALCE, NULL, NAVRATOVKA
			generateInstruction(OC_CALL, htSearch(ptrhtGlobal, porovnani ), NULL, htSearch( ptrhtLocal, porovnani ) );
			//PRIRAZ, NAVRATOVKA, NULL, IDCKO
			generateInstruction(OC_PRIRAZENI, htSearch( ptrhtLocal, porovnani ), NULL, searchFrames( id, ptrhtLastLocal, ptrhtGlobal ) );
			//nastaveni spravneho listu instrukci
			listIntrukci = &(ptrStack->top->field);
			//instrukce return na konci volane fce
			generateInstruction(OC_RET, NULL, NULL, NULL );
		}
		//globalni promenna -> musime nulovat
		pocitadlo = 0;								 
		token = getNextToken();
		if(token.stav == s_lex_error) {
			return S_LEXIKALNI_CHYBA;
		}
		return S_BEZ_CHYB;
	}
	return S_SYNTAKTICKA_CHYBA;
}
Пример #8
0
tChyba FUNKCE() {
	int analyza;
	//opet lokalni promenna, stejna funkce jako ve funkci nahore
	TItem *nasel;
	// FUNKCE-> begin ACT_LIST
	if(!strcmp(token.data, "begin") && token.stav == s_klicove) {
		token = getNextToken();			//pres strcmp porovnavam data tokenu (prakticky primo to, co se nacte)
		if(token.stav == s_lex_error) {
			return S_LEXIKALNI_CHYBA;
		}
		//po zavolani funkce se getToken nevola, protoze kazda funkce, nez vrati hodnotu, nacte dalsi token
		analyza = ACT_LIST();			
		if(analyza != S_BEZ_CHYB) {
			return analyza;
		}
		return S_BEZ_CHYB;
	}
	//FUNKCE->function id PARAMS : DTYPE ; DOPREDNE ; FUNKCE
	else if(!strcmp(token.data, "function") && token.stav == s_klicove) {
		//pamatujeme si, ze jsme v definici funkce
		byla_funkce = true;				
		token = getNextToken();
		if(token.stav == s_lex_error) {
			return S_LEXIKALNI_CHYBA;
		}

		if(token.stav == s_identifikator) {	
			//pokud id ma nazev stejny jako tyto 2 funkce, jedna se o chybu
			if(!strcmp(token.data, "length") || !strcmp(token.data, "copy")) {
				return S_SEMANTICKA_CHYBA_NEDEF;
			}

			if((funkce = malloc(strlen(token.data)+1)) == NULL) {	
				return S_INTERNI_CHYBA;
			}
			//nulovani poctu parametru funkce
			TData *dat = (TData*)malloc(sizeof(TData));
			dat->param.numParam = 0;
			
			strcpy(funkce, token.data);
			//pokud id funkce j*z je v globalni hash tabulce a nejedna se o doprednou deklaraci -> chyba
			nasel = htSearch(ptrhtGlobal,funkce);		
			if(nasel != NULL ) {
				if(nasel->init == true) {
					return S_SEMANTICKA_CHYBA_NEDEF;
				}
				nasel->init = true;
			}
			//vlozeni nazvu funkce do globalni hash
			htInsert(ptrhtGlobal,funkce,dat, TYPEUNDEF , ID_FUNCTION);		

			token = getNextToken();
			if(token.stav == s_lex_error) {
			return S_LEXIKALNI_CHYBA;
			}
			//funkce na kontrolu a ukladani parametru funkce
			analyza = PARAMS();
			if(analyza != S_BEZ_CHYB) {
				return analyza;
			}
				
			else if(token.stav == s_dvojtecka) {
				token = getNextToken();
				if(token.stav == s_lex_error) {
					return S_LEXIKALNI_CHYBA;
				}
				//funkce na kontrolu datovych typu	
				analyza = DTYPE();
				if(analyza != S_BEZ_CHYB) {
					return analyza;
				}
										
				if(!strcmp(token.data, "integer")) {
					dtype = TYPEINT;
				}
				else if(!strcmp(token.data, "real")) {				//do docasne promene nacteme datovy typ funkce
					dtype = TYPEDOUBLE;
				}
				else if(!strcmp(token.data, "string")) {
					dtype = TYPESTR;
				}
				else if(!strcmp(token.data, "boolean")) {
					dtype = TYPEBOOL;
				}
					
				token = getNextToken();
				if(token.stav == s_lex_error) {
					return S_LEXIKALNI_CHYBA;
				}
	
				else if(token.stav == s_strednik) {
					token = getNextToken();
					if(token.stav == s_lex_error) {
						return S_LEXIKALNI_CHYBA;
					}
					//zjisteni, zda se jedna o doprednou deklaraci funkces
					analyza = DOPREDNE();
					if(analyza != S_BEZ_CHYB) {
						return analyza;
					}
					//pokud neni dopredna, vkladame do globalni hash tabulky a zaroven i do lokalni hash tabulky
					if(init == true) {
						htCompleteInsert(ptrhtGlobal,funkce, ID_FUNCTION, dtype, true);				
						htInsert(func[currFuncSize-1].table, funkce, dat, dtype, ID_FUNCTION);
							
					}//pokud se jedna o doprednou deklaraci, ukladame jen do globalky hlavicku funkce																			
					else if (init == false) {
						htCompleteInsert(ptrhtGlobal,funkce, ID_FUNCTION, dtype, false);	
						

							//vlozeni navratove hodnoty do lokalni tabulky
					}
						
					if(token.stav == s_strednik) {
							
						token = getNextToken();
						if(token.stav == s_lex_error) {
							return S_LEXIKALNI_CHYBA;
						}
						else {
							//nastaveni ukazatele lokalni tabulky na vrchol zasobniku
							ptrhtLocal = ptrStack->top->ptrht;
							listIntrukci = &(ptrStack->top->field);
							// nastaveni tabulky instrukci v mainu
							byla_funkce = false;
							//rekurzivni volani 
							return FUNKCE();
						}								
					}
				}
			}
		}
		//pokud se nacte token, ktery podle pravidla tam nepatri, vrati se syntakticka chyba
		return S_SYNTAKTICKA_CHYBA;		
	}
	//FUNKCE->var DEKLARACE FUNKCE
	else if(!strcmp(token.data, "var") && token.stav == s_klicove) {
		token = getNextToken();
		if(token.stav == s_lex_error) {
			return S_LEXIKALNI_CHYBA;
		}
		//volani funkce na kontrolu a ukladani globalnich id
		analyza = DEKLARACE();
		if(analyza != S_BEZ_CHYB) {
			return analyza;
		}
		return FUNKCE();
	}
	return S_SYNTAKTICKA_CHYBA;
}