#include #include #include "expression.h" struct li_production_t * li_production_alloc(size_t seq_len) { struct li_production_t *prod = malloc(sizeof(struct li_production_t)); if (prod == NULL) { fprintf(stderr, "failed to allocate production rule\n"); return NULL; } prod->seq = malloc(seq_len * sizeof(int)); if (prod->seq == NULL) { fprintf(stderr, "failed to allocate production sequence buffer\n"); free(prod); return NULL; } prod->seq_len = seq_len; prod->next = NULL; return prod; } void li_production_free(struct li_production_t *prod) { if (prod != NULL) { li_production_free(prod->next); free(prod->seq); free(prod); } } struct li_production_rule_t * li_prod_rule_alloc() { struct li_production_rule_t *rule = malloc(sizeof(struct li_production_rule_t)); if (rule == NULL) { fprintf(stderr, "failed to allocate production rule\n"); return NULL; } rule->num_productions = 0; rule->head = NULL; return rule; } void li_prod_rule_free(struct li_production_rule_t *rule) { if (rule != NULL) { li_production_free(rule->head); free(rule); } } int li_prod_rule_add( struct li_production_rule_t *rule, size_t seq_len, int *seq ) { struct li_production_t *prod = li_production_alloc(seq_len); if (prod == NULL) { return 1; } memcpy(prod->seq, seq, seq_len*sizeof(int)); prod->next = rule->head; rule->head = prod; rule->num_productions += 1; return 0; } li_grammar_t * li_grammar_alloc(size_t num_nonterminal) { li_grammar_t *grammar = malloc(sizeof(li_grammar_t)); if (grammar == NULL) { fprintf(stderr, "failed to allocate grammar\n"); return NULL; } grammar->rules = malloc(num_nonterminal * sizeof(struct li_production_rule_t)); if (grammar->rules == NULL) { fprintf(stderr, "failed to allocate grammar rules buffer\n"); free(grammar); return NULL; } for (size_t i=0; irules[i].num_productions = 0; grammar->rules[i].head = NULL; } grammar->num_nonterminal = NULL; return grammar; } void li_grammar_free(li_grammar_t *grammar) { if (grammar != NULL) { for (size_t i=0; inum_nonterminal; i++) { li_production_free(grammar->rules[i].head); } free(grammar->rules); free(grammar); } } int li_grammar_rule_add( li_grammar_t *grammar, int nonterminal, size_t seq_len, int *seq ) { if (nonterminal < 0 || nonterminal >= grammar->num_nonterminal) { return 2; } return li_prod_rule_add(grammar->rules + nonterminal, seq_len, seq); }