132 lines
4.7 KiB
C
132 lines
4.7 KiB
C
|
|
#ifndef HAMMER_BACKENDS_LR__H
|
||
|
|
#define HAMMER_BACKENDS_LR__H
|
||
|
|
|
||
|
|
#include "../hammer.h"
|
||
|
|
#include "../cfgrammar.h"
|
||
|
|
#include "../internal.h"
|
||
|
|
|
||
|
|
|
||
|
|
typedef HHashSet HLRState; // states are sets of LRItems
|
||
|
|
|
||
|
|
typedef struct HLRDFA_ {
|
||
|
|
size_t nstates;
|
||
|
|
const HLRState **states; // array of size nstates
|
||
|
|
HSlist *transitions;
|
||
|
|
} HLRDFA;
|
||
|
|
|
||
|
|
typedef struct HLRTransition_ {
|
||
|
|
size_t from; // index into 'states' array
|
||
|
|
const HCFChoice *symbol;
|
||
|
|
size_t to; // index into 'states' array
|
||
|
|
} HLRTransition;
|
||
|
|
|
||
|
|
typedef struct HLRItem_ {
|
||
|
|
HCFChoice *lhs;
|
||
|
|
HCFChoice **rhs; // NULL-terminated
|
||
|
|
size_t len; // number of elements in rhs
|
||
|
|
size_t mark;
|
||
|
|
} HLRItem;
|
||
|
|
|
||
|
|
typedef struct HLRAction_ {
|
||
|
|
enum {HLR_SHIFT, HLR_REDUCE} type;
|
||
|
|
union {
|
||
|
|
size_t nextstate; // used with SHIFT
|
||
|
|
struct {
|
||
|
|
HCFChoice *lhs; // symbol carrying semantic actions etc.
|
||
|
|
size_t length; // # of symbols in rhs
|
||
|
|
#ifndef NDEBUG
|
||
|
|
HCFChoice **rhs; // NB: the rhs symbols are not needed for the parse
|
||
|
|
#endif
|
||
|
|
} production; // used with REDUCE
|
||
|
|
};
|
||
|
|
} HLRAction;
|
||
|
|
|
||
|
|
typedef struct HLRTable_ {
|
||
|
|
size_t nrows;
|
||
|
|
HHashTable **rows; // map symbols to HLRActions
|
||
|
|
HLRAction **forall; // shortcut to set an action for an entire row
|
||
|
|
HCFChoice *start; // start symbol
|
||
|
|
HSlist *inadeq; // indices of any inadequate states
|
||
|
|
HArena *arena;
|
||
|
|
HAllocator *mm__;
|
||
|
|
} HLRTable;
|
||
|
|
|
||
|
|
typedef struct HLREnhGrammar_ {
|
||
|
|
HCFGrammar *grammar; // enhanced grammar
|
||
|
|
HHashTable *tmap; // maps transitions to enhanced-grammar symbols
|
||
|
|
HHashTable *smap; // maps enhanced-grammar symbols to transitions
|
||
|
|
HHashTable *corr; // maps symbols to sets of corresponding e. symbols
|
||
|
|
HArena *arena;
|
||
|
|
} HLREnhGrammar;
|
||
|
|
|
||
|
|
typedef struct HLREngine_ {
|
||
|
|
const HLRTable *table;
|
||
|
|
HSlist *left; // left stack; reductions happen here
|
||
|
|
HSlist *right; // right stack; input appears here
|
||
|
|
size_t state;
|
||
|
|
bool running;
|
||
|
|
HArena *arena; // will hold the results
|
||
|
|
HArena *tarena; // tmp, deleted after parse
|
||
|
|
} HLREngine;
|
||
|
|
|
||
|
|
|
||
|
|
// XXX move to internal.h or something
|
||
|
|
// XXX replace other hashtable iterations with this
|
||
|
|
#define H_FOREACH_(HT) { \
|
||
|
|
const HHashTable *ht__ = HT; \
|
||
|
|
for(size_t i__=0; i__ < ht__->capacity; i__++) { \
|
||
|
|
for(HHashTableEntry *hte__ = &ht__->contents[i__]; \
|
||
|
|
hte__; \
|
||
|
|
hte__ = hte__->next) { \
|
||
|
|
if(hte__->key == NULL) continue;
|
||
|
|
|
||
|
|
#define H_FOREACH_KEY(HT, KEYVAR) H_FOREACH_(HT) \
|
||
|
|
const KEYVAR = hte__->key;
|
||
|
|
|
||
|
|
#define H_FOREACH(HT, KEYVAR, VALVAR) H_FOREACH_KEY(HT, KEYVAR) \
|
||
|
|
VALVAR = hte__->value;
|
||
|
|
|
||
|
|
#define H_END_FOREACH \
|
||
|
|
} \
|
||
|
|
} \
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
HLRItem *h_lritem_new(HArena *a, HCFChoice *lhs, HCFChoice **rhs, size_t mark);
|
||
|
|
HLRState *h_lrstate_new(HArena *arena);
|
||
|
|
HLRTable *h_lrtable_new(HAllocator *mm__, size_t nrows);
|
||
|
|
void h_lrtable_free(HLRTable *table);
|
||
|
|
HLREngine *h_lrengine_new(HArena *arena, HArena *tarena, const HLRTable *table);
|
||
|
|
HLRAction *h_reduce_action(HArena *arena, const HLRItem *item);
|
||
|
|
HLRAction *h_shift_action(HArena *arena, size_t nextstate);
|
||
|
|
|
||
|
|
bool h_eq_symbol(const void *p, const void *q);
|
||
|
|
bool h_eq_lr_itemset(const void *p, const void *q);
|
||
|
|
bool h_eq_transition(const void *p, const void *q);
|
||
|
|
HHashValue h_hash_symbol(const void *p);
|
||
|
|
HHashValue h_hash_lr_itemset(const void *p);
|
||
|
|
HHashValue h_hash_transition(const void *p);
|
||
|
|
|
||
|
|
HLRDFA *h_lr0_dfa(HCFGrammar *g);
|
||
|
|
HLRTable *h_lr0_table(HCFGrammar *g, const HLRDFA *dfa);
|
||
|
|
int h_lrtable_put(HLRTable *tbl, size_t state, HCFChoice *x, HLRAction *action);
|
||
|
|
|
||
|
|
int h_lalr_compile(HAllocator* mm__, HParser* parser, const void* params);
|
||
|
|
void h_lalr_free(HParser *parser);
|
||
|
|
|
||
|
|
const HLRAction *h_lr_lookup(const HLRTable *table, size_t state, const HCFChoice *symbol);
|
||
|
|
void h_lrengine_step(HLREngine *engine, HInputStream *stream);
|
||
|
|
HParseResult *h_lrengine_result(HLREngine *engine);
|
||
|
|
HParseResult *h_lr_parse(HAllocator* mm__, const HParser* parser, HInputStream* stream);
|
||
|
|
|
||
|
|
void h_pprint_lritem(FILE *f, const HCFGrammar *g, const HLRItem *item);
|
||
|
|
void h_pprint_lrstate(FILE *f, const HCFGrammar *g,
|
||
|
|
const HLRState *state, unsigned int indent);
|
||
|
|
void h_pprint_lrdfa(FILE *f, const HCFGrammar *g,
|
||
|
|
const HLRDFA *dfa, unsigned int indent);
|
||
|
|
void h_pprint_lrtable(FILE *f, const HCFGrammar *g, const HLRTable *table,
|
||
|
|
unsigned int indent);
|
||
|
|
|
||
|
|
#endif
|