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 Grammar::addClosureProductions() { bool stable; do { stable = true; for(int p = 0; p < getProductionCount(); p++) { Production &prod = m_productions[p]; const int length = prod.getLength(); for(int s = 0; s < length; s++) { RightSideSymbol &symbol = prod.m_rightSide[s]; switch(symbol.m_modifier) { case NO_MODIFIER: continue; case ZEROORONE : // ? { Production copy(prod); symbol.m_modifier = NO_MODIFIER; copy.m_rightSide.removeIndex(s); addProduction(copy); stable = false; } break; case ZEROORMANY : // * case ONEORMANY : // + { GrammarSymbol &m = getSymbol(symbol); String ntName = m.m_name + _T("_plus"); int nt = findSymbol(ntName); if(nt < 0) { nt = addNonTerminal(ntName, prod.m_pos); Production newProd1(nt, prod.m_pos); newProd1.m_rightSide.add(RightSideSymbol(nt, NO_MODIFIER)); newProd1.m_rightSide.add(RightSideSymbol(symbol, NO_MODIFIER)); addProduction(newProd1); Production newProd2(nt, prod.m_pos); newProd2.m_rightSide.add(RightSideSymbol(symbol, NO_MODIFIER)); addProduction(newProd2); } symbol.m_index = nt; symbol.m_modifier = (symbol.m_modifier == ZEROORMANY) ? ZEROORONE : NO_MODIFIER; stable = false; } break; default: throwException(_T("Invalid modifier in production %s. (=%d)"), getProductionString(p).cstr(), symbol.m_modifier); break; } // end switch } // end for(s... } //end for(p... } while(!stable); }
errorCode cloneProtoGrammar(ProtoGrammar* src, ProtoGrammar* dest) { errorCode tmp_err_code = UNEXPECTED_ERROR; ProtoRuleEntry* pRuleEntry; Index i; Index j; tmp_err_code = createProtoGrammar(src->count, dest); if(tmp_err_code != ERR_OK) return tmp_err_code; dest->contentIndex = src->contentIndex; for (i = 0; i < src->count; i++) { tmp_err_code = addProtoRule(dest, src->rule[i].count, &pRuleEntry); if(tmp_err_code != ERR_OK) return tmp_err_code; for (j = 0; j < src->rule[i].count; j++) { tmp_err_code = addProduction(pRuleEntry, src->rule[i].prod[j].eventType, src->rule[i].prod[j].typeId, src->rule[i].prod[j].qnameId, src->rule[i].prod[j].nonTermID); if(tmp_err_code != ERR_OK) return tmp_err_code; } } return ERR_OK; }
Grammar::Grammar(Language language, const ParserTables &src) : m_stateMap(stateCoreHashFunction, stateCoreCompareFunction, 4001) , m_unfinishedSet(1001) { m_language = language; m_verboseLevel = 0; m_terminalCount = 0; SourcePosition dummyPos; for(unsigned int t = 0; t < src.getTerminalCount(); t++) { addTerminal(src.getSymbolName(t), TERMINAL, 0, dummyPos); } for(unsigned int nt = src.getTerminalCount(); nt < src.getSymbolCount(); nt++) { addNonTerminal(src.getSymbolName(nt), dummyPos); } for(unsigned int p = 0; p < src.getProductionCount(); p++) { Production production(src.getLeftSymbol(p), dummyPos); unsigned int rightSide[256]; // guess there is no more than 256 symbols on the rightside of any Production src.getRightSide(p, rightSide); for(unsigned int s = 0; s < src.getProductionLength(p); s++) { production.m_rightSide.add(RightSideSymbol(rightSide[s], NO_MODIFIER)); } addProduction(production); } }
Production newProduction(Grammar g){ Production p=malloc(sizeof(production)); p->productive=false; p->visited=false; addProduction(g,p); return p; }
errorCode cloneProtoGrammar(ProtoGrammar* src, ProtoGrammar* dest) { errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR; ProtoRuleEntry* pRuleEntry; Index i; Index j; TRY(createProtoGrammar(src->count, dest)); dest->contentIndex = src->contentIndex; for (i = 0; i < src->count; i++) { TRY(addProtoRule(dest, src->rule[i].count, &pRuleEntry)); for (j = 0; j < src->rule[i].count; j++) { TRY(addProduction(pRuleEntry, GET_PROD_EXI_EVENT(src->rule[i].prod[j].content), src->rule[i].prod[j].typeId, src->rule[i].prod[j].qnameId, GET_PROD_NON_TERM(src->rule[i].prod[j].content))); } } return EXIP_OK; }
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; }