/* Definitions for grr.c */ /* Last edited on 2006-04-15 15:03:01 by stolfi */ #ifndef grr_types_H #define grr_types_H #include #include #ifndef FALSE typedef enum {FALSE, TRUE} bool_t; #define FALSE FALSE #endif /* A non-negative integer that identifies a symbol of the grammar. */ typedef int GSymbId_t; /* A special {GSymbId_t} meaning "no symbol": */ #define NOSYMB 0 /* A non-negative integer that identifies a rule of the grammar. */ typedef int GRuleId_t; /* A special {GRuleId_t} meaning "no rule": */ #define NORULE 0 /* A rule of the grammar: */ typedef struct GRule_t { GSymbId_t H; GSymbId_t L; GSymbId_t R; GRuleId_t nextH; /* Next rule with same {H} field, or {NORULE} if none. */ GRuleId_t nextL; /* Next rule with same {L} field, or {NORULE} if none. */ GRuleId_t nextR; /* Next rule with same {R} field, or {NORULE} if none. */ } GRule_t; /* The grammar: */ typedef struct Grammar_t { int NS; /* Number of symbols. */ int NR; /* Number of rules. */ char **sname; /* {sname[S]} is an external name of symbol {S}. */ GRule_t *rule; /* The rules, indexed by {GRuleId_t}. */ GRuleId_t *firstH; /* {firstH[S]} is a rule with {H == S}, or {NORULE}. */ GRuleId_t *firstL; /* {firstL[S]} is a rule with {L == S}, or {NORULE}. */ GRuleId_t *firstR; /* {firstR[S]} is a rule with {R == S}, or {NORULE}. */ } Grammar_t; Grammar_t *grr_read_Grammar(FILE *rd); /* The grammar consists of zero or more rules, one per line, of the form "{H} -> {L} {R}" where {H}, {L}, {R} are strings matching the pattern [*$_(),A_Za-z0-9]+. The part {R} or both {L} and {R} may be omitted. Comment lines and/or blank lines are ignored. */ void grr_write_Grammar(FILE *wr, Grammar_t *G); /* Writes a grammar {G} to {wr}, in the numeric format expected by {cfg_parser}. */ void grr_free_grammar(Grammar_t *G); /* Frees all storage associated with the grammar {G}, including the symbol names and the record {G} itself. */ char *grr_copy_name(char *sOld); /* If {sOld} is NULL, returns NULL; otherwise creates a fresh copy of the string {sOld} and returns its address. */ void grr_build_lists(Grammar_t *G); /* (Re)builds the inverted rule lists, namely the arrays {G->firstH,G->firstL,G->firstR} and the fields {nextH,nextL,nextR} in all rules of {G}. */ Grammar_t *grr_new_Grammar(int NS, int NR); /* Allocates a new grammar with {NS} symbols and {NR} rules, including the inverted list tables {firstH,firstR,firstL}. Initially all symbols have {sname = NULL} and all rules are {NOSYMB -> NOSYMB NOSYMB}. */ bool_t grr_is_symbol_char(int c); /* TRUE iff {c} is a character that can be used in the name of a symbol. */ /* DEBUGING: */ void grr_file_error(char *where, int loc, char *msg); /* Prints the string {where}, the line counter {loc}, and the message {msg}, then aborts with error status. */ void grr_print_rule(FILE *wr, Grammar_t *G, char *pre, GRule_t *r, char *suf); void grr_print_symbol(FILE *wr, Grammar_t *G, char *pre, GSymbId_t S, char *suf); /* Prints the string {pre}, the given symbol or rule, and the string {suf}. */ extern bool_t grr_debug; void grr_debug_rule(FILE *wr, Grammar_t *G, char *pre, GRule_t *r, char *suf); void grr_debug_symbol(FILE *wr, Grammar_t *G, char *pre, GSymbId_t S, char *suf); /* Like {} an d{}, but print onlly if the global {grr_debug} flag is set. */ /* VECTORS OF RULES: */ vec_typedef(GRule_vec_t,GRule_vec,GRule_t); /* A vector of rules ({GRule_t}s). The procedure {GRule_vec_new(n)} allocates a vector with space for {n} elements. The procedure {GRule_vec_expand(&nv,ix)} makes sure that the vector {nv} has element {nv.e[ix]}. Reallocates {nv.e} if necessary, to have at least {index+1} elements -- but possibly more. The procedure {GRule_vec_trim(nv,ne)} makes sure that the vector {nv} has exactly {ne} elements. Reallocates {nv.e} if necessary. */ #endif