Пример #1
0
static void init_symbols(void)
{
    size_t i, j;
    const char *p;

    start_symbol = grammar[0].p_lhs;
    for (i = 0; i < charmap_size; i++)
	charmap[i] = CT_NONE;
    for (i = 0; i < grammar_size; i++)
	charmap[(uint_fast8_t)grammar[i].p_lhs] = CT_NONTERMINAL;
    for (i = 0; i < grammar_size; i++)
	for (p = grammar[i].p_rhs; *p; p++)
	    if (charmap[(uint_fast8_t)*p] == CT_NONE)
		charmap[(uint_fast8_t)*p] = CT_TERMINAL;
    assert(charmap['$'] == CT_NONE);
    charmap['$'] = CT_TERMINAL;
    assert(charmap['-'] == CT_NONE);
    for (i = j = 0; i < token_pairs_size; i++, j++) {
	token_pair_t *tpp = &token_pairs[i];
	assert(tpp->tm_ttype < token_pairs_size);
	uint_fast8_t *cmp = &charmap[(uint_fast8_t)tpp->tm_term];
	assert(*cmp == CT_TERMINAL);
	*cmp |= tpp->tm_ttype;
	*next_symbols(1) = tpp->tm_term;
    }
    terminals_size = symbols_size;
    charmap['-'] = CT_TERMINAL | j++;
    epsilon = symbols_size;
    *next_symbols(1) = '-';
    exterminals_size = symbols_size;
    for (i = 0; i < charmap_size; i++)
	if (charmap[i] == CT_NONTERMINAL) {
	    charmap[i] |= j++;
	    *next_symbols(1) = i;
	}
    nonterminals_size = symbols_size - exterminals_size;
    assert(symbols_size < CTMASK);

#if DUMP_TABLES
    printf("start_symbol = '%c'\n", start_symbol);
    printf("terminals_size = %d\n", terminals_size);
    printf("exterminals_size = %d\n", exterminals_size);
    printf("nonterminals_size = %d\n", nonterminals_size);
    printf("symbols_size = %d\n", symbols_size);
    printf("epsilon = %d\n", epsilon);
    printf("charmap\n");
    for (i = 0; i < charmap_size; i++)
	if (charmap[i])
	    printf("   ['%c'] = 0x%x\n", i, charmap[i]);
    printf("\n");

    printf("symbols\n");
    for (i = 0; i < symbols_size; i++)
	printf("   %2d: %c\n", i, symbols[i]);
    printf("\n");
#endif
}
Пример #2
0
/* returns -1 on failure, >= 0 is an actual symbol value. String is
 * searched until terminating null or end. The empty string cannot
 * receive a symbol value.
 */
symbol_t getvalue_symbols(symbols_t *sb, bool_t generate,
			  const char_t *begin, const char_t *end) {
  const byte_t *p;
  bool_t bdone, pdone;
  jump_t *j;

  if( sb && begin && *begin ) {
    if( !end ) {
      end = begin + strlen(begin);
    }
    
    if( (sb->bigs_len + (end - begin) + 1 + sizeof(symbol_t)) > sb->bigmax ) {
      if( !grow_mem(&sb->bigs, &sb->bigmax, sizeof(byte_t), 16) ) {
	errormsg(E_WARNING, "out of symbol memory\n");
	return -1;
      }
    }
    
    if( sb->bigs_len == 0 ) {
      return next_symbols(sb, generate, begin, end);
    }

    p = sb->bigs;
    while( *begin && (begin < end) ) {

      /* skip common prefix */
      while( (*begin == *p) && *begin && (begin < end) ) {
	p++;
	begin++;
      }

      bdone = ((begin == end) || (*begin == 0));
      pdone = (*p == 0);

      /* either begin string is empty, or p string is empty, or both */
      if( bdone && pdone ) {

	/* we found the string */
	return *((symbol_t *)p);

      } else if( bdone ) { /* a longer p string was inserted first */

	/* follow as many branches as possible */
	j = find_in_jumptable(&sb->jt, p - sb->bigs);
	while( j && sb->bigs[j->pos] ) {
	  p = sb->bigs + j->pos;
	  j = find_in_jumptable(&sb->jt, p - sb->bigs);
	}

	if( j && (sb->bigs[j->pos] == 0) ) { /* found the string */
	  p = sb->bigs + j->pos;
	  return *((symbol_t *)p);
	} else { /* there are no further branches at p */
	  insert_jumptable(&sb->jt, p - sb->bigs, sb->bigs_len);
	  return next_symbols(sb, generate, begin, end);
	}	  

      } else { /* 0 != *begin != *p */

	j = find_in_jumptable(&sb->jt, p - sb->bigs);
	if( !j ) { /* no branch at p, so we append begin */
	  insert_jumptable(&sb->jt, p - sb->bigs, sb->bigs_len);
	  return next_symbols(sb, generate, begin, end);
	}

	/* in here, branch exists */
	p = sb->bigs + j->pos;
      }
      /* and back to while */
    }
  }
  return -1;
}