示例#1
0
//==========================================================================================================
//==========================================================================================================
void Grammar::calc_follow_table() {
    calc_first_table();
    
    //------------------------------------------------------------------------------------------------------
    // To handle end-of-input correctly, add the EOI (= $) symbol to the follow of the start symbol.
    // This is instead of add another symbol to be the new start and a production: START' -> START $
    // That will have the same effect but causes some overhead of needing to deal with the new symbol and
    // production.
    //------------------------------------------------------------------------------------------------------
    follow_table[START].insert(EOI);
    
    //------------------------------------------------------------------------------------------------------
    // Go over the productions:
    // For a sequence ...NA, add First(A) to Follow(N).
    // For a sequence ...N, add a constraint: Follow(M) ⊆ Follow(N), where M is the LHS of the production.
    //------------------------------------------------------------------------------------------------------
    vector<pair<Symbol, Symbol>> follow_constraints; // Pair (M,N) means Follow(M) ⊆ Follow(N)
    
    for(auto& p: productions) {
        Symbol M = p[0];
        
        for(int j = 1; j < p.size(); ++j) {
            if(is_terminal(p[j])) continue;
            Symbol N = p[j];
            
            if(j < p.size() - 1) {
                follow_table[N].insert(get_first_set(p[j+1]));
            }
            else if(M != N) {
                follow_constraints.push_back({M,N});
            }
        }
    }

    //------------------------------------------------------------------------------------------------------
    // Go over the constraints and apply them, until no more changes are made
    //------------------------------------------------------------------------------------------------------
    bool added = true;
    while(added) {
        added = false;
        
        for(auto& c: follow_constraints) {
            Symbol M = c.first, N = c.second;
            int old_size = follow_table[N].size();
            follow_table[N].insert(follow_table[M]);
            added = (added or follow_table[N].size() > old_size);
        }
    }

} // calc_follow_table()
示例#2
0
static PTBL_ParseTable generateParseTable() {
  int i;

  ATermList vertex; 

  PTBL_State state;
  PTBL_States statelist = PTBL_makeStatesEmpty();
  PTBL_Gotos gotos; 
  PTBL_Choices actions;

  
  calc_first_table();
  calc_follow_table();
  createDFA();

  for (i = PGEN_getNumberOfStates()-1; i >= 0; i--) {
    vertex = PGEN_getStateOfStateNumber(i);

    gotos = (PTBL_Gotos)PGEN_getGotosOfState(vertex);
    if (!gotos) {
      gotos = PTBL_makeGotosEmpty();
    } 
    else if (PGEN_getStatsFlag) {
      PGEN_STATS_increaseGotos(PTBL_getGotosLength(gotos));
    }

    actions = PGEN_getActionsOfState(vertex);
    if (!actions) {
      actions = PTBL_makeChoicesEmpty();
    }
    else if (PGEN_getStatsFlag) {
      PGEN_STATS_increaseActions(PTBL_getChoicesLength(actions));
    }

    state = PTBL_makeStateDefault(i, gotos, actions);
    statelist = PTBL_makeStatesMany(state, statelist);
  }

  if (PGEN_getStatsFlag) { PGEN_STATS_print(); }

  return PTBL_makeParseTableParseTable(PTBL_makeVersionDefault(), PGEN_getInitialStateNumber(), PGEN_getLabelSection(), statelist, PGEN_getPrioSection());
}