start filling in h_ll_compile()
This commit is contained in:
parent
9f5c32e205
commit
52f81045fc
1 changed files with 56 additions and 8 deletions
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue