feat: add sepby1 combinator
`sepby1` is a common reusable combinator in Haskell Parsec. This adds `mpc_sepby1(mpc_fold_t f, mpc_parser_t *sep, mpc_parser_t *a)` according to Haskell's implementation: https://hackage.haskell.org/package/parsec-3.1.16.1/docs/src/Text.Parsec.Combinator.html#sepBy1 Reuses existing `mpc_and`, `mpc_many`, and `mpcf_snd_free`.
This commit is contained in:
@@ -356,6 +356,14 @@ Runs `a` one or more times until it fails. Results are combined with fold functi
|
|||||||
|
|
||||||
* * *
|
* * *
|
||||||
|
|
||||||
|
```c
|
||||||
|
mpc_parser_t *mpc_sepby1(mpc_fold_t f, mpc_parser_t *sep, mpc_parser_t *a);
|
||||||
|
```
|
||||||
|
|
||||||
|
Runs `a` one or more times, separated by `sep`. Results are combined with fold function `f`.
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
```c
|
```c
|
||||||
mpc_parser_t *mpc_count(int n, mpc_fold_t f, mpc_parser_t *a, mpc_dtor_t da);
|
mpc_parser_t *mpc_count(int n, mpc_fold_t f, mpc_parser_t *a, mpc_dtor_t da);
|
||||||
```
|
```
|
||||||
|
6
mpc.c
6
mpc.c
@@ -2120,6 +2120,12 @@ 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
|
||||||
*/
|
*/
|
||||||
|
2
mpc.h
2
mpc.h
@@ -220,6 +220,8 @@ mpc_parser_t *mpc_tok_braces(mpc_parser_t *a, mpc_dtor_t ad);
|
|||||||
mpc_parser_t *mpc_tok_brackets(mpc_parser_t *a, mpc_dtor_t ad);
|
mpc_parser_t *mpc_tok_brackets(mpc_parser_t *a, mpc_dtor_t ad);
|
||||||
mpc_parser_t *mpc_tok_squares(mpc_parser_t *a, mpc_dtor_t ad);
|
mpc_parser_t *mpc_tok_squares(mpc_parser_t *a, mpc_dtor_t ad);
|
||||||
|
|
||||||
|
mpc_parser_t *mpc_sepby1(mpc_fold_t f, mpc_parser_t *sep, mpc_parser_t *a);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Common Function Parameters
|
** Common Function Parameters
|
||||||
*/
|
*/
|
||||||
|
13
tests/core.c
13
tests/core.c
@@ -242,6 +242,18 @@ void test_eoi(void) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_sepby(void) {
|
||||||
|
mpc_parser_t* CommaSepIdent = mpc_sepby1(mpcf_strfold, mpc_char(','), mpc_ident());
|
||||||
|
|
||||||
|
PT_ASSERT(mpc_test_fail(CommaSepIdent, "", "", streq, free, strprint));
|
||||||
|
PT_ASSERT(mpc_test_pass(CommaSepIdent, "one", "one", streq, free, strprint));
|
||||||
|
PT_ASSERT(mpc_test_pass(CommaSepIdent, "one,", "one", streq, free, strprint));
|
||||||
|
PT_ASSERT(mpc_test_pass(CommaSepIdent, "one,two,", "onetwo", streq, free, strprint));
|
||||||
|
PT_ASSERT(mpc_test_pass(CommaSepIdent, "one,two,three", "onetwothree", streq, free, strprint));
|
||||||
|
|
||||||
|
mpc_delete(CommaSepIdent);
|
||||||
|
}
|
||||||
|
|
||||||
void suite_core(void) {
|
void suite_core(void) {
|
||||||
pt_add_test(test_ident, "Test Ident", "Suite Core");
|
pt_add_test(test_ident, "Test Ident", "Suite Core");
|
||||||
pt_add_test(test_maths, "Test Maths", "Suite Core");
|
pt_add_test(test_maths, "Test Maths", "Suite Core");
|
||||||
@@ -251,4 +263,5 @@ void suite_core(void) {
|
|||||||
pt_add_test(test_reader, "Test Reader", "Suite Core");
|
pt_add_test(test_reader, "Test Reader", "Suite Core");
|
||||||
pt_add_test(test_tokens, "Test Tokens", "Suite Core");
|
pt_add_test(test_tokens, "Test Tokens", "Suite Core");
|
||||||
pt_add_test(test_eoi, "Test EOI", "Suite Core");
|
pt_add_test(test_eoi, "Test EOI", "Suite Core");
|
||||||
|
pt_add_test(test_sepby, "Test SepBy", "Suite Core");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user