/* get a production matching a particular name. Always returns something, but * may have NULL functionality */ struct Production *getProduction(const unsigned char *name) { struct Production *curp = productions; /* first production */ if (curp == NULL) { return (productions = newProduction(name)); } /* find a place to put it, or where it already is */ while (1) { int cmp = strcmp((char *) name, (char *) curp->name); if (cmp < 0) { if (curp->left) { curp = curp->left; } else { return (curp->left = newProduction(name)); } } else if (cmp > 0) { if (curp->right) { curp = curp->right; } else { return (curp->right = newProduction(name)); } } else { return curp; } } }
void addProductionsTest(){ printf("\nTesting Add Productions Method \n"); addProduction(getProductions(g1), newProduction('S',LAMDA,'A')); addProduction(getProductions(g1), newProduction('B',LAMDA,'C')); addProduction(getProductions(g1), newProduction('C',LAMDA,'D')); printGrammar(g1); printf("productions quant: %d\n", getQuant(getProductions(g1))); }
void grammar5Test(){ /*Gr5 = ({S, B, C}, {a,b, c}, S, {S->B | a, B->cC | \, C->bC})*/ GrammarADT grammar5 = newGrammar(); grammar5 = newGrammar(); setDistinguished(grammar5, 'S'); char * nonterminals1 = malloc(sizeof(char)*3); nonterminals1[0] = 'S'; nonterminals1[1] = 'B'; nonterminals1[2] = 'C'; setNonTerminals(grammar5,nonterminals1,3); char * term1 = malloc(sizeof(char)*3); term1[0] = 'a'; term1[1] = 'b'; term1[2] = 'c'; setTerminals(grammar5,term1,3); ProductionADT prod1 = newProduction('S','B',LAMDA); ProductionADT prod2 = newProduction('S','a',LAMDA); ProductionADT prod3 = newProduction('B','c','C'); ProductionADT prod4 = newProduction('B',LAMDA, LAMDA); ProductionADT prod5 = newProduction('C', 'b', 'C'); //ProductionsADT productions1 = newProductions(0); ProductionsADT productions1 = newProductions(5); setProduction(productions1,0,prod1); setProduction(productions1,1,prod2); setProduction(productions1,2,prod3); setProduction(productions1,3,prod4); setProduction(productions1,4,prod5); /*addProduction(productions1,prod1); addProduction(productions1,prod2); addProduction(productions1,prod3); addProduction(productions1,prod4);*/ setProductions(grammar5,productions1); printf("Before Nomalization\n"); printGrammar(grammar5); /*Conversion*/ AutomataADT automata1 = toAutomata(grammar5); printf("After Nomalization\n"); printGrammar(grammar5); printAutomata(automata1); }
void grammar1Test(){ //G1 = ({A, B, C}, {a, b, c},A, {A -> aB|c, B -> aA|b}) /*Initialization*/ GrammarADT grammar1 = newGrammar(); grammar1 = newGrammar(); setDistinguished(grammar1, 'A'); char * nonterminals1 = malloc(sizeof(char)*3); nonterminals1[0] = 'A'; nonterminals1[1] = 'B'; nonterminals1[2] = 'C'; setNonTerminals(grammar1,nonterminals1,3); char * term1 = malloc(sizeof(char)*3); term1[0] = 'a'; term1[1] = 'b'; term1[2] = 'c'; setTerminals(grammar1,term1,3); ProductionADT prod1 = newProduction('A','a','B'); ProductionADT prod2 = newProduction('A','c',LAMDA); ProductionADT prod3 = newProduction('B','a','A'); ProductionADT prod4 = newProduction('B',LAMDA,'b'); //ProductionsADT productions1 = newProductions(0); ProductionsADT productions1 = newProductions(4); setProduction(productions1,0,prod1); setProduction(productions1,1,prod2); setProduction(productions1,2,prod3); setProduction(productions1,3,prod4); /*addProduction(productions1,prod1); addProduction(productions1,prod2); addProduction(productions1,prod3); addProduction(productions1,prod4);*/ setProductions(grammar1,productions1); printf("Before Nomalization\n"); printGrammar(grammar1); /*Conversion*/ AutomataADT automata1 = toAutomata(grammar1); printf("After Nomalization\n"); printGrammar(grammar1); printAutomata(automata1); }
void init(){ g1 = newGrammar(); setDistinguished(g1, 'S'); nonterminals = malloc(sizeof(char)*5); nonterminals[0] = 'S'; nonterminals[1] = 'A'; nonterminals[2] = 'B'; nonterminals[3] = 'C'; nonterminals[4] = 'D'; setNonTerminals(g1,nonterminals,5); term = malloc(sizeof(char)*2); term[0] = 'a'; term[1] = 'b'; setTerminals(g1,term,2); /*S-> aA*/ p1 = newProduction('S','A','b'); /*A-> b*/ p2 = newProduction('A','b',LAMDA); /*B-> aB*/ p7 = newProduction('B','B','b'); /*A-> bA*/ p3 = newProduction('A','B','\\'); /*A-> aB*/ p8 = newProduction('A','B','a'); /*B-> ab*/ //p4 = newProduction('B','c','b'); /*A-> bB*/ //p5 = newProduction('A','b','B'); /*A-> aB*/ //p6 = newProduction('A',LAMDA,'B'); prods = newProductions(5); setProduction(prods,0,p1); setProduction(prods,1,p2); setProduction(prods,2,p7); setProduction(prods,3,p3); setProduction(prods,4,p8); // setProduction(prods,5,p4); // setProduction(prods,6,p5); // setProduction(prods,7,p6); setProductions(g1,prods); }
void removeParticularProductionTest(){ printf("\nTesting Remove Particular Productions Method \n"); removeParticularProduction(getProductions(g1), newProduction('A',LAMDA,'b')); /*remove non terminals and terminals that are no longer there */ actualizeTerminals(g1); actualizeNonTerminals(g1); printGrammar(g1); printf("productions quant: %d\n", getQuant(getProductions(g1))); }
bool GrammarSymbol::addProduction(const std::vector<GrammarSymbol*>& body, int& productionIDCounter_) { Production newProduction(productionIDCounter_++, this, body); bool exists = false; for (size_t i = 0; ((exists == false) && (i < productions_.size())); ++i) exists = (productions_[i] == newProduction); if (exists == false) { productions_.push_back(newProduction); return true; } else --productionIDCounter_; return false; }
void removeUnitaryProductions(GrammarADT grammar) { ProductionsADT productions = getProductions(grammar); int i,j,k, productionquant = getQuant(productions), unitaryquant = 0, lastunitaryquant = 0; /*auxiliar array for unitary productions*/ char * unitaries = NULL; /*iterate over productions and determine first unitaries: * the productions that have only one non terminal symbol * on the right side */ for (i=0; i< productionquant; i++) { char first = getProductionComponent(getProduction(productions,i),0); char sec = getProductionComponent(getProduction(productions,i),1); char third = getProductionComponent(getProduction(productions,i),2); if ( isNonTerminal(sec) && third == LAMDA ) { addPair(&unitaries,&unitaryquant,first, sec); } else if( isNonTerminal(third) && sec == LAMDA) { addPair(&unitaries,&unitaryquant,first, third); } } /*iterate over unitaries, adding the closure*/ while(unitaryquant != lastunitaryquant) { lastunitaryquant = unitaryquant; for (i=0; i<unitaryquant ; i+=2) { char first1 = unitaries[i]; char sec1 = unitaries[i+1]; for (j=0; j<unitaryquant ; j+=2) { char first2 = unitaries[j]; char sec2 = unitaries[j+1]; /*(A,B)(B,C)-> (A,C)*/ if (sec1 == first2 ) { if (!containsPair(unitaries,unitaryquant,first1,sec2) && first1 != sec2 ) { /*no sense in adding (A,A) unitaries*/ addPair(&unitaries,&unitaryquant,first1,sec2); } } } } } /*Debug*/ //printByPairs(unitaries,unitaryquant); //printf("unitaries quant: %d\n\n", unitaryquant/2); /*create the new productions and remove the unitaries*/ for(i=0; i<productionquant; i++) { ProductionADT p1 = getProduction(productions,i); if ( isUnitary(p1) ) { char first1 = getProductionComponent(p1,0); char sec1 = getProductionComponent(p1,1); char third1 = getProductionComponent(p1,2); for(j=0; j<unitaryquant; j+=2) { char uni1 = unitaries[j]; char uni2 = unitaries[j+1]; //A->B and (A,B) (unitary production is localized) if ((first1 == uni1) && (sec1 == uni2 || third1 == uni2 )) { for(k=0; k<productionquant; k++ ) { ProductionADT p2 = getProduction(productions,k); char first2 = getProductionComponent(p2,0); char sec2 = getProductionComponent(p2,1); char third2 = getProductionComponent(p2,2); if(!isUnitary(p2)) { if(first2 == uni2 ) { addProduction(productions,newProduction(first1,sec2,third2)); } } } } } removeParticularProduction(productions,p1); free(p1); } } /*remove non terminals and terminals that are no longer there */ actualizeTerminals(grammar); actualizeNonTerminals(grammar); actualizeProductions(grammar); }
void convertToRight(GrammarADT grammar) { int i; int ml = FALSE; char oldistiguished = getDistinguished(grammar); /*if the grammar is already right there is no * reason to convert it*/ if ( isRight(grammar) ) { return; } ProductionsADT productions = getProductions(grammar); int quantproductions = getQuant(productions); for(i = 0; i < quantproductions ; i++) { ProductionADT p1 = getProduction(productions, i); char first = getProductionComponent(p1, 0); char sec = getProductionComponent(p1, 1); char third = getProductionComponent(p1, 2); if(isNonTerminal(sec)) { addProduction(productions, newProduction(sec , third, first)); removeParticularProduction(productions,p1); } } setProductions(grammar, productions); /*a new nonTerminal should be created , * that joint the non terminals that were joined to lambda*/ char * leftnontermssymbols = NULL; int size=0; for(i=0; i < quantproductions; i++) { ProductionADT p1 = getProduction(productions, i); char first = getProductionComponent(p1, 0); char sec = getProductionComponent(p1, 1); char third = getProductionComponent(p1, 2); if(sec == LAMDA && third == LAMDA) { addChar(&leftnontermssymbols,&size,first); } } /*get a new distiguished symbol*/ char newsymbol = getNewSymbol(grammar); setDistinguished(grammar,newsymbol); /*generate new unitary productions*/ for(i=0; i<size; i++) { ProductionADT newprod = newProduction(newsymbol,leftnontermssymbols[i],LAMDA); //printProduction(newprod); addProduction(productions, newprod); } /*remove all old lambda productions*/ for(i=0; i<getQuant(productions); i++) { ProductionADT p = getProduction(productions,i); char sec = getProductionComponent(p,1); char third = getProductionComponent(p,2); /*if it is a lamda productions : delete*/ if( sec == LAMDA && third == LAMDA ) { removeParticularProduction(productions,p); } } if(!ml) { addProduction(productions, newProduction(oldistiguished, LAMDA, LAMDA)); } setProductions(grammar,productions); /*remove non terminals and terminals that are no longer there */ actualizeTerminals(grammar); actualizeNonTerminals(grammar); actualizeProductions(grammar); }
void removeOnlyRightTerminals(GrammarADT grammar) { int j; int found = FALSE; char newsymbol; ProductionsADT productions = getProductions(grammar); /*search for A->a like productions*/ for(j=0; j< getQuant(getProductions(grammar)); j++) { ProductionADT p = getProduction(productions,j); char sec = getProductionComponent(p,1); char third = getProductionComponent(p,2); if( ( isTerminal(sec) && third == LAMDA ) || ( isTerminal(third) && sec == LAMDA ) ) { found = TRUE; break; } } /*if there are not productions with only terminals in the right side * ,go away*/ if(!found) { return; } /*search for the new symbol to insert*/ newsymbol = getNewSymbol(grammar); /*add new symbol to the nonterminals array*/ char * term = getNonTerminals(grammar); int termquant = getQuantNonTerminals(grammar); char * aux = realloc(term, (termquant+1)*sizeof(char)); if(aux == NULL) { printf("Error: Not enought memory\n"); exit(1); } term = aux; term[termquant] = newsymbol; termquant++; setNonTerminals(grammar, term, termquant); int isright = isRight(grammar) ; int productionquant = getQuant(getProductions(grammar)); /*create the new productions with the new symbol*/ for(j=0; j< productionquant ; j++) { ProductionADT p = getProduction(getProductions(grammar),j); char sec = getProductionComponent(p,1); char third = getProductionComponent(p,2); /*is the production have only one terminal symbol on the right side */ if ( isTerminal(sec) && third == LAMDA ) { /*if the grammar is right sided the new symbol should be * added to the right*/ if( isright ) { setProductionComponent(p, 1, sec ); setProductionComponent(p, 2, newsymbol); } else { setProductionComponent(p, 2, sec ); setProductionComponent(p, 1, newsymbol); } } else if( isTerminal(third) && sec == LAMDA) { if( isright ) { setProductionComponent(p, 1, third ); setProductionComponent(p, 2, newsymbol); } else { setProductionComponent(p, 1, newsymbol); setProductionComponent(p, 2, third ); } } } addProduction(getProductions(grammar), newProduction(newsymbol,LAMDA,LAMDA)); /*remove non terminals and terminals that are no longer there */ actualizeTerminals(grammar); actualizeNonTerminals(grammar); return; }