start filling in h_ll_compile()

This commit is contained in:
Sven M. Hallberg 2013-05-08 18:04:08 +02:00
parent 9f5c32e205
commit 52f81045fc

View file

@ -5,23 +5,53 @@
/* LL parse table and associated data */ /* Generating the LL parse table */
/* Maps each nonterminal (HCFChoice) of the grammar to another hash table that /* Maps each nonterminal (HCFChoice) of the grammar to another hash table that
* maps lookahead tokens (HCFToken) to productions (HCFSequence). * maps lookahead tokens (HCFToken) to productions (HCFSequence).
*/ */
typedef HHashTable HLLTable; typedef struct HLLTable_ {
HHashTable *rows;
HArena *arena;
HAllocator *mm__;
} HLLTable;
/* Interface to look up an entry in the parse table. */ /* Interface to look up an entry in the parse table. */
const HCFSequence *h_ll_lookup(const HLLTable *table, const HCFChoice *x, HCFToken tok) const HCFSequence *h_ll_lookup(const HLLTable *table, const HCFChoice *x, HCFToken tok)
{ {
const HHashTable *row = h_hashtable_get(table, x); const HHashTable *row = h_hashtable_get(table->rows, x);
assert(row != NULL); // the table should have one row for each nonterminal assert(row != NULL); // the table should have one row for each nonterminal
const HCFSequence *production = h_hashtable_get(row, (void *)tok); const HCFSequence *production = h_hashtable_get(row, (void *)tok);
return production; return production;
} }
/* Allocate a new parse table. */
HLLTable *h_lltable_new(HAllocator *mm__)
{
// NB the parse table gets an arena separate from the grammar so we can free
// the latter after table generation.
HArena *arena = h_new_arena(mm__, 0); // default blocksize
assert(arena != NULL);
HHashTable *rows = h_hashtable_new(arena, h_eq_ptr, h_hash_ptr);
assert(rows != NULL);
HLLTable *table = h_new(HLLTable, 1);
assert(table != NULL);
table->mm__ = mm__;
table->arena = arena;
table->rows = rows;
return table;
}
void h_lltable_free(HLLTable *table)
{
HAllocator *mm__ = table->mm__;
h_delete_arena(table->arena);
h_free(table);
}
/* Compute the predict set of production "A -> rhs". */ /* Compute the predict set of production "A -> rhs". */
HHashSet *h_predict(HCFGrammar *g, const HCFChoice *A, const HCFSequence *rhs) HHashSet *h_predict(HCFGrammar *g, const HCFChoice *A, const HCFSequence *rhs)
{ {
@ -38,7 +68,15 @@ HHashSet *h_predict(HCFGrammar *g, const HCFChoice *A, const HCFSequence *rhs)
} }
} }
int h_ll_compile(HAllocator* mm__, const HParser* parser, const void* params) /* Generate the LL parse table from the given grammar.
* Returns -1 on error, 0 on success.
*/
static int fill_table(HCFGrammar *g, HLLTable *table)
{
return -1; // XXX
}
int h_ll_compile(HAllocator* mm__, HParser* parser, const void* params)
{ {
// Convert parser to a CFG. This can fail as indicated by a NULL return. // Convert parser to a CFG. This can fail as indicated by a NULL return.
HCFGrammar *grammar = h_cfgrammar(mm__, parser); HCFGrammar *grammar = h_cfgrammar(mm__, parser);
@ -49,11 +87,21 @@ int h_ll_compile(HAllocator* mm__, const HParser* parser, const void* params)
// TODO: eliminate left recursion // TODO: eliminate left recursion
// TODO: avoid conflicts by splitting occurances? // TODO: avoid conflicts by splitting occurances?
// XXX generate table and store in parser->data. // generate table and store in parser->data.
// XXX any other data structures needed? HLLTable *table = h_lltable_new(mm__);
// XXX free grammar and its arena if(fill_table(grammar, table) < 0) {
// the table was ambiguous
h_cfgrammar_free(grammar);
h_lltable_free(table);
return -1;
}
parser->data = table;
return -1; // XXX 0 on success // free grammar and its arena.
// desugared parsers (HCFChoice and HCFSequence) are unaffected by this.
h_cfgrammar_free(grammar);
return 0;
} }