示例#1
0
文件: packrat.c 项目: GregorR/plof3
/* create a nonterminal given only names */
struct Production *newPackratNonterminal(unsigned char *name, unsigned char ***sub)
{
    struct Production *ret = getProduction(name);
    struct Buffer_Production_p pors;
    struct Buffer_Production pthens;
    struct Production *pr;
    int ors, thens;

    ret->parser = packratNonterminal;

    /* now fill in the sub-productions */
    INIT_BUFFER(pors);
    for (ors = 0; sub[ors]; ors++) {
        INIT_BUFFER(pthens);
        for (thens = 0; sub[ors][thens]; thens++) {
            pr = getProduction(sub[ors][thens]);
            WRITE_BUFFER(pthens, &pr, 1);
        }
        pr = NULL;
        WRITE_BUFFER(pthens, &pr, 1);

        WRITE_BUFFER(pors, &pthens.buf, 1);
    }
    pr = NULL;
    WRITE_BUFFER(pors, (struct Production ***) &pr, 1);

    ret->arg = pors.buf;

    return ret;
}
示例#2
0
void Grammar::computeSuccessors(LR1State &state) {
//dump(state); pause();
  BitSet itemsDone(state.m_items.size()); // this is correct!
  for(UINT i = 0; i < state.m_items.size(); i++) {
    if(itemsDone.contains(i)) {
      continue;
    }
    const LR1Item &origItem = state.m_items[i];
    if(isAcceptItem(origItem)) {
      continue; // No successor, but accept
    }
    const Production &origProduction = getProduction(origItem);
    if(origItem.m_dot < origProduction.getLength()) { // origItem is A -> alfa . X beta [la]
      CompactIntArray successorItems;
      successorItems.add(i);
      int symbolNr = origProduction.m_rightSide[origItem.m_dot];
      LR1State newState(getStateCount());
      const LR1Item newItem(true, origItem.m_prod, origItem.m_dot+1, origItem.m_la); // newItem is A -> alfa X . beta [la] (kernelItem)
      newState.addItem(newItem);
      itemsDone += i;
      for(UINT k = i+1; k < state.m_items.size(); k++) {
        if(itemsDone.contains(k)) {
          continue;
        }
        const LR1Item    &sameSymbolItem = state.m_items[k];
        const Production &sameSymbolProd = getProduction(sameSymbolItem);
        if(sameSymbolItem.m_dot < sameSymbolProd.getLength()
          && sameSymbolProd.m_rightSide[sameSymbolItem.m_dot] == symbolNr) { // sameSymbolItem is C -> gamma . X zeta [la1]
          const LR1Item newItem1(true, sameSymbolItem.m_prod, sameSymbolItem.m_dot+1, sameSymbolItem.m_la); // newItem1 is C -> gamma X . zeta [la1] (kernelItem)
          newState.addItem(newItem1);
          itemsDone += k;
          successorItems.add(k);
        }
      }
      newState.sortItems();
      int succStateIndex = findState(newState);
      if(succStateIndex < 0) {
        computeClosure(newState, true);
        succStateIndex = addState(newState);
      } else {
        if(mergeLookahead(m_states[succStateIndex], newState)) {
          m_unfinishedSet.add(succStateIndex);
//          printf(_T(")%d ", succStateIndex);
        }
      }

      assert(succStateIndex >= 0);

      for(size_t j = 0; j < successorItems.size(); j++) {
        state.m_items[successorItems[j]].m_succ = succStateIndex;
      }
    }
  }
}
示例#3
0
文件: packrat.c 项目: GregorR/plof3
/* create a negation nonterminal given only a name */
struct Production *newPackratNotNonterminal(unsigned char *name, unsigned char *sub)
{
    struct Production *ret = getProduction(name);
    struct Production **subp;

    ret->parser = packratNotNonterminal;

    /* now fill in the sub-production */
    subp = GC_MALLOC(2 * sizeof(struct Production *));
    subp[1] = NULL;
    subp[0] = getProduction(sub);
    ret->sub = subp;

    return ret;
}
示例#4
0
void actualizeNonTerminals(GrammarADT grammar) {
    int nontermquant = getQuantTerminals(grammar);
    char * nontermsfounded = NULL ;
    int nontermsfoundedsize =0;
    ProductionsADT productions = getProductions(grammar);
    int productionquant = getQuant(productions),i;
    /*detect current non terminals*/
    for (i=0; i<productionquant; i++) {
        ProductionADT p = getProduction(productions,i);
        char first = getProductionComponent(p,0);
        char sec = getProductionComponent(p,1);
        char third = getProductionComponent(p,2);
        if (isNonTerminal(first) && !containsChar(nontermsfounded,nontermsfoundedsize,first) ) {
            addChar(&nontermsfounded, &nontermsfoundedsize, first);
        }
        if (isNonTerminal(sec) && !containsChar(nontermsfounded,nontermsfoundedsize,sec) ) {
            addChar(&nontermsfounded, &nontermsfoundedsize, sec);
        }
        if(isNonTerminal(third) && !containsChar(nontermsfounded,nontermsfoundedsize,third)) {
            addChar(&nontermsfounded, &nontermsfoundedsize, third);
        }
    }
    /*actualize non terminals*/
    if( nontermsfoundedsize != nontermquant ) {
        /*there are less current non terminals*/
        setNonTerminals(grammar,nontermsfounded,nontermsfoundedsize);
    }

}
示例#5
0
/*should be called after actualizeNonterminals*/
void actualizeProductions(GrammarADT grammar) {
    ProductionsADT productions = getProductions(grammar);
    int quantproductions = getQuant(productions);
    int quantnonterminals = getQuantNonTerminals(grammar);
    char * nonterminals = getNonTerminals(grammar);
    int i,j;
    /* por cada no terminal, si no exite ninguna producion que lo tenga
     * en su parte izquierda, hay que elimicar la producion
     */
    int contained = FALSE;
    for ( i=0; i<quantnonterminals; i++ ) {
        contained = FALSE;
        for (j=0; j<quantproductions; j++ ) {
            ProductionADT p = getProduction(productions,j);
            char first = getProductionComponent(p,0);
            if( nonterminals[i] == first ) {
                contained = TRUE;
                break;
            }
        }
        /* if the symbol is no longer in the left of a production ->
         * all the production containing that symbol should be deleted
         */
        if (!contained) {
            removeProductionsContaining(productions, nonterminals[i]);
        }
    }
}
示例#6
0
void Grammar::computeClosure(LR1State &state, bool allowNewItems) {
  bool changed;
  do {
    changed = false;
    for(size_t i = 0; i < state.m_items.size(); i++) {
      const LR1Item &item = state.m_items[i];
      const Production &prod = getProduction(item);
      if(item.m_dot < prod.getLength() && isNonTerminal(prod.m_rightSide[item.m_dot])) { // item is A -> alfa . B beta [la]
        const GrammarSymbol &B = getSymbol(prod.m_rightSide[item.m_dot]);
        const BitSet la(first1(item));
        for(size_t p = 0; p < B.m_leftSideOf.size(); p++) {
          const LR1Item newItem(false, B.m_leftSideOf[p], 0, la); // newItem is B -> . gamma [first1(beta la)] (nonkernelitem)
          LR1Item *oldItem = state.findItem(newItem);
          if(oldItem == NULL) {
            if(!allowNewItems) {
              throwException(_T("Grammar::computeClosure:No new items allowed"));
            }
            state.addItem(newItem);
            changed = true;
          } else {
            if(!(newItem.m_la - oldItem->m_la).isEmpty()) {
              oldItem->m_la += newItem.m_la;
              changed = true;
            }
          }
        }
      }
    }
  } while(changed);
  state.sortItems();
}
示例#7
0
/*Utility*/
void printProductions(ProductionsADT productions){
	printf("Productions: { \n");
	int i;
	for(i=0; i<getQuant(productions);i++){
		printProduction(getProduction(productions,i));
	}
	printf("}\n");
}
示例#8
0
void ProductionState::set_valid(const char *result) {
    Production *p = getProduction(result);

    // Update valid as allowed by current constraints
    if( _constraint == noConstraint ) {
        p->_valid = knownValid;
    } else {
        if( p->_valid != knownValid ) {
            p->_valid = unknownValid;
        }
    }
}
示例#9
0
文件: packrat.c 项目: GregorR/plof3
/* remove all productions with the given name */
void delProduction(const unsigned char *name)
{
    /* find the relevant production */
    struct Production *curp = getProduction(name),
                      *curp_left = curp->left,
                      *curp_right = curp->right;

    /* and blank it */
    memset(curp, 0, sizeof(struct Production));
    curp->name = (unsigned char *) GC_STRDUP((char *) name);
    curp->left = curp_left;
    curp->right = curp_right;
}
示例#10
0
int isRight(GrammarADT grammar) {
    ProductionsADT productions = getProductions(grammar);
    int n = getQuant(productions);
    int i;
    for (i=0; i<n; i++) {
        ProductionADT p = getProduction(productions,i);
        char sec = getProductionComponent(p,1);
        char third = getProductionComponent(p,2);
        /*if there is a production like A->Ba, it is a left sided grammar*/
        if (isNonTerminal(sec) && isTerminal(third)) {
            return 0;
        }
    }
    return 1;
}
示例#11
0
ConflictSolution Grammar::resolveShiftReduceConflict(const GrammarSymbol &terminal, const LR1Item &item) const {
  short productionPrecedence = getProduction(item).m_precedence;
  short terminalPrecedence   = terminal.m_precedence;

  if((productionPrecedence == 0) || (terminalPrecedence == 0)) {
    return CONFLICT_NOT_RESOLVED;
  }

  if( (terminalPrecedence < productionPrecedence)
    || (productionPrecedence == terminalPrecedence && terminal.m_type != RIGHTASSOC_TERMINAL) ) {
    return CHOOSE_REDUCE;
  } else {
    return CHOOSE_SHIFT;
  }
}
示例#12
0
void toFile(GrammarADT grammar) {
    FILE * fp = fopen("grammar.gr", "w");
    if(fp == NULL) {
        printf("Error: File could not be created\n");
        fclose(fp);
        return;
    }

    fprintf(fp, "G1 = ({");

    int i;

    for(i = 0; i < getQuantNonTerminals(grammar); i++)	{
        fprintf(fp, "%c%s", getNonTerminals(grammar)[i], (i == getQuantNonTerminals(grammar)-1?"}":", "));
    }

    fprintf(fp, ", {");

    for(i = 0; i < getQuantTerminals(grammar); i++)	{
        fprintf(fp, "%c%s", getTerminals(grammar)[i], (i == getQuantTerminals(grammar)-1?"}":", "));
    }

    fprintf(fp, ", %c, {", getDistinguished(grammar));

    for(i = 0; i < getQuant(getProductions(grammar)); i++) {
        fprintf(fp, "%c -> %c%c%s", getProductionComponent(getProduction(getProductions(grammar), i), 0),
                getProductionComponent(getProduction(getProductions(grammar), i), 1),
                getProductionComponent(getProduction(getProductions(grammar), i), 2),
                (i == getQuant(getProductions(grammar))-1? "}": ", "));
    }

    fprintf(fp, ")");
    fclose(fp);
    return;

}
示例#13
0
/*
fills the list with Templates that can be manufactured
in the Factory - based on size. There is a limit on how many can be manufactured
at any one time.
*/
void fillTemplateList(std::vector<DROID_TEMPLATE *> &pList, STRUCTURE *psFactory)
{
	const int player = psFactory->player;
	pList.clear();

	BODY_SIZE	iCapacity = (BODY_SIZE)psFactory->capacity;

	/* Add the templates to the list*/
	for (DROID_TEMPLATE &i : localTemplates)
	{
		DROID_TEMPLATE *psCurr = &i;
		// Must add droids if currently in production.
		if (!getProduction(psFactory, psCurr).quantity)
		{
			//can only have (MAX_CMDDROIDS) in the world at any one time
			if (psCurr->droidType == DROID_COMMAND)
			{
				if (checkProductionForCommand(player) + checkCommandExist(player) >= (MAX_CMDDROIDS))
				{
					continue;
				}
			}

			if (!psCurr->enabled || !validTemplateForFactory(psCurr, psFactory, false)
			    || !researchedTemplate(psCurr, player, includeRedundantDesigns))
			{
				continue;
			}
		}

		//check the factory can cope with this sized body
		if (((asBodyStats + psCurr->asParts[COMP_BODY])->size <= iCapacity))
		{
			pList.push_back(psCurr);
		}
		else if (bMultiPlayer && (iCapacity == SIZE_HEAVY))
		{
			// Special case for Super heavy bodyies (Super Transporter)
			if ((asBodyStats + psCurr->asParts[COMP_BODY])->size == SIZE_SUPER_HEAVY)
			{
				pList.push_back(psCurr);
			}
		}
	}
}
示例#14
0
// assume item = A -> alfa . B beta [la]
// computes first1(beta la)
BitSet Grammar::first1(const LR1Item &item) const {
  const Production &prod = getProduction(item);
  const int length = prod.getLength();
  BitSet result(getTerminalCount());
  for(int k = item.m_dot+1; k < length; k++) {
    const int symbol = prod.m_rightSide[k];
    if(isTerminal(symbol)) {
      result += symbol;
      return result;
    } else { // nonterminal
      const GrammarSymbol &nt = getSymbol(symbol);
      result += nt.m_first1;
      if(!nt.m_deriveEpsilon) {
        return result;
      }
    }
  }
  return result += item.m_la;
}
示例#15
0
文件: packrat.c 项目: GregorR/plof3
/* create a regex nonterminal */
struct Production *newPackratRegexTerminal(unsigned char *name, unsigned char *regex)
{
    struct Production *ret = getProduction(name);
    const char *err;
    int erroffset;

    ret->parser = packratRegexTerminal;

    /* now fill in the arg */
    ret->arg = pcre_compile((char *) regex, PCRE_DOTALL, &err, &erroffset, NULL);

    /* and cry if it's bad */
    if (ret->arg == NULL) {
        fprintf(stderr, "Error compiling regex %s at (%d): %s\n", regex, erroffset, err);
        exit(1);
    }

    return ret;
}
示例#16
0
/*
fills the list with Templates that can be manufactured
in the Factory - based on size. There is a limit on how many can be manufactured
at any one time. Pass back the number available.
*/
void fillTemplateList(std::vector<DROID_TEMPLATE *> &pList, STRUCTURE *psFactory)
{
	const int player = psFactory->player;
	pList.clear();

	DROID_TEMPLATE	*psCurr;
	UDWORD iCapacity = psFactory->capacity;

	/* Add the templates to the list*/
	for (std::list<DROID_TEMPLATE>::iterator i = localTemplates.begin(); i != localTemplates.end(); ++i)
	{
		psCurr = &*i;
		// Must add droids if currently in production.
		if (!getProduction(psFactory, psCurr).quantity)
		{
			//can only have (MAX_CMDDROIDS) in the world at any one time
			if (psCurr->droidType == DROID_COMMAND)
			{
				if (checkProductionForCommand(player) + checkCommandExist(player) >= (MAX_CMDDROIDS))
				{
					continue;
				}
			}

			if (!psCurr->enabled || !validTemplateForFactory(psCurr, psFactory, false)
			    || !researchedTemplate(psCurr, player, includeRedundantDesigns))
			{
				continue;
			}
		}

		//check the factory can cope with this sized body
		if (!((asBodyStats + psCurr->asParts[COMP_BODY])->size > iCapacity) )
		{
			pList.push_back(psCurr);
		}
	}
}
示例#17
0
void ProductionState::set_cost_bounds(const char *result, const Expr *cost, bool has_state_check, bool has_cost_check) {
    Production *p = getProduction(result);

    if( p->_valid == knownInvalid ) {
        // Our cost bounds are not unknown, just not defined.
        p->_cost_lb = cost->clone();
        p->_cost_ub = cost->clone();
    } else if (has_state_check || _constraint != noConstraint) {
        // The production is protected by a condition, so
        // the cost bounds may expand.
        // _cost_lb = min(cost, _cost_lb)
        if( cost->less_than_or_equal(p->_cost_lb) ) {
            p->_cost_lb = cost->clone();
        }
        // _cost_ub = max(cost, _cost_ub)
        if( p->_cost_ub->less_than_or_equal(cost) ) {
            p->_cost_ub = cost->clone();
        }
    } else if (has_cost_check) {
        // The production has no condition check, but does
        // have a cost check that could reduce the upper
        // and/or lower bound.
        // _cost_lb = min(cost, _cost_lb)
        if( cost->less_than_or_equal(p->_cost_lb) ) {
            p->_cost_lb = cost->clone();
        }
        // _cost_ub = min(cost, _cost_ub)
        if( cost->less_than_or_equal(p->_cost_ub) ) {
            p->_cost_ub = cost->clone();
        }
    } else {
        // The costs are unconditionally set.
        p->_cost_lb = cost->clone();
        p->_cost_ub = cost->clone();
    }

}
示例#18
0
void removeUnproductiveProductions(GrammarADT grammar) {
    ProductionsADT  productions = getProductions(grammar);
    int i, quantproductions = getQuant(productions), productivequant=0,lastproductivequant=-1;
    char * productives = NULL;
    char * aux1 = NULL;
    while(productivequant != lastproductivequant) {
        lastproductivequant = productivequant;
        for( i=0; i< quantproductions; i++ ) {
            ProductionADT p1 = getProduction(productions,i);
            char first1 = getProductionComponent(p1,0);
            char sec1 = getProductionComponent(p1,1);
            char third1 = getProductionComponent(p1,2);
            if ( !containsChar(productives,productivequant,first1)  ) {
                if ( ( sec1 == LAMDA && third1 == LAMDA ) || /*lamda*/
                        (isTerminal(sec1) && isTerminal(third1) ) || /*both terminal*/
                        (   isTerminal(sec1) && third1 == LAMDA   ) || /*one terminal*/
                        (   isTerminal(third1) && sec1 == LAMDA   ) ||
                        /*one terminal and one productive*/
                        (isTerminal(sec1) && ( isNonTerminal(third1) && containsChar(productives,productivequant,third1) ) ) ||
                        (isTerminal(third1) && ( isNonTerminal(sec1) && containsChar(productives,productivequant,sec1) ) ) ||
                        ( sec1 == LAMDA && ( isNonTerminal(third1) && containsChar(productives,productivequant,third1) ) ) ||
                        ( third1 == LAMDA && ( isNonTerminal(sec1) && containsChar(productives,productivequant,sec1) ) )) {
                    if ( ( aux1 = realloc(productives, sizeof(char)*(productivequant+1)) ) == NULL ) {
                        fprintf(stderr, "Error doing realloc \n");
                    }
                    productives = aux1;
                    productives[productivequant++] = first1;
                }
            }
        }
    }
    /*remove non terminals and terminals that are no longer there */
    actualizeTerminals(grammar);
    actualizeNonTerminals(grammar);
    actualizeProductions(grammar);
}
示例#19
0
String Grammar::itemToString(const LR1Item &item, int flags) const {
  String result;
  const Production &prod = getProduction(item);
  result = format(_T(" (%3d)%c %-15s -> "), item.m_prod, item.m_kernelItem?'K':' ', getSymbol(prod.m_leftSide).m_name.cstr());
  for(int i = 0; i < item.m_dot; i++) {
    result += getSymbol(prod.m_rightSide[i]).m_name;
    result += _T(" ");
  }
  result += _T(".");
  const int n = prod.getLength();
  const TCHAR *delimiter = EMPTYSTRING;
  for(int i = item.m_dot; i < n; i++, delimiter = _T(" ")) {
    result += delimiter;
    result += getSymbol(prod.m_rightSide[i]).m_name;
  }
  if(flags & DUMP_LOOKAHEAD) {
    result += symbolSetToString(item.m_la);
  }

  if((flags & DUMP_SUCC) && (item.m_succ >= 0)) {
    result += format(_T(" -> %d"), item.getSuccessor()); // ie not reduce-item
  }
  return result;
}
示例#20
0
Expr *ProductionState::cost_ub(const char *result) {
    return getProduction(result)->cost_ub();
}
示例#21
0
bool Grammar::isShiftItem(const LR1Item &item) const { // is item = "A -> alfa . a beta [la]"
  const Production &prod = getProduction(item);
  return item.m_dot < prod.getLength() && isTerminal(prod.m_rightSide[item.m_dot]);
}
示例#22
0
const char *ProductionState::valid(const char *result) {
    return getProduction(result)->valid();
}
示例#23
0
bool Grammar::isReduceItem(const LR1Item &item) const { // is item = "A -> alfa . [la]"
  return item.m_dot == getProduction(item).getLength();
}
示例#24
0
int Grammar::getShiftSymbol(const LR1Item &item) const { // Assume item = "A -> alfa . x beta [la]". Return x
  return getProduction(item).m_rightSide[item.m_dot];
}
示例#25
0
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);



}
示例#26
0
void Grammar::checkStateIsConsistent(const LR1State &state, StateResult &result) {
  BitSet symbolsDone(getSymbolCount());
  const int itemCount = (int)state.m_items.size();

  for(int i = 0; i < itemCount; i++) {
    const LR1Item &item = state.m_items[i];
    if(isShiftItem(item)) {
      const int t = getShiftSymbol(item);
      if(symbolsDone.contains(t)) {
        continue;
      }
      for(int j = 0; j < itemCount; j++) {
        if(j == i) {
          continue;
        }
        const LR1Item &item1 = state.m_items[j];
        if(isReduceItem(item1) && item1.m_la.contains(t)) {
          const GrammarSymbol &terminal = getSymbol(t);
          switch(resolveShiftReduceConflict(terminal, item1)) {
          case CONFLICT_NOT_RESOLVED:
            m_SRconflicts++;
            result.m_errors.add(format(_T("Shift/reduce conflict. Shift or reduce by prod %-3d (prec=%d) on '%s' (prec=%d, %s).")
                                      ,item1.m_prod
                                      ,getProduction(item1).m_precedence
                                      ,terminal.m_name.cstr()
                                      ,terminal.m_precedence
                                      ,terminal.getTypeString()));
            break;
          case CHOOSE_SHIFT:
            result.m_actions.add(ParserAction(t, item.getSuccessor()));
            symbolsDone += t;
            result.m_warnings.add(format(_T("Shift/reduce conflict on %s (prec=%d, %s). Choose shift instead of reduce by prod %d (prec=%d).")
                                        ,terminal.m_name.cstr()
                                        ,terminal.m_precedence
                                        ,terminal.getTypeString()
                                        ,item1.m_prod
                                        ,getProduction(item1).m_precedence));
            m_warningCount++;
            break;
          case CHOOSE_REDUCE:
            result.m_actions.add(ParserAction(t, -item1.m_prod));
            symbolsDone += t;
            result.m_warnings.add(format(_T("Shift/reduce conflict on %s (prec=%d, %s). Choose reduce by prod %d (prec=%d).")
                                        ,terminal.m_name.cstr()
                                        ,terminal.m_precedence
                                        ,terminal.getTypeString()
                                        ,item1.m_prod
                                        ,getProduction(item1).m_precedence));
            m_warningCount++;
            break;
          }
        }
      }
      if(!symbolsDone.contains(t)) {
        if(item.m_succ >= 0) {
          result.m_actions.add(ParserAction(t, item.getSuccessor()));
        }
        symbolsDone += t;
        continue;
      }
    }
  }

  for(int i = 0; i < itemCount; i++) {
    const LR1Item &itemi = state.m_items[i];
    if(isReduceItem(itemi)) {
      BitSet tokensReducedByOtherItems(getTerminalCount());
      if(isAcceptItem(itemi)) {  // check if this is start -> S . [EOI]
        result.m_actions.add(ParserAction(0, 0));
        if(symbolsDone.contains(0)) {
          throwException(_T("Token EOI already done in state %d while generating Acceptitem"), state.m_index);
        }
        symbolsDone += 0;
        continue;
      }
      for(int j = 0; j < itemCount; j++) {
        if(j == i) {
          continue;
        }
        const LR1Item &itemj = state.m_items[j];
        if(isReduceItem(itemj)) {
          const BitSet intersection(itemi.m_la & itemj.m_la);
          if(!intersection.isEmpty()) {
            if(itemj.m_prod < itemi.m_prod) {
              tokensReducedByOtherItems += intersection;
              result.m_warnings.add(format(_T("Reduce/reduce conflict on %s between prod %d and prod %d. Choose prod %d.")
                                          ,symbolSetToString(intersection).cstr()
                                          ,itemj.m_prod
                                          ,itemi.m_prod
                                          ,itemj.m_prod));
              m_warningCount++;
            }
          }
        }
      }
      BitSet itemTokens(itemi.m_la - tokensReducedByOtherItems);
      for(Iterator<size_t> it = itemTokens.getIterator(); it.hasNext(); ) {
        const unsigned short t = (unsigned short)it.next();
        if(!symbolsDone.contains(t)) {
          result.m_actions.add(ParserAction(t, -itemi.m_prod));
          symbolsDone += t;
        }
      }
    }
  }

  for(int i = 0; i < itemCount; i++) {
    const LR1Item &itemi = state.m_items[i];
    if(!isShiftItem(itemi) && !isReduceItem(itemi)) {
      const int nt = getShiftSymbol(itemi);
      if(!symbolsDone.contains(nt)) {
        if(itemi.getSuccessor() >= 0) {
          result.m_succs.add(ParserAction(nt, itemi.getSuccessor()));
        }
        symbolsDone += nt;
      }
    }
  } // for

  result.m_actions.sort(parserActionCompareToken); // sort actions by symbolnumber (lookahead symbol)
  result.m_succs.sort(  parserActionCompareToken); // sort result by symbolnumber  (nonTerminal)
}
示例#27
0
void removeUnreachableProductions(GrammarADT grammar) {
    ProductionsADT  productions = getProductions(grammar);
    int i, quantproductions = getQuant(productions), reachablesquant=0,lastreachablesquant=0;
    char * reachables = malloc(sizeof(char));
    char * aux1 = NULL;
    /*starts only with distinguished symbol, if it is in the current productions*/
    if(inCurrentProductions(productions,getDistinguished(grammar))) {
        reachables[reachablesquant++] = getDistinguished(grammar);
    }
    /*until something the quantity of reachables varies*/
    while (reachablesquant != lastreachablesquant) {
        lastreachablesquant = reachablesquant;
        for(i=0; i<quantproductions; i++) {
            char first = getProductionComponent(getProduction(productions,i),0);
            char sec = getProductionComponent(getProduction(productions,i),1);
            char third = getProductionComponent(getProduction(productions,i),2);
            /*if the symbol of the left is contained in the reachables, the non terminal
             * symbols of the right must be added*/
            if (containsChar(reachables,reachablesquant,first)) {
                /*if the second symbol is nonterminal and is not yet in the
                 * reachable list, it must be added*/
                if ( isNonTerminal( sec ) &&
                        !containsChar(reachables,reachablesquant,sec)) {
                    if ( ( aux1 = realloc(reachables, sizeof(char)*(reachablesquant+1)) ) == NULL ) {
                        fprintf(stderr, "Error doing realloc \n");
                    }
                    reachables = aux1;
                    reachables[reachablesquant++] = sec;
                }/*if the third symbol is nonterminal and is not yet in the
				 * reachable list, it must be added*/
                else if( isNonTerminal(third) &&
                         !containsChar(reachables,reachablesquant,third) ) {
                    if ( (aux1 = realloc(reachables, sizeof(char)*(reachablesquant+1)) ) == NULL ) {
                        fprintf(stderr, "Error doing realloc \n");
                    }
                    reachables = aux1;
                    reachables[reachablesquant++] = third;
                }
            }
        }
    }
    /*TODO: delete debug printf*/
    printf("\nReachables!!: ");
    printArray(reachables,reachablesquant);
    int symsToRemovequant=0;
    /*remove the unreachable productions*/
    /*If the quantity of reachables is equal to the quantity of nonterminals,
     * nothing should be removed*/
    if (reachablesquant != getQuantNonTerminals(grammar)) {
        char * symsToRemove = NULL;
        symsToRemovequant = getDifferents(getNonTerminals(grammar),
                                          getQuantNonTerminals(grammar) ,reachables, reachablesquant, &symsToRemove);
        printf("\nTO REMOVE:");
        printArray(symsToRemove,symsToRemovequant );
        for(i=0; i<symsToRemovequant; i++) {
            removeProduction(productions,symsToRemove[i]);
        }
    }
    /*remove non terminals and terminals that are no longer there */
    actualizeTerminals(grammar);
    actualizeNonTerminals(grammar);
    actualizeProductions(grammar);

}
示例#28
0
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;
}
示例#29
0
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);
}