static int parse_class(struct peg_grammar_parser *pgp, struct peg_cursor *pc, int *clsp) { struct peg_grammar *peg = pgp->peg; struct peg_cursor npc = *pc; char c; int nn; struct peg_node *cls; uchar *cset; if ( CHAR(pgp, &npc) != '[' && CHAR(pgp, &npc) != '.' ) return 0; nn = peg_node_new(peg, PEG_CLASS, pc->line); if ( nn < 0 ) { pgp->err = PEG_ERR_NOMEM; return -1; } cset = malloc(32); if ( cset == NULL ) { peg_node_free(peg, nn); pgp->err = PEG_ERR_NOMEM; return -1; } /* treat . as a special class that matches almost everying */ if ( CHAR(pgp, &npc) == '.' ) { cset_fill(cset); cset_rem(cset, '\0'); goto match; } else { cset_clear(cset); npc.pos += 1; } while ( (c = CHAR(pgp, &npc)) != ']' && c != '\0' ) if ( class_add_char(pgp, &npc, cset) < 0 ) return -1; if ( c == '\0' ) { pgp->err = PEG_ERR_BAD_CLASS; pgp->eloc = npc; free(cset); peg_node_free(peg, nn); return -1; } match: cls = NODE(peg, nn); cls->pc_cset = cset; cls->pc_cset_size = 32; npc.pos += 1; *pc = npc; *clsp = nn; skip_space(pgp, pc); return 1; }
void clear_bnf_index(bnf_index* bi) { if(!bi)return; cset_clear((*bi).lookaheads,0); }