Exemplo n.º 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()
Exemplo n.º 2
0
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre16_get_named_substring(const pcre16 *code, PCRE_SPTR16 subject,
                           int *ovector, int stringcount, PCRE_SPTR16 stringname,
                           PCRE_SPTR16 *stringptr)
#endif
{
    int n = get_first_set(code, stringname, ovector);
    if (n <= 0) return n;
#ifdef COMPILE_PCRE8
    return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
#else
    return pcre16_get_substring(subject, ovector, stringcount, n, stringptr);
#endif
}
Exemplo n.º 3
0
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre32_copy_named_substring(const pcre32 *code, PCRE_SPTR32 subject,
  int *ovector, int stringcount, PCRE_SPTR32 stringname,
  PCRE_UCHAR32 *buffer, int size)
#endif
{
int n = get_first_set(code, stringname, ovector, stringcount);
if (n <= 0) return n;
#if defined COMPILE_PCRE8
return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
#elif defined COMPILE_PCRE16
return pcre16_copy_substring(subject, ovector, stringcount, n, buffer, size);
#elif defined COMPILE_PCRE32
return pcre32_copy_substring(subject, ovector, stringcount, n, buffer, size);
#endif
}
Exemplo n.º 4
0
static void first(CC_Class *cc, PT_Symbols symbols) {
  PT_Symbol symbol;
  CC_Class *set;

  while(!PT_isSymbolsEmpty(symbols)) {
    symbol = PT_getSymbolsHead(symbols);
    symbols = PT_getSymbolsTail(symbols);

    set = get_first_set(symbol, ATtrue);
    CC_union(cc, set, cc);
    if (!CC_containsChar(set, CC_EPSILON)) {
      CC_removeChar(cc, CC_EPSILON);
      return;
    }
  }
  CC_addChar(cc, CC_EPSILON);
}
Exemplo n.º 5
0
/* For each symbol on the left hand side of the given production rule, if the 
 * symbol is a non-terminal initialise the symbol's first set to empty, 
 * otherwise if the symbol is a terminal or the end-of-string symbol, 
 * initialise the symbol's first set to the symbol. */ 
void init_prod_first(PT_Production prod) {
  PT_Symbols symbols;
  PT_Symbol symbol;
  CC_Class *set; 
  CC_Class *newset;

  symbols = PT_getProductionLhs(prod);
  while(!PT_isSymbolsEmpty(symbols)) {
    symbol = PT_getSymbolsHead(symbols);

    set = get_first_set(symbol, ATtrue);
    newset = CC_getCharClass(symbol);
    
    /*assert(CC_isEmpty(set) || CC_isEqual(set, newset));*/

    CC_copy(newset, set);
    symbols = PT_getSymbolsTail(symbols);
  }
}
Exemplo n.º 6
0
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre32_get_named_substring(const pcre32 *code, PCRE_SPTR32 subject,
  int *ovector, int stringcount, PCRE_SPTR32 stringname,
  PCRE_SPTR32 *stringptr)
#endif
{
int n = get_first_set(code, stringname, ovector);
if (n <= 0) return n;
#if defined COMPILE_PCRE8
#if defined(ERLANG_INTEGRATION)
return erts_pcre_get_substring(subject, ovector, stringcount, n, stringptr);
#else
return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
#endif
#elif defined COMPILE_PCRE16
return pcre16_get_substring(subject, ovector, stringcount, n, stringptr);
#elif defined COMPILE_PCRE32
return pcre32_get_substring(subject, ovector, stringcount, n, stringptr);
#endif
}
Exemplo n.º 7
0
static void		*comp_sym_follow(void *sym, void *first_set_of_following)
{
	t_lst	*first_set_of_next;
	t_bool	sym_added;

	if (first_set_of_following == NULL)
		return (NULL);
	first_set_of_next = first_set_of_following;
	if (!is_empty_first(first_set_of_next) && !is_terminal(sym))
	{
		if (!add_set_to_follow_set(sym, first_set_of_next, &sym_added))
			return (NULL);
	}
	if (!has_symbol_in_first(sym, EMPTY_SYMBOL))
	{
		f_lstdel(&first_set_of_next, no_destroy);
		if (NULL == f_lstpush(EMPTY_SYMBOL, &first_set_of_next))
			return (NULL);
	}
	return (lst_add_to_filter(
				&first_set_of_next, get_first_set(sym), &sym_added));
}