Merge pull request #167 from steve-chavez/sepby-repeat
fix: mpc_sepby1 not applying fold correctly
This commit is contained in:
87
mpc.c
87
mpc.c
@@ -916,7 +916,9 @@ enum {
|
|||||||
MPC_TYPE_CHECK_WITH = 26,
|
MPC_TYPE_CHECK_WITH = 26,
|
||||||
|
|
||||||
MPC_TYPE_SOI = 27,
|
MPC_TYPE_SOI = 27,
|
||||||
MPC_TYPE_EOI = 28
|
MPC_TYPE_EOI = 28,
|
||||||
|
|
||||||
|
MPC_TYPE_SEPBY1 = 29
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct { char *m; } mpc_pdata_fail_t;
|
typedef struct { char *m; } mpc_pdata_fail_t;
|
||||||
@@ -936,6 +938,7 @@ typedef struct { mpc_parser_t *x; mpc_dtor_t dx; mpc_ctor_t lf; } mpc_pdata_not_
|
|||||||
typedef struct { int n; mpc_fold_t f; mpc_parser_t *x; mpc_dtor_t dx; } mpc_pdata_repeat_t;
|
typedef struct { int n; mpc_fold_t f; mpc_parser_t *x; mpc_dtor_t dx; } mpc_pdata_repeat_t;
|
||||||
typedef struct { int n; mpc_parser_t **xs; } mpc_pdata_or_t;
|
typedef struct { int n; mpc_parser_t **xs; } mpc_pdata_or_t;
|
||||||
typedef struct { int n; mpc_fold_t f; mpc_parser_t **xs; mpc_dtor_t *dxs; } mpc_pdata_and_t;
|
typedef struct { int n; mpc_fold_t f; mpc_parser_t **xs; mpc_dtor_t *dxs; } mpc_pdata_and_t;
|
||||||
|
typedef struct { int n; mpc_fold_t f; mpc_parser_t *x; mpc_parser_t *sep; } mpc_pdata_sepby1;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
mpc_pdata_fail_t fail;
|
mpc_pdata_fail_t fail;
|
||||||
@@ -955,6 +958,7 @@ typedef union {
|
|||||||
mpc_pdata_repeat_t repeat;
|
mpc_pdata_repeat_t repeat;
|
||||||
mpc_pdata_and_t and;
|
mpc_pdata_and_t and;
|
||||||
mpc_pdata_or_t or;
|
mpc_pdata_or_t or;
|
||||||
|
mpc_pdata_sepby1 sepby1;
|
||||||
} mpc_pdata_t;
|
} mpc_pdata_t;
|
||||||
|
|
||||||
struct mpc_parser_t {
|
struct mpc_parser_t {
|
||||||
@@ -1046,7 +1050,7 @@ enum {
|
|||||||
|
|
||||||
#define MPC_MAX_RECURSION_DEPTH 1000
|
#define MPC_MAX_RECURSION_DEPTH 1000
|
||||||
|
|
||||||
static mpc_result_t *grow_results(mpc_input_t *i, int j, mpc_result_t *results_stk, mpc_result_t *results){
|
static mpc_result_t *mpc_grow_results(mpc_input_t *i, int j, mpc_result_t *results_stk, mpc_result_t *results){
|
||||||
mpc_result_t *tmp_results = results;
|
mpc_result_t *tmp_results = results;
|
||||||
|
|
||||||
if (j == MPC_PARSE_STACK_MIN) {
|
if (j == MPC_PARSE_STACK_MIN) {
|
||||||
@@ -1190,7 +1194,7 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
|
|||||||
|
|
||||||
while (mpc_parse_run(i, p->data.repeat.x, &results[j], e, depth+1)) {
|
while (mpc_parse_run(i, p->data.repeat.x, &results[j], e, depth+1)) {
|
||||||
j++;
|
j++;
|
||||||
results = grow_results(i, j, results_stk, results);
|
results = mpc_grow_results(i, j, results_stk, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
*e = mpc_err_merge(i, *e, results[j].error);
|
*e = mpc_err_merge(i, *e, results[j].error);
|
||||||
@@ -1205,7 +1209,7 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
|
|||||||
|
|
||||||
while (mpc_parse_run(i, p->data.repeat.x, &results[j], e, depth+1)) {
|
while (mpc_parse_run(i, p->data.repeat.x, &results[j], e, depth+1)) {
|
||||||
j++;
|
j++;
|
||||||
results = grow_results(i, j, results_stk, results);
|
results = mpc_grow_results(i, j, results_stk, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
@@ -1221,6 +1225,35 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
|
|||||||
if (j >= MPC_PARSE_STACK_MIN) { mpc_free(i, results); });
|
if (j >= MPC_PARSE_STACK_MIN) { mpc_free(i, results); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case MPC_TYPE_SEPBY1:
|
||||||
|
|
||||||
|
results = results_stk;
|
||||||
|
|
||||||
|
if(mpc_parse_run(i, p->data.sepby1.x, &results[j], e, depth+1)){
|
||||||
|
j++;
|
||||||
|
results = mpc_grow_results(i, j, results_stk, results);
|
||||||
|
|
||||||
|
while (
|
||||||
|
mpc_parse_run(i, p->data.sepby1.sep, &results[j], e, depth+1) &&
|
||||||
|
mpc_parse_run(i, p->data.sepby1.x, &results[j], e, depth+1)
|
||||||
|
) {
|
||||||
|
j++;
|
||||||
|
results = mpc_grow_results(i, j, results_stk, results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j == 0) {
|
||||||
|
MPC_FAILURE(
|
||||||
|
mpc_err_many1(i, results[j].error);
|
||||||
|
if (j >= MPC_PARSE_STACK_MIN) { mpc_free(i, results); });
|
||||||
|
} else {
|
||||||
|
*e = mpc_err_merge(i, *e, results[j].error);
|
||||||
|
|
||||||
|
MPC_SUCCESS(
|
||||||
|
mpc_parse_fold(i, p->data.repeat.f, j, (mpc_val_t**)results);
|
||||||
|
if (j >= MPC_PARSE_STACK_MIN) { mpc_free(i, results); });
|
||||||
|
}
|
||||||
|
|
||||||
case MPC_TYPE_COUNT:
|
case MPC_TYPE_COUNT:
|
||||||
|
|
||||||
results = p->data.repeat.n > MPC_PARSE_STACK_MIN
|
results = p->data.repeat.n > MPC_PARSE_STACK_MIN
|
||||||
@@ -1268,7 +1301,6 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
|
|||||||
if (p->data.or.n > MPC_PARSE_STACK_MIN) { mpc_free(i, results); });
|
if (p->data.or.n > MPC_PARSE_STACK_MIN) { mpc_free(i, results); });
|
||||||
|
|
||||||
case MPC_TYPE_AND:
|
case MPC_TYPE_AND:
|
||||||
|
|
||||||
if (p->data.and.n == 0) { MPC_SUCCESS(NULL); }
|
if (p->data.and.n == 0) { MPC_SUCCESS(NULL); }
|
||||||
|
|
||||||
results = p->data.or.n > MPC_PARSE_STACK_MIN
|
results = p->data.or.n > MPC_PARSE_STACK_MIN
|
||||||
@@ -1429,6 +1461,11 @@ static void mpc_undefine_unretained(mpc_parser_t *p, int force) {
|
|||||||
mpc_undefine_unretained(p->data.repeat.x, 0);
|
mpc_undefine_unretained(p->data.repeat.x, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MPC_TYPE_SEPBY1:
|
||||||
|
mpc_undefine_unretained(p->data.sepby1.x, 0);
|
||||||
|
mpc_undefine_unretained(p->data.sepby1.sep, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
case MPC_TYPE_OR: mpc_undefine_or(p); break;
|
case MPC_TYPE_OR: mpc_undefine_or(p); break;
|
||||||
case MPC_TYPE_AND: mpc_undefine_and(p); break;
|
case MPC_TYPE_AND: mpc_undefine_and(p); break;
|
||||||
|
|
||||||
@@ -1538,6 +1575,11 @@ mpc_parser_t *mpc_copy(mpc_parser_t *a) {
|
|||||||
p->data.repeat.x = mpc_copy(a->data.repeat.x);
|
p->data.repeat.x = mpc_copy(a->data.repeat.x);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MPC_TYPE_SEPBY1:
|
||||||
|
p->data.sepby1.x = mpc_copy(a->data.sepby1.x);
|
||||||
|
p->data.sepby1.sep = mpc_copy(a->data.sepby1.sep);
|
||||||
|
break;
|
||||||
|
|
||||||
case MPC_TYPE_OR:
|
case MPC_TYPE_OR:
|
||||||
p->data.or.xs = malloc(a->data.or.n * sizeof(mpc_parser_t*));
|
p->data.or.xs = malloc(a->data.or.n * sizeof(mpc_parser_t*));
|
||||||
for (i = 0; i < a->data.or.n; i++) {
|
for (i = 0; i < a->data.or.n; i++) {
|
||||||
@@ -1933,6 +1975,15 @@ mpc_parser_t *mpc_count(int n, mpc_fold_t f, mpc_parser_t *a, mpc_dtor_t da) {
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mpc_parser_t *mpc_sepby1(mpc_fold_t f, mpc_parser_t *sep, mpc_parser_t *a) {
|
||||||
|
mpc_parser_t *p = mpc_undefined();
|
||||||
|
p->type = MPC_TYPE_SEPBY1;
|
||||||
|
p->data.sepby1.x = a;
|
||||||
|
p->data.sepby1.f = f;
|
||||||
|
p->data.sepby1.sep = sep;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
mpc_parser_t *mpc_or(int n, ...) {
|
mpc_parser_t *mpc_or(int n, ...) {
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
@@ -2120,12 +2171,6 @@ mpc_parser_t *mpc_tok_braces(mpc_parser_t *a, mpc_dtor_t ad) { return mpc_tok_
|
|||||||
mpc_parser_t *mpc_tok_brackets(mpc_parser_t *a, mpc_dtor_t ad) { return mpc_tok_between(a, ad, "{", "}"); }
|
mpc_parser_t *mpc_tok_brackets(mpc_parser_t *a, mpc_dtor_t ad) { return mpc_tok_between(a, ad, "{", "}"); }
|
||||||
mpc_parser_t *mpc_tok_squares(mpc_parser_t *a, mpc_dtor_t ad) { return mpc_tok_between(a, ad, "[", "]"); }
|
mpc_parser_t *mpc_tok_squares(mpc_parser_t *a, mpc_dtor_t ad) { return mpc_tok_between(a, ad, "[", "]"); }
|
||||||
|
|
||||||
mpc_parser_t *mpc_sepby1(mpc_fold_t f, mpc_parser_t *sep, mpc_parser_t *a) {
|
|
||||||
return mpc_and(2, f,
|
|
||||||
a, mpc_many(f, mpc_and(2, mpcf_snd_free, sep, mpc_copy(a), free)),
|
|
||||||
free);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Regular Expression Parsers
|
** Regular Expression Parsers
|
||||||
*/
|
*/
|
||||||
@@ -2771,6 +2816,15 @@ static void mpc_print_unretained(mpc_parser_t *p, int force) {
|
|||||||
if (p->type == MPC_TYPE_MANY) { mpc_print_unretained(p->data.repeat.x, 0); printf("*"); }
|
if (p->type == MPC_TYPE_MANY) { mpc_print_unretained(p->data.repeat.x, 0); printf("*"); }
|
||||||
if (p->type == MPC_TYPE_MANY1) { mpc_print_unretained(p->data.repeat.x, 0); printf("+"); }
|
if (p->type == MPC_TYPE_MANY1) { mpc_print_unretained(p->data.repeat.x, 0); printf("+"); }
|
||||||
if (p->type == MPC_TYPE_COUNT) { mpc_print_unretained(p->data.repeat.x, 0); printf("{%i}", p->data.repeat.n); }
|
if (p->type == MPC_TYPE_COUNT) { mpc_print_unretained(p->data.repeat.x, 0); printf("{%i}", p->data.repeat.n); }
|
||||||
|
if (p->type == MPC_TYPE_SEPBY1) {
|
||||||
|
mpc_print_unretained(p->data.sepby1.x, 0);
|
||||||
|
printf(" (");
|
||||||
|
mpc_print_unretained(p->data.sepby1.sep, 0);
|
||||||
|
printf(" ");
|
||||||
|
mpc_print_unretained(p->data.sepby1.x, 0);
|
||||||
|
printf(")");
|
||||||
|
printf("*");
|
||||||
|
}
|
||||||
|
|
||||||
if (p->type == MPC_TYPE_OR) {
|
if (p->type == MPC_TYPE_OR) {
|
||||||
printf("(");
|
printf("(");
|
||||||
@@ -3860,6 +3914,13 @@ static int mpc_nodecount_unretained(mpc_parser_t* p, int force) {
|
|||||||
if (p->type == MPC_TYPE_MANY) { return 1 + mpc_nodecount_unretained(p->data.repeat.x, 0); }
|
if (p->type == MPC_TYPE_MANY) { return 1 + mpc_nodecount_unretained(p->data.repeat.x, 0); }
|
||||||
if (p->type == MPC_TYPE_MANY1) { return 1 + mpc_nodecount_unretained(p->data.repeat.x, 0); }
|
if (p->type == MPC_TYPE_MANY1) { return 1 + mpc_nodecount_unretained(p->data.repeat.x, 0); }
|
||||||
if (p->type == MPC_TYPE_COUNT) { return 1 + mpc_nodecount_unretained(p->data.repeat.x, 0); }
|
if (p->type == MPC_TYPE_COUNT) { return 1 + mpc_nodecount_unretained(p->data.repeat.x, 0); }
|
||||||
|
if (p->type == MPC_TYPE_SEPBY1) {
|
||||||
|
total = 1;
|
||||||
|
total += mpc_nodecount_unretained(p->data.sepby1.x, 0);
|
||||||
|
total += mpc_nodecount_unretained(p->data.sepby1.sep, 0);
|
||||||
|
total += mpc_nodecount_unretained(p->data.sepby1.x, 0);
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
if (p->type == MPC_TYPE_OR) {
|
if (p->type == MPC_TYPE_OR) {
|
||||||
total = 1;
|
total = 1;
|
||||||
@@ -3907,6 +3968,10 @@ static void mpc_optimise_unretained(mpc_parser_t *p, int force) {
|
|||||||
if (p->type == MPC_TYPE_MANY) { mpc_optimise_unretained(p->data.repeat.x, 0); }
|
if (p->type == MPC_TYPE_MANY) { mpc_optimise_unretained(p->data.repeat.x, 0); }
|
||||||
if (p->type == MPC_TYPE_MANY1) { mpc_optimise_unretained(p->data.repeat.x, 0); }
|
if (p->type == MPC_TYPE_MANY1) { mpc_optimise_unretained(p->data.repeat.x, 0); }
|
||||||
if (p->type == MPC_TYPE_COUNT) { mpc_optimise_unretained(p->data.repeat.x, 0); }
|
if (p->type == MPC_TYPE_COUNT) { mpc_optimise_unretained(p->data.repeat.x, 0); }
|
||||||
|
if (p->type == MPC_TYPE_SEPBY1) {
|
||||||
|
mpc_optimise_unretained(p->data.sepby1.x, 0);
|
||||||
|
mpc_optimise_unretained(p->data.sepby1.sep, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (p->type == MPC_TYPE_OR) {
|
if (p->type == MPC_TYPE_OR) {
|
||||||
for(i = 0; i < p->data.or.n; i++) {
|
for(i = 0; i < p->data.or.n; i++) {
|
||||||
|
18
tests/core.c
18
tests/core.c
@@ -8,6 +8,11 @@ static int int_eq(const void* x, const void* y) { return (*(int*)x == *(int*)y);
|
|||||||
static void int_print(const void* x) { printf("'%i'", *((int*)x)); }
|
static void int_print(const void* x) { printf("'%i'", *((int*)x)); }
|
||||||
static int streq(const void* x, const void* y) { return (strcmp(x, y) == 0); }
|
static int streq(const void* x, const void* y) { return (strcmp(x, y) == 0); }
|
||||||
static void strprint(const void* x) { printf("'%s'", (char*)x); }
|
static void strprint(const void* x) { printf("'%s'", (char*)x); }
|
||||||
|
static mpc_val_t *fold_vals(int n, mpc_val_t **xs) {
|
||||||
|
char** vals = malloc(sizeof(char*) * n);
|
||||||
|
memcpy(vals, xs, sizeof(char*) * n);
|
||||||
|
return vals;
|
||||||
|
}
|
||||||
|
|
||||||
void test_ident(void) {
|
void test_ident(void) {
|
||||||
|
|
||||||
@@ -252,6 +257,19 @@ void test_sepby(void) {
|
|||||||
PT_ASSERT(mpc_test_pass(CommaSepIdent, "one,two,three", "onetwothree", streq, free, strprint));
|
PT_ASSERT(mpc_test_pass(CommaSepIdent, "one,two,three", "onetwothree", streq, free, strprint));
|
||||||
|
|
||||||
mpc_delete(CommaSepIdent);
|
mpc_delete(CommaSepIdent);
|
||||||
|
|
||||||
|
mpc_parser_t* CommaSepIdent1 = mpc_sepby1(fold_vals, mpc_char(','), mpc_ident());
|
||||||
|
mpc_result_t r;
|
||||||
|
|
||||||
|
mpc_parse("<test>", "uno,dos,tres,cuatro", CommaSepIdent1, &r);
|
||||||
|
char **vals = r.output;
|
||||||
|
PT_ASSERT(strcmp("uno", vals[0]) == 0);
|
||||||
|
PT_ASSERT(strcmp("dos", vals[1]) == 0);
|
||||||
|
PT_ASSERT(strcmp("tres", vals[2]) == 0);
|
||||||
|
PT_ASSERT(strcmp("cuatro", vals[3]) == 0);
|
||||||
|
|
||||||
|
free(vals);
|
||||||
|
mpc_delete(CommaSepIdent1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void suite_core(void) {
|
void suite_core(void) {
|
||||||
|
Reference in New Issue
Block a user