diff --git a/README.md b/README.md
index 7075c78..3c1acd8 100644
--- a/README.md
+++ b/README.md
@@ -116,7 +116,7 @@ Basic Parsers
All the following functions construct new basic parsers of the type `mpc_parser_t *`. All of those parsers return a newly allocated `char *` with the character(s) they manage to match. If unsuccessful they will return an error. They have the following functionality.
-* * *
+* * *
```c
mpc_parser_t *mpc_any(void);
@@ -124,7 +124,7 @@ mpc_parser_t *mpc_any(void);
Matches any individual character
-* * *
+* * *
```c
mpc_parser_t *mpc_char(char c);
@@ -283,7 +283,7 @@ Run a parser on the contents of some file.
Combinators
-----------
-Combinators are functions that take one or more parsers and return a new parser of some given functionality.
+Combinators are functions that take one or more parsers and return a new parser of some given functionality.
These combinators work independently of exactly what data type the parser(s) supplied as input return. In languages such as Haskell ensuring you don't input one type of data into a parser requiring a different type is done by the compiler. But in C we don't have that luxury. So it is at the discretion of the programmer to ensure that he or she deals correctly with the outputs of different parser types.
@@ -556,9 +556,9 @@ To ease the task of undefining and then deleting parsers `mpc_cleanup` can be us
mpc_parser_t *mpc_copy(mpc_parser_t *a);
```
-This function makes a copy of a parser `a`. This can be useful when you want to
-use a parser as input for some other parsers multiple times without retaining
-it.
+This function makes a copy of a parser `a`. This can be useful when you want to
+use a parser as input for some other parsers multiple times without retaining
+it.
* * *
@@ -567,11 +567,11 @@ mpc_parser_t *mpc_re(const char *re);
mpc_parser_t *mpc_re_mode(const char *re, int mode);
```
-This function takes as input the regular expression `re` and builds a parser
-for it. With the `mpc_re_mode` function optional mode flags can also be given.
-Available flags are `MPC_RE_MULTILINE` / `MPC_RE_M` where the start of input
-character `^` also matches the beginning of new lines and the end of input `$`
-character also matches new lines, and `MPC_RE_DOTALL` / `MPC_RE_S` where the
+This function takes as input the regular expression `re` and builds a parser
+for it. With the `mpc_re_mode` function optional mode flags can also be given.
+Available flags are `MPC_RE_MULTILINE` / `MPC_RE_M` where the start of input
+character `^` also matches the beginning of new lines and the end of input `$`
+character also matches new lines, and `MPC_RE_DOTALL` / `MPC_RE_S` where the
any character token `.` also matches newlines (by default it doesn't).
@@ -626,7 +626,7 @@ Useful Parsers
mpc_startswith(mpc_parser_t *a); | Matches the start of input followed by a |
mpc_endswith(mpc_parser_t *a, mpc_dtor_t da); | Matches a followed by the end of input |
- mpc_whole(mpc_parser_t *a, mpc_dtor_t da); | Matches the start of input, a , and the end of input |
+ mpc_whole(mpc_parser_t *a, mpc_dtor_t da); | Matches the start of input, a , and the end of input |
mpc_stripl(mpc_parser_t *a); | Matches a first consuming any whitespace to the left |
mpc_stripr(mpc_parser_t *a); | Matches a then consumes any whitespace to the right |
mpc_strip(mpc_parser_t *a); | Matches a consuming any surrounding whitespace |
@@ -707,17 +707,17 @@ We start with a fold function that will fold two `int *` into a new `int *` base
```c
mpc_val_t *fold_maths(int n, mpc_val_t **xs) {
-
+
int **vs = (int**)xs;
-
+
if (strcmp(xs[1], "*") == 0) { *vs[0] *= *vs[2]; }
if (strcmp(xs[1], "/") == 0) { *vs[0] /= *vs[2]; }
if (strcmp(xs[1], "%") == 0) { *vs[0] %= *vs[2]; }
if (strcmp(xs[1], "+") == 0) { *vs[0] += *vs[2]; }
if (strcmp(xs[1], "-") == 0) { *vs[0] -= *vs[2]; }
-
+
free(xs[1]); free(xs[2]);
-
+
return xs[0];
}
```
@@ -730,14 +730,14 @@ mpc_parser_t *Factor = mpc_new("factor");
mpc_parser_t *Term = mpc_new("term");
mpc_parser_t *Maths = mpc_new("maths");
-mpc_define(Expr, mpc_or(2,
+mpc_define(Expr, mpc_or(2,
mpc_and(3, fold_maths,
Factor, mpc_oneof("+-"), Factor,
free, free),
Factor
));
-mpc_define(Factor, mpc_or(2,
+mpc_define(Factor, mpc_or(2,
mpc_and(3, fold_maths,
Term, mpc_oneof("*/"), Term,
free, free),
@@ -781,6 +781,8 @@ The syntax for this is defined as follows.
'a' | 'b' | Either 'a' is required, or 'b' is required. |
'a'* | Zero or more 'a' are required. |
'a'+ | One or more 'a' are required. |
+ 'a'? | Zero or one 'a' is required. |
+ 'a'{x} | Exactly x (integer) copies of 'a' are required. |
<abba> | The rule called abba is required. |
@@ -825,17 +827,17 @@ This opens and reads in the contents of the file given by `filename` and passes
Case Study - Tokenizer
======================
-Another common task we might be interested in doing is tokenizing some block of
+Another common task we might be interested in doing is tokenizing some block of
text (splitting the text into individual elements) and performing some function
on each one of these elements as it is read. We can do this with `mpc` too.
-First, we can build a regular expression which parses an individual token. For
-example if our tokens are identifiers, integers, commas, periods and colons we
-could build something like this `mpc_re("\\s*([a-zA-Z_]+|[0-9]+|,|\\.|:)")`.
-Next we can strip any whitespace, and add a callback function using `mpc_apply`
-which gets called every time this regex is parsed successfully
-`mpc_apply(mpc_strip(mpc_re("\\s*([a-zA-Z_]+|[0-9]+|,|\\.|:)")), print_token)`.
-Finally we can surround all of this in `mpc_many` to parse it zero or more
+First, we can build a regular expression which parses an individual token. For
+example if our tokens are identifiers, integers, commas, periods and colons we
+could build something like this `mpc_re("\\s*([a-zA-Z_]+|[0-9]+|,|\\.|:)")`.
+Next we can strip any whitespace, and add a callback function using `mpc_apply`
+which gets called every time this regex is parsed successfully
+`mpc_apply(mpc_strip(mpc_re("\\s*([a-zA-Z_]+|[0-9]+|,|\\.|:)")), print_token)`.
+Finally we can surround all of this in `mpc_many` to parse it zero or more
times. The final code might look something like this:
```c
@@ -847,16 +849,16 @@ static mpc_val_t *print_token(mpc_val_t *x) {
int main(int argc, char **argv) {
const char *input = " hello 4352 , \n foo.bar \n\n test:ing ";
-
+
mpc_parser_t* Tokens = mpc_many(
- mpcf_all_free,
+ mpcf_all_free,
mpc_apply(mpc_strip(mpc_re("\\s*([a-zA-Z_]+|[0-9]+|,|\\.|:)")), print_token));
-
+
mpc_result_t r;
mpc_parse("input", input, Tokens, &r);
-
+
mpc_delete(Tokens);
-
+
return 0;
}
```
@@ -875,7 +877,7 @@ Token: ':'
Token: 'ing'
```
-By extending the regex we can easily extend this to parse many more types of
+By extending the regex we can easily extend this to parse many more types of
tokens and quickly and easily build a tokenizer for whatever language we are
interested in.
@@ -991,5 +993,3 @@ When parsing from a grammar, the abstract syntax tree is tagged with different t
If you have a rule in your grammar called `string`, `char` or `regex`, you may encounter some confusion. This is because nodes will be tagged with (for example) `string` _either_ if they are a string primitive, _or_ if they were parsed via your `string` rule. If you are detecting node type using something like `strstr`, in this situation it might break. One solution to this is to always check that `string` is the innermost tag to test for string primitives, or to rename your rule called `string` to something that doesn't conflict.
Yes it is annoying but its probably not going to change!
-
-
diff --git a/mpc.c b/mpc.c
index c3f7344..8e8e83e 100644
--- a/mpc.c
+++ b/mpc.c
@@ -27,24 +27,24 @@ static mpc_state_t mpc_state_new(void) {
*/
/*
-** In mpc the input type has three modes of
+** In mpc the input type has three modes of
** operation: String, File and Pipe.
**
-** String is easy. The whole contents are
+** String is easy. The whole contents are
** loaded into a buffer and scanned through.
-** The cursor can jump around at will making
+** The cursor can jump around at will making
** backtracking easy.
**
** The second is a File which is also somewhat
-** easy. The contents are never loaded into
+** easy. The contents are never loaded into
** memory but backtracking can still be achieved
** by seeking in the file at different positions.
**
** The final mode is Pipe. This is the difficult
-** one. As we assume pipes cannot be seeked - and
-** only support a single character lookahead at
-** any point, when the input is marked for a
-** potential backtracking we start buffering any
+** one. As we assume pipes cannot be seeked - and
+** only support a single character lookahead at
+** any point, when the input is marked for a
+** potential backtracking we start buffering any
** input.
**
** This means that if we are requested to seek
@@ -78,43 +78,43 @@ typedef struct {
typedef struct {
int type;
- char *filename;
+ char *filename;
mpc_state_t state;
-
+
char *string;
char *buffer;
FILE *file;
-
+
int suppress;
int backtrack;
int marks_slots;
int marks_num;
mpc_state_t *marks;
-
+
char *lasts;
char last;
-
+
size_t mem_index;
char mem_full[MPC_INPUT_MEM_NUM];
mpc_mem_t mem[MPC_INPUT_MEM_NUM];
-
+
} mpc_input_t;
static mpc_input_t *mpc_input_new_string(const char *filename, const char *string) {
mpc_input_t *i = malloc(sizeof(mpc_input_t));
-
+
i->filename = malloc(strlen(filename) + 1);
strcpy(i->filename, filename);
i->type = MPC_INPUT_STRING;
-
+
i->state = mpc_state_new();
-
+
i->string = malloc(strlen(string) + 1);
strcpy(i->string, string);
i->buffer = NULL;
i->file = NULL;
-
+
i->suppress = 0;
i->backtrack = 1;
i->marks_num = 0;
@@ -122,29 +122,29 @@ static mpc_input_t *mpc_input_new_string(const char *filename, const char *strin
i->marks = malloc(sizeof(mpc_state_t) * i->marks_slots);
i->lasts = malloc(sizeof(char) * i->marks_slots);
i->last = '\0';
-
+
i->mem_index = 0;
memset(i->mem_full, 0, sizeof(char) * MPC_INPUT_MEM_NUM);
-
+
return i;
}
static mpc_input_t *mpc_input_new_nstring(const char *filename, const char *string, size_t length) {
mpc_input_t *i = malloc(sizeof(mpc_input_t));
-
+
i->filename = malloc(strlen(filename) + 1);
strcpy(i->filename, filename);
i->type = MPC_INPUT_STRING;
-
+
i->state = mpc_state_new();
-
+
i->string = malloc(length + 1);
strncpy(i->string, string, length);
i->string[length] = '\0';
i->buffer = NULL;
i->file = NULL;
-
+
i->suppress = 0;
i->backtrack = 1;
i->marks_num = 0;
@@ -152,10 +152,10 @@ static mpc_input_t *mpc_input_new_nstring(const char *filename, const char *stri
i->marks = malloc(sizeof(mpc_state_t) * i->marks_slots);
i->lasts = malloc(sizeof(char) * i->marks_slots);
i->last = '\0';
-
+
i->mem_index = 0;
memset(i->mem_full, 0, sizeof(char) * MPC_INPUT_MEM_NUM);
-
+
return i;
}
@@ -163,17 +163,17 @@ static mpc_input_t *mpc_input_new_nstring(const char *filename, const char *stri
static mpc_input_t *mpc_input_new_pipe(const char *filename, FILE *pipe) {
mpc_input_t *i = malloc(sizeof(mpc_input_t));
-
+
i->filename = malloc(strlen(filename) + 1);
strcpy(i->filename, filename);
-
+
i->type = MPC_INPUT_PIPE;
i->state = mpc_state_new();
-
+
i->string = NULL;
i->buffer = NULL;
i->file = pipe;
-
+
i->suppress = 0;
i->backtrack = 1;
i->marks_num = 0;
@@ -181,27 +181,27 @@ static mpc_input_t *mpc_input_new_pipe(const char *filename, FILE *pipe) {
i->marks = malloc(sizeof(mpc_state_t) * i->marks_slots);
i->lasts = malloc(sizeof(char) * i->marks_slots);
i->last = '\0';
-
+
i->mem_index = 0;
memset(i->mem_full, 0, sizeof(char) * MPC_INPUT_MEM_NUM);
-
+
return i;
-
+
}
static mpc_input_t *mpc_input_new_file(const char *filename, FILE *file) {
-
+
mpc_input_t *i = malloc(sizeof(mpc_input_t));
-
+
i->filename = malloc(strlen(filename) + 1);
strcpy(i->filename, filename);
i->type = MPC_INPUT_FILE;
i->state = mpc_state_new();
-
+
i->string = NULL;
i->buffer = NULL;
i->file = file;
-
+
i->suppress = 0;
i->backtrack = 1;
i->marks_num = 0;
@@ -209,20 +209,20 @@ static mpc_input_t *mpc_input_new_file(const char *filename, FILE *file) {
i->marks = malloc(sizeof(mpc_state_t) * i->marks_slots);
i->lasts = malloc(sizeof(char) * i->marks_slots);
i->last = '\0';
-
+
i->mem_index = 0;
memset(i->mem_full, 0, sizeof(char) * MPC_INPUT_MEM_NUM);
-
+
return i;
}
static void mpc_input_delete(mpc_input_t *i) {
-
+
free(i->filename);
-
+
if (i->type == MPC_INPUT_STRING) { free(i->string); }
if (i->type == MPC_INPUT_PIPE) { free(i->buffer); }
-
+
free(i->marks);
free(i->lasts);
free(i);
@@ -237,9 +237,9 @@ static int mpc_mem_ptr(mpc_input_t *i, void *p) {
static void *mpc_malloc(mpc_input_t *i, size_t n) {
size_t j;
char *p;
-
+
if (n > sizeof(mpc_mem_t)) { return malloc(n); }
-
+
j = i->mem_index;
do {
if (!i->mem_full[i->mem_index]) {
@@ -250,7 +250,7 @@ static void *mpc_malloc(mpc_input_t *i, size_t n) {
}
i->mem_index = (i->mem_index+1) % MPC_INPUT_MEM_NUM;
} while (j != i->mem_index);
-
+
return malloc(n);
}
@@ -268,18 +268,18 @@ static void mpc_free(mpc_input_t *i, void *p) {
}
static void *mpc_realloc(mpc_input_t *i, void *p, size_t n) {
-
+
char *q = NULL;
-
+
if (!mpc_mem_ptr(i, p)) { return realloc(p, n); }
-
+
if (n > sizeof(mpc_mem_t)) {
q = malloc(n);
memcpy(q, p, sizeof(mpc_mem_t));
mpc_free(i, p);
return q;
}
-
+
return p;
}
@@ -289,7 +289,7 @@ static void *mpc_export(mpc_input_t *i, void *p) {
q = malloc(sizeof(mpc_mem_t));
memcpy(q, p, sizeof(mpc_mem_t));
mpc_free(i, p);
- return q;
+ return q;
}
static void mpc_input_backtrack_disable(mpc_input_t *i) { i->backtrack--; }
@@ -299,11 +299,11 @@ static void mpc_input_suppress_disable(mpc_input_t *i) { i->suppress--; }
static void mpc_input_suppress_enable(mpc_input_t *i) { i->suppress++; }
static void mpc_input_mark(mpc_input_t *i) {
-
+
if (i->backtrack < 1) { return; }
-
+
i->marks_num++;
-
+
if (i->marks_num > i->marks_slots) {
i->marks_slots = i->marks_num + i->marks_num / 2;
i->marks = realloc(i->marks, sizeof(mpc_state_t) * i->marks_slots);
@@ -312,46 +312,46 @@ static void mpc_input_mark(mpc_input_t *i) {
i->marks[i->marks_num-1] = i->state;
i->lasts[i->marks_num-1] = i->last;
-
+
if (i->type == MPC_INPUT_PIPE && i->marks_num == 1) {
i->buffer = calloc(1, 1);
}
-
+
}
static void mpc_input_unmark(mpc_input_t *i) {
-
+
if (i->backtrack < 1) { return; }
-
+
i->marks_num--;
-
+
if (i->marks_slots > i->marks_num + i->marks_num / 2
&& i->marks_slots > MPC_INPUT_MARKS_MIN) {
- i->marks_slots =
+ i->marks_slots =
i->marks_num > MPC_INPUT_MARKS_MIN ?
i->marks_num : MPC_INPUT_MARKS_MIN;
i->marks = realloc(i->marks, sizeof(mpc_state_t) * i->marks_slots);
- i->lasts = realloc(i->lasts, sizeof(char) * i->marks_slots);
+ i->lasts = realloc(i->lasts, sizeof(char) * i->marks_slots);
}
-
+
if (i->type == MPC_INPUT_PIPE && i->marks_num == 0) {
free(i->buffer);
i->buffer = NULL;
}
-
+
}
static void mpc_input_rewind(mpc_input_t *i) {
-
+
if (i->backtrack < 1) { return; }
-
+
i->state = i->marks[i->marks_num-1];
i->last = i->lasts[i->marks_num-1];
-
+
if (i->type == MPC_INPUT_FILE) {
fseek(i->file, i->state.pos, SEEK_SET);
}
-
+
mpc_input_unmark(i);
}
@@ -364,17 +364,17 @@ static char mpc_input_buffer_get(mpc_input_t *i) {
}
static char mpc_input_getc(mpc_input_t *i) {
-
+
char c = '\0';
-
+
switch (i->type) {
-
+
case MPC_INPUT_STRING: return i->string[i->state.pos];
case MPC_INPUT_FILE: c = fgetc(i->file); return c;
case MPC_INPUT_PIPE:
-
+
if (!i->buffer) { c = getc(i->file); return c; }
-
+
if (i->buffer && mpc_input_buffer_in_range(i)) {
c = mpc_input_buffer_get(i);
return c;
@@ -382,34 +382,34 @@ static char mpc_input_getc(mpc_input_t *i) {
c = getc(i->file);
return c;
}
-
+
default: return c;
}
}
static char mpc_input_peekc(mpc_input_t *i) {
-
+
char c = '\0';
-
+
switch (i->type) {
case MPC_INPUT_STRING: return i->string[i->state.pos];
- case MPC_INPUT_FILE:
-
+ case MPC_INPUT_FILE:
+
c = fgetc(i->file);
if (feof(i->file)) { return '\0'; }
-
+
fseek(i->file, -1, SEEK_CUR);
return c;
-
+
case MPC_INPUT_PIPE:
-
+
if (!i->buffer) {
c = getc(i->file);
if (feof(i->file)) { return '\0'; }
ungetc(c, i->file);
return c;
}
-
+
if (i->buffer && mpc_input_buffer_in_range(i)) {
return mpc_input_buffer_get(i);
} else {
@@ -418,10 +418,10 @@ static char mpc_input_peekc(mpc_input_t *i) {
ungetc(c, i->file);
return c;
}
-
+
default: return c;
}
-
+
}
static int mpc_input_terminated(mpc_input_t *i) {
@@ -434,13 +434,13 @@ static int mpc_input_failure(mpc_input_t *i, char c) {
case MPC_INPUT_STRING: { break; }
case MPC_INPUT_FILE: fseek(i->file, -1, SEEK_CUR); { break; }
case MPC_INPUT_PIPE: {
-
+
if (!i->buffer) { ungetc(c, i->file); break; }
-
+
if (i->buffer && mpc_input_buffer_in_range(i)) {
break;
} else {
- ungetc(c, i->file);
+ ungetc(c, i->file);
}
}
default: { break; }
@@ -449,29 +449,29 @@ static int mpc_input_failure(mpc_input_t *i, char c) {
}
static int mpc_input_success(mpc_input_t *i, char c, char **o) {
-
+
if (i->type == MPC_INPUT_PIPE
&& i->buffer && !mpc_input_buffer_in_range(i)) {
i->buffer = realloc(i->buffer, strlen(i->buffer) + 2);
i->buffer[strlen(i->buffer) + 1] = '\0';
i->buffer[strlen(i->buffer) + 0] = c;
}
-
+
i->last = c;
i->state.pos++;
i->state.col++;
-
+
if (c == '\n') {
i->state.col = 0;
i->state.row++;
}
-
+
if (o) {
(*o) = mpc_malloc(i, 2);
(*o)[0] = c;
(*o)[1] = '\0';
}
-
+
return 1;
}
@@ -518,7 +518,7 @@ static int mpc_input_satisfy(mpc_input_t *i, int(*cond)(char), char **o) {
}
static int mpc_input_string(mpc_input_t *i, const char *c, char **o) {
-
+
const char *x = c;
mpc_input_mark(i);
@@ -530,7 +530,7 @@ static int mpc_input_string(mpc_input_t *i, const char *c, char **o) {
x++;
}
mpc_input_unmark(i);
-
+
*o = mpc_malloc(i, strlen(c) + 1);
strcpy(*o, c);
return 1;
@@ -600,12 +600,12 @@ static void mpc_err_string_cat(char *buffer, int *pos, int *max, char const *fmt
static char char_unescape_buffer[4];
static const char *mpc_err_char_unescape(char c) {
-
+
char_unescape_buffer[0] = '\'';
char_unescape_buffer[1] = ' ';
char_unescape_buffer[2] = '\'';
char_unescape_buffer[3] = '\0';
-
+
switch (c) {
case '\a': return "bell";
case '\b': return "backspace";
@@ -620,42 +620,42 @@ static const char *mpc_err_char_unescape(char c) {
char_unescape_buffer[1] = c;
return char_unescape_buffer;
}
-
+
}
char *mpc_err_string(mpc_err_t *x) {
- int i;
- int pos = 0;
+ int i;
+ int pos = 0;
int max = 1023;
char *buffer = calloc(1, 1024);
-
+
if (x->failure) {
mpc_err_string_cat(buffer, &pos, &max,
"%s: error: %s\n", x->filename, x->failure);
return buffer;
}
-
- mpc_err_string_cat(buffer, &pos, &max,
+
+ mpc_err_string_cat(buffer, &pos, &max,
"%s:%i:%i: error: expected ", x->filename, x->state.row+1, x->state.col+1);
-
+
if (x->expected_num == 0) { mpc_err_string_cat(buffer, &pos, &max, "ERROR: NOTHING EXPECTED"); }
if (x->expected_num == 1) { mpc_err_string_cat(buffer, &pos, &max, "%s", x->expected[0]); }
if (x->expected_num >= 2) {
-
+
for (i = 0; i < x->expected_num-2; i++) {
mpc_err_string_cat(buffer, &pos, &max, "%s, ", x->expected[i]);
- }
-
- mpc_err_string_cat(buffer, &pos, &max, "%s or %s",
- x->expected[x->expected_num-2],
+ }
+
+ mpc_err_string_cat(buffer, &pos, &max, "%s or %s",
+ x->expected[x->expected_num-2],
x->expected[x->expected_num-1]);
}
-
+
mpc_err_string_cat(buffer, &pos, &max, " at ");
mpc_err_string_cat(buffer, &pos, &max, mpc_err_char_unescape(x->recieved));
mpc_err_string_cat(buffer, &pos, &max, "\n");
-
+
return realloc(buffer, strlen(buffer) + 1);
}
@@ -743,17 +743,17 @@ static void mpc_err_add_expected(mpc_input_t *i, mpc_err_t *x, char *expected) {
}
static mpc_err_t *mpc_err_or(mpc_input_t *i, mpc_err_t** x, int n) {
-
+
int j, k, fst;
mpc_err_t *e;
-
+
fst = -1;
for (j = 0; j < n; j++) {
if (x[j] != NULL) { fst = j; }
}
-
+
if (fst == -1) { return NULL; }
-
+
e = mpc_malloc(i, sizeof(mpc_err_t));
e->state = mpc_state_invalid();
e->expected_num = 0;
@@ -761,36 +761,36 @@ static mpc_err_t *mpc_err_or(mpc_input_t *i, mpc_err_t** x, int n) {
e->failure = NULL;
e->filename = mpc_malloc(i, strlen(x[fst]->filename)+1);
strcpy(e->filename, x[fst]->filename);
-
+
for (j = 0; j < n; j++) {
if (x[j] == NULL) { continue; }
if (x[j]->state.pos > e->state.pos) { e->state = x[j]->state; }
}
-
+
for (j = 0; j < n; j++) {
if (x[j] == NULL) { continue; }
if (x[j]->state.pos < e->state.pos) { continue; }
-
+
if (x[j]->failure) {
e->failure = mpc_malloc(i, strlen(x[j]->failure)+1);
strcpy(e->failure, x[j]->failure);
break;
}
-
+
e->recieved = x[j]->recieved;
-
+
for (k = 0; k < x[j]->expected_num; k++) {
if (!mpc_err_contains_expected(i, e, x[j]->expected[k])) {
mpc_err_add_expected(i, e, x[j]->expected[k]);
}
}
}
-
+
for (j = 0; j < n; j++) {
if (x[j] == NULL) { continue; }
mpc_err_delete_internal(i, x[j]);
}
-
+
return e;
}
@@ -799,9 +799,9 @@ static mpc_err_t *mpc_err_repeat(mpc_input_t *i, mpc_err_t *x, const char *prefi
int j = 0;
size_t l = 0;
char *expect = NULL;
-
+
if (x == NULL) { return NULL; }
-
+
if (x->expected_num == 0) {
expect = mpc_calloc(i, 1, 1);
x->expected_num = 1;
@@ -809,7 +809,7 @@ static mpc_err_t *mpc_err_repeat(mpc_input_t *i, mpc_err_t *x, const char *prefi
x->expected[0] = expect;
return x;
}
-
+
else if (x->expected_num == 1) {
expect = mpc_malloc(i, strlen(prefix) + strlen(x->expected[0]) + 1);
strcpy(expect, prefix);
@@ -818,9 +818,9 @@ static mpc_err_t *mpc_err_repeat(mpc_input_t *i, mpc_err_t *x, const char *prefi
x->expected[0] = expect;
return x;
}
-
+
else if (x->expected_num > 1) {
-
+
l += strlen(prefix);
for (j = 0; j < x->expected_num-2; j++) {
l += strlen(x->expected[j]) + strlen(", ");
@@ -828,9 +828,9 @@ static mpc_err_t *mpc_err_repeat(mpc_input_t *i, mpc_err_t *x, const char *prefi
l += strlen(x->expected[x->expected_num-2]);
l += strlen(" or ");
l += strlen(x->expected[x->expected_num-1]);
-
+
expect = mpc_malloc(i, l + 1);
-
+
strcpy(expect, prefix);
for (j = 0; j < x->expected_num-2; j++) {
strcat(expect, x->expected[j]); strcat(expect, ", ");
@@ -840,13 +840,13 @@ static mpc_err_t *mpc_err_repeat(mpc_input_t *i, mpc_err_t *x, const char *prefi
strcat(expect, x->expected[x->expected_num-1]);
for (j = 0; j < x->expected_num; j++) { mpc_free(i, x->expected[j]); }
-
+
x->expected_num = 1;
x->expected = mpc_realloc(i, x->expected, sizeof(char*) * x->expected_num);
x->expected[0] = expect;
return x;
}
-
+
return NULL;
}
@@ -908,7 +908,7 @@ enum {
MPC_TYPE_CHECK = 25,
MPC_TYPE_CHECK_WITH = 26,
-
+
MPC_TYPE_SOI = 27,
MPC_TYPE_EOI = 28
};
@@ -963,7 +963,7 @@ static mpc_val_t *mpcf_input_nth_free(mpc_input_t *i, int n, mpc_val_t **xs, int
for (j = 0; j < n; j++) { if (j != x) { mpc_free(i, xs[j]); } }
return xs[x];
}
-
+
static mpc_val_t *mpcf_input_fst_free(mpc_input_t *i, int n, mpc_val_t **xs) { return mpcf_input_nth_free(i, n, xs, 0); }
static mpc_val_t *mpcf_input_snd_free(mpc_input_t *i, int n, mpc_val_t **xs) { return mpcf_input_nth_free(i, n, xs, 1); }
static mpc_val_t *mpcf_input_trd_free(mpc_input_t *i, int n, mpc_val_t **xs) { return mpcf_input_nth_free(i, n, xs, 2); }
@@ -1039,14 +1039,14 @@ enum {
else { MPC_FAILURE(NULL); }
static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_err_t **e) {
-
+
int j = 0, k = 0;
mpc_result_t results_stk[MPC_PARSE_STACK_MIN];
mpc_result_t *results;
int results_slots = MPC_PARSE_STACK_MIN;
-
+
switch (p->type) {
-
+
/* Basic Parsers */
case MPC_TYPE_ANY: MPC_PRIMITIVE(mpc_input_any(i, (char**)&r->output));
@@ -1059,25 +1059,25 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
case MPC_TYPE_ANCHOR: MPC_PRIMITIVE(mpc_input_anchor(i, p->data.anchor.f, (char**)&r->output));
case MPC_TYPE_SOI: MPC_PRIMITIVE(mpc_input_soi(i, (char**)&r->output));
case MPC_TYPE_EOI: MPC_PRIMITIVE(mpc_input_eoi(i, (char**)&r->output));
-
+
/* Other parsers */
-
+
case MPC_TYPE_UNDEFINED: MPC_FAILURE(mpc_err_fail(i, "Parser Undefined!"));
case MPC_TYPE_PASS: MPC_SUCCESS(NULL);
case MPC_TYPE_FAIL: MPC_FAILURE(mpc_err_fail(i, p->data.fail.m));
case MPC_TYPE_LIFT: MPC_SUCCESS(p->data.lift.lf());
case MPC_TYPE_LIFT_VAL: MPC_SUCCESS(p->data.lift.x);
case MPC_TYPE_STATE: MPC_SUCCESS(mpc_input_state_copy(i));
-
+
/* Application Parsers */
-
+
case MPC_TYPE_APPLY:
if (mpc_parse_run(i, p->data.apply.x, r, e)) {
MPC_SUCCESS(mpc_parse_apply(i, p->data.apply.f, r->output));
} else {
MPC_FAILURE(r->output);
}
-
+
case MPC_TYPE_APPLY_TO:
if (mpc_parse_run(i, p->data.apply_to.x, r, e)) {
MPC_SUCCESS(mpc_parse_apply_to(i, p->data.apply_to.f, r->output, p->data.apply_to.d));
@@ -1116,21 +1116,21 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
mpc_input_suppress_disable(i);
MPC_FAILURE(mpc_err_new(i, p->data.expect.m));
}
-
+
case MPC_TYPE_PREDICT:
mpc_input_backtrack_disable(i);
- if (mpc_parse_run(i, p->data.predict.x, r, e)) {
+ if (mpc_parse_run(i, p->data.predict.x, r, e)) {
mpc_input_backtrack_enable(i);
MPC_SUCCESS(r->output);
} else {
mpc_input_backtrack_enable(i);
MPC_FAILURE(r->error);
}
-
+
/* Optional Parsers */
-
+
/* TODO: Update Not Error Message */
-
+
case MPC_TYPE_NOT:
mpc_input_mark(i);
mpc_input_suppress_enable(i);
@@ -1144,7 +1144,7 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
mpc_input_suppress_disable(i);
MPC_SUCCESS(p->data.not.lf());
}
-
+
case MPC_TYPE_MAYBE:
if (mpc_parse_run(i, p->data.not.x, r, e)) {
MPC_SUCCESS(r->output);
@@ -1152,13 +1152,13 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
*e = mpc_err_merge(i, *e, r->error);
MPC_SUCCESS(p->data.not.lf());
}
-
+
/* Repeat Parsers */
-
+
case MPC_TYPE_MANY:
-
+
results = results_stk;
-
+
while (mpc_parse_run(i, p->data.repeat.x, &results[j], e)) {
j++;
if (j == MPC_PARSE_STACK_MIN) {
@@ -1170,17 +1170,17 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
results = mpc_realloc(i, results, sizeof(mpc_result_t) * results_slots);
}
}
-
+
*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_MANY1:
-
+
results = results_stk;
-
+
while (mpc_parse_run(i, p->data.repeat.x, &results[j], e)) {
j++;
if (j == MPC_PARSE_STACK_MIN) {
@@ -1192,31 +1192,31 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
results = mpc_realloc(i, results, sizeof(mpc_result_t) * results_slots);
}
}
-
+
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:
-
+
results = p->data.repeat.n > MPC_PARSE_STACK_MIN
? mpc_malloc(i, sizeof(mpc_result_t) * p->data.repeat.n)
: results_stk;
-
+
while (mpc_parse_run(i, p->data.repeat.x, &results[j], e)) {
j++;
if (j == p->data.repeat.n) { break; }
}
-
+
if (j == p->data.repeat.n) {
MPC_SUCCESS(
mpc_parse_fold(i, p->data.repeat.f, j, (mpc_val_t**)results);
@@ -1227,39 +1227,39 @@ static int mpc_parse_run(mpc_input_t *i, mpc_parser_t *p, mpc_result_t *r, mpc_e
}
MPC_FAILURE(
mpc_err_count(i, results[j].error, p->data.repeat.n);
- if (p->data.repeat.n > MPC_PARSE_STACK_MIN) { mpc_free(i, results); });
+ if (p->data.repeat.n > MPC_PARSE_STACK_MIN) { mpc_free(i, results); });
}
-
+
/* Combinatory Parsers */
-
+
case MPC_TYPE_OR:
-
+
if (p->data.or.n == 0) { MPC_SUCCESS(NULL); }
-
+
results = p->data.or.n > MPC_PARSE_STACK_MIN
? mpc_malloc(i, sizeof(mpc_result_t) * p->data.or.n)
: results_stk;
-
+
for (j = 0; j < p->data.or.n; j++) {
if (mpc_parse_run(i, p->data.or.xs[j], &results[j], e)) {
MPC_SUCCESS(results[j].output;
if (p->data.or.n > MPC_PARSE_STACK_MIN) { mpc_free(i, results); });
} else {
*e = mpc_err_merge(i, *e, results[j].error);
- }
+ }
}
-
+
MPC_FAILURE(NULL;
if (p->data.or.n > MPC_PARSE_STACK_MIN) { mpc_free(i, results); });
-
+
case MPC_TYPE_AND:
-
+
if (p->data.and.n == 0) { MPC_SUCCESS(NULL); }
-
+
results = p->data.or.n > MPC_PARSE_STACK_MIN
? mpc_malloc(i, sizeof(mpc_result_t) * p->data.or.n)
: results_stk;
-
+
mpc_input_mark(i);
for (j = 0; j < p->data.and.n; j++) {
if (!mpc_parse_run(i, p->data.and.xs[j], &results[j], e)) {
@@ -1271,20 +1271,20 @@ 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); });
}
}
- mpc_input_unmark(i);
+ mpc_input_unmark(i);
MPC_SUCCESS(
mpc_parse_fold(i, p->data.and.f, j, (mpc_val_t**)results);
if (p->data.or.n > MPC_PARSE_STACK_MIN) { mpc_free(i, results); });
-
+
/* End */
-
+
default:
-
+
MPC_FAILURE(mpc_err_fail(i, "Unknown Parser Type Id!"));
}
-
+
return 0;
-
+
}
#undef MPC_SUCCESS
@@ -1338,16 +1338,16 @@ int mpc_parse_pipe(const char *filename, FILE *pipe, mpc_parser_t *p, mpc_result
}
int mpc_parse_contents(const char *filename, mpc_parser_t *p, mpc_result_t *r) {
-
+
FILE *f = fopen(filename, "rb");
int res;
-
+
if (f == NULL) {
r->output = NULL;
r->error = mpc_err_file(filename, "Unable to open file!");
return 0;
}
-
+
res = mpc_parse_file(filename, f, p, r);
fclose(f);
return res;
@@ -1360,63 +1360,63 @@ int mpc_parse_contents(const char *filename, mpc_parser_t *p, mpc_result_t *r) {
static void mpc_undefine_unretained(mpc_parser_t *p, int force);
static void mpc_undefine_or(mpc_parser_t *p) {
-
+
int i;
for (i = 0; i < p->data.or.n; i++) {
mpc_undefine_unretained(p->data.or.xs[i], 0);
}
free(p->data.or.xs);
-
+
}
static void mpc_undefine_and(mpc_parser_t *p) {
-
+
int i;
for (i = 0; i < p->data.and.n; i++) {
mpc_undefine_unretained(p->data.and.xs[i], 0);
}
free(p->data.and.xs);
free(p->data.and.dxs);
-
+
}
static void mpc_undefine_unretained(mpc_parser_t *p, int force) {
-
+
if (p->retained && !force) { return; }
-
+
switch (p->type) {
-
+
case MPC_TYPE_FAIL: free(p->data.fail.m); break;
-
- case MPC_TYPE_ONEOF:
+
+ case MPC_TYPE_ONEOF:
case MPC_TYPE_NONEOF:
case MPC_TYPE_STRING:
- free(p->data.string.x);
+ free(p->data.string.x);
break;
-
+
case MPC_TYPE_APPLY: mpc_undefine_unretained(p->data.apply.x, 0); break;
case MPC_TYPE_APPLY_TO: mpc_undefine_unretained(p->data.apply_to.x, 0); break;
case MPC_TYPE_PREDICT: mpc_undefine_unretained(p->data.predict.x, 0); break;
-
+
case MPC_TYPE_MAYBE:
case MPC_TYPE_NOT:
mpc_undefine_unretained(p->data.not.x, 0);
break;
-
+
case MPC_TYPE_EXPECT:
mpc_undefine_unretained(p->data.expect.x, 0);
free(p->data.expect.m);
break;
-
+
case MPC_TYPE_MANY:
case MPC_TYPE_MANY1:
case MPC_TYPE_COUNT:
mpc_undefine_unretained(p->data.repeat.x, 0);
break;
-
+
case MPC_TYPE_OR: mpc_undefine_or(p); break;
case MPC_TYPE_AND: mpc_undefine_and(p); break;
-
+
case MPC_TYPE_CHECK:
mpc_undefine_unretained(p->data.check.x, 0);
free(p->data.check.e);
@@ -1429,12 +1429,12 @@ static void mpc_undefine_unretained(mpc_parser_t *p, int force) {
default: break;
}
-
+
if (!force) {
free(p->name);
free(p);
}
-
+
}
void mpc_delete(mpc_parser_t *p) {
@@ -1442,13 +1442,13 @@ void mpc_delete(mpc_parser_t *p) {
if (p->type != MPC_TYPE_UNDEFINED) {
mpc_undefine_unretained(p, 0);
- }
-
+ }
+
free(p->name);
free(p);
-
+
} else {
- mpc_undefine_unretained(p, 0);
+ mpc_undefine_unretained(p, 0);
}
}
@@ -1475,54 +1475,54 @@ mpc_parser_t *mpc_new(const char *name) {
mpc_parser_t *mpc_copy(mpc_parser_t *a) {
int i = 0;
mpc_parser_t *p;
-
+
if (a->retained) { return a; }
-
+
p = mpc_undefined();
p->retained = a->retained;
p->type = a->type;
p->data = a->data;
-
+
if (a->name) {
p->name = malloc(strlen(a->name)+1);
strcpy(p->name, a->name);
}
-
+
switch (a->type) {
-
+
case MPC_TYPE_FAIL:
p->data.fail.m = malloc(strlen(a->data.fail.m)+1);
strcpy(p->data.fail.m, a->data.fail.m);
break;
-
- case MPC_TYPE_ONEOF:
+
+ case MPC_TYPE_ONEOF:
case MPC_TYPE_NONEOF:
case MPC_TYPE_STRING:
p->data.string.x = malloc(strlen(a->data.string.x)+1);
strcpy(p->data.string.x, a->data.string.x);
break;
-
+
case MPC_TYPE_APPLY: p->data.apply.x = mpc_copy(a->data.apply.x); break;
case MPC_TYPE_APPLY_TO: p->data.apply_to.x = mpc_copy(a->data.apply_to.x); break;
case MPC_TYPE_PREDICT: p->data.predict.x = mpc_copy(a->data.predict.x); break;
-
+
case MPC_TYPE_MAYBE:
case MPC_TYPE_NOT:
p->data.not.x = mpc_copy(a->data.not.x);
break;
-
+
case MPC_TYPE_EXPECT:
p->data.expect.x = mpc_copy(a->data.expect.x);
p->data.expect.m = malloc(strlen(a->data.expect.m)+1);
strcpy(p->data.expect.m, a->data.expect.m);
break;
-
+
case MPC_TYPE_MANY:
case MPC_TYPE_MANY1:
case MPC_TYPE_COUNT:
p->data.repeat.x = mpc_copy(a->data.repeat.x);
break;
-
+
case MPC_TYPE_OR:
p->data.or.xs = malloc(a->data.or.n * sizeof(mpc_parser_t*));
for (i = 0; i < a->data.or.n; i++) {
@@ -1539,7 +1539,7 @@ mpc_parser_t *mpc_copy(mpc_parser_t *a) {
p->data.and.dxs[i] = a->data.and.dxs[i];
}
break;
-
+
case MPC_TYPE_CHECK:
p->data.check.x = mpc_copy(a->data.check.x);
p->data.check.e = malloc(strlen(a->data.check.e)+1);
@@ -1554,7 +1554,7 @@ mpc_parser_t *mpc_copy(mpc_parser_t *a) {
default: break;
}
-
+
return p;
}
@@ -1565,7 +1565,7 @@ mpc_parser_t *mpc_undefine(mpc_parser_t *p) {
}
mpc_parser_t *mpc_define(mpc_parser_t *p, mpc_parser_t *a) {
-
+
if (p->retained) {
p->type = a->type;
p->data = a->data;
@@ -1575,21 +1575,21 @@ mpc_parser_t *mpc_define(mpc_parser_t *p, mpc_parser_t *a) {
p->data = a2->data;
free(a2);
}
-
+
free(a);
- return p;
+ return p;
}
void mpc_cleanup(int n, ...) {
int i;
mpc_parser_t **list = malloc(sizeof(mpc_parser_t*) * n);
-
+
va_list va;
va_start(va, n);
for (i = 0; i < n; i++) { list[i] = va_arg(va, mpc_parser_t*); }
for (i = 0; i < n; i++) { mpc_undefine(list[i]); }
- for (i = 0; i < n; i++) { mpc_delete(list[i]); }
- va_end(va);
+ for (i = 0; i < n; i++) { mpc_delete(list[i]); }
+ va_end(va);
free(list);
}
@@ -1609,7 +1609,7 @@ mpc_parser_t *mpc_fail(const char *m) {
}
/*
-** As `snprintf` is not ANSI standard this
+** As `snprintf` is not ANSI standard this
** function `mpc_failf` should be considered
** unsafe.
**
@@ -1620,7 +1620,7 @@ mpc_parser_t *mpc_fail(const char *m) {
** the buffer length using precision specifiers
** such as `%.512s`.
**
-** - Patch this function in your code base to
+** - Patch this function in your code base to
** use `snprintf` or whatever variant your
** system supports.
**
@@ -1629,18 +1629,18 @@ mpc_parser_t *mpc_fail(const char *m) {
*/
mpc_parser_t *mpc_failf(const char *fmt, ...) {
-
+
va_list va;
char *buffer;
mpc_parser_t *p = mpc_undefined();
p->type = MPC_TYPE_FAIL;
-
+
va_start(va, fmt);
buffer = malloc(2048);
vsprintf(buffer, fmt, va);
va_end(va);
-
+
buffer = realloc(buffer, strlen(buffer) + 1);
p->data.fail.m = buffer;
return p;
@@ -1684,7 +1684,7 @@ mpc_parser_t *mpc_expect(mpc_parser_t *a, const char *expected) {
}
/*
-** As `snprintf` is not ANSI standard this
+** As `snprintf` is not ANSI standard this
** function `mpc_expectf` should be considered
** unsafe.
**
@@ -1695,7 +1695,7 @@ mpc_parser_t *mpc_expect(mpc_parser_t *a, const char *expected) {
** the buffer length using precision specifiers
** such as `%.512s`.
**
-** - Patch this function in your code base to
+** - Patch this function in your code base to
** use `snprintf` or whatever variant your
** system supports.
**
@@ -1709,12 +1709,12 @@ mpc_parser_t *mpc_expectf(mpc_parser_t *a, const char *fmt, ...) {
mpc_parser_t *p = mpc_undefined();
p->type = MPC_TYPE_EXPECT;
-
+
va_start(va, fmt);
buffer = malloc(2048);
vsprintf(buffer, fmt, va);
va_end(va);
-
+
buffer = realloc(buffer, strlen(buffer) + 1);
p->data.expect.x = a;
p->data.expect.m = buffer;
@@ -1916,17 +1916,17 @@ mpc_parser_t *mpc_or(int n, ...) {
va_list va;
mpc_parser_t *p = mpc_undefined();
-
+
p->type = MPC_TYPE_OR;
p->data.or.n = n;
p->data.or.xs = malloc(sizeof(mpc_parser_t*) * n);
-
- va_start(va, n);
+
+ va_start(va, n);
for (i = 0; i < n; i++) {
p->data.or.xs[i] = va_arg(va, mpc_parser_t*);
}
va_end(va);
-
+
return p;
}
@@ -1936,22 +1936,22 @@ mpc_parser_t *mpc_and(int n, mpc_fold_t f, ...) {
va_list va;
mpc_parser_t *p = mpc_undefined();
-
+
p->type = MPC_TYPE_AND;
p->data.and.n = n;
p->data.and.f = f;
p->data.and.xs = malloc(sizeof(mpc_parser_t*) * n);
p->data.and.dxs = malloc(sizeof(mpc_dtor_t) * (n-1));
- va_start(va, f);
+ va_start(va, f);
for (i = 0; i < n; i++) {
p->data.and.xs[i] = va_arg(va, mpc_parser_t*);
}
for (i = 0; i < (n-1); i++) {
p->data.and.dxs[i] = va_arg(va, mpc_dtor_t);
- }
+ }
va_end(va);
-
+
return p;
}
@@ -1984,7 +1984,7 @@ static int mpc_boundary_anchor(char prev, char next) {
static int mpc_boundary_newline_anchor(char prev, char next) {
(void)next;
- return prev == '\n';
+ return prev == '\n';
}
mpc_parser_t *mpc_boundary(void) { return mpc_expect(mpc_anchor(mpc_boundary_anchor), "word boundary"); }
@@ -2019,9 +2019,9 @@ mpc_parser_t *mpc_number(void) { return mpc_expect(mpc_or(3, mpc_int(), mpc_hex(
mpc_parser_t *mpc_real(void) {
/* [+-]?\d+(\.\d+)?([eE][+-]?[0-9]+)? */
-
+
mpc_parser_t *p0, *p1, *p2, *p30, *p31, *p32, *p3;
-
+
p0 = mpc_maybe_lift(mpc_oneof("+-"), mpcf_ctor_str);
p1 = mpc_digits();
p2 = mpc_maybe_lift(mpc_and(2, mpcf_strfold, mpc_char('.'), mpc_digits(), free), mpcf_ctor_str);
@@ -2029,7 +2029,7 @@ mpc_parser_t *mpc_real(void) {
p31 = mpc_maybe_lift(mpc_oneof("+-"), mpcf_ctor_str);
p32 = mpc_digits();
p3 = mpc_maybe_lift(mpc_and(3, mpcf_strfold, p30, p31, p32, free, free), mpcf_ctor_str);
-
+
return mpc_expect(mpc_and(4, mpcf_strfold, p0, p1, p2, p3, free, free, free), "real");
}
@@ -2047,15 +2047,15 @@ mpc_parser_t *mpc_string_lit(void) {
return mpc_expect(mpc_between(mpc_many(mpcf_strfold, strchar), free, "\"", "\""), "string");
}
-mpc_parser_t *mpc_regex_lit(void) {
+mpc_parser_t *mpc_regex_lit(void) {
mpc_parser_t *regexchar = mpc_or(2, mpc_escape(), mpc_noneof("/"));
return mpc_expect(mpc_between(mpc_many(mpcf_strfold, regexchar), free, "/", "/"), "regex");
}
mpc_parser_t *mpc_ident(void) {
- mpc_parser_t *p0, *p1;
+ mpc_parser_t *p0, *p1;
p0 = mpc_or(2, mpc_alpha(), mpc_underscore());
- p1 = mpc_many(mpcf_strfold, mpc_alphanum());
+ p1 = mpc_many(mpcf_strfold, mpc_alphanum());
return mpc_and(2, mpcf_strfold, p0, p1, free);
}
@@ -2116,7 +2116,7 @@ mpc_parser_t *mpc_tok_squares(mpc_parser_t *a, mpc_dtor_t ad) { return mpc_tok_
** a parser directly - as we are parsing.
**
** This is certainly something that
-** would be less elegant/interesting
+** would be less elegant/interesting
** in a two-phase parser which first
** builds an AST and then traverses it
** to generate the object.
@@ -2132,7 +2132,7 @@ mpc_parser_t *mpc_tok_squares(mpc_parser_t *a, mpc_dtor_t ad) { return mpc_tok_
** ### Regular Expression Grammar
**
** : | ( "|" )
-**
+**
** : *
**
** :
@@ -2140,7 +2140,7 @@ mpc_parser_t *mpc_tok_squares(mpc_parser_t *a, mpc_dtor_t ad) { return mpc_tok_
** | "+"
** | "?"
** | "{" "}"
-**
+**
** :
** | "\"
** | "(" ")"
@@ -2175,7 +2175,7 @@ static mpc_val_t *mpcf_re_repeat(int n, mpc_val_t **xs) {
num = *(int*)xs[1];
free(xs[1]);
}
-
+
return mpc_count(num, mpcf_strfold, xs[0], free);
}
@@ -2202,21 +2202,21 @@ static mpc_parser_t *mpc_re_escape_char(char c) {
}
static mpc_val_t *mpcf_re_escape(mpc_val_t *x, void* data) {
-
+
int mode = *((int*)data);
char *s = x;
mpc_parser_t *p;
-
+
/* Any Character */
if (s[0] == '.') {
free(s);
if (mode & MPC_RE_DOTALL) {
- return mpc_any();
+ return mpc_any();
} else {
return mpc_expect(mpc_noneof("\n"), "any character except a newline");
}
}
-
+
/* Start of Input */
if (s[0] == '^') {
free(s);
@@ -2226,21 +2226,21 @@ static mpc_val_t *mpcf_re_escape(mpc_val_t *x, void* data) {
return mpc_and(2, mpcf_snd, mpc_soi(), mpc_lift(mpcf_ctor_str), free);
}
}
-
+
/* End of Input */
if (s[0] == '$') {
- free(s);
+ free(s);
if (mode & MPC_RE_MULTILINE) {
- return mpc_or(2,
- mpc_newline(),
- mpc_and(2, mpcf_snd, mpc_eoi(), mpc_lift(mpcf_ctor_str), free));
+ return mpc_or(2,
+ mpc_newline(),
+ mpc_and(2, mpcf_snd, mpc_eoi(), mpc_lift(mpcf_ctor_str), free));
} else {
- return mpc_or(2,
- mpc_and(2, mpcf_fst, mpc_newline(), mpc_eoi(), free),
- mpc_and(2, mpcf_snd, mpc_eoi(), mpc_lift(mpcf_ctor_str), free));
+ return mpc_or(2,
+ mpc_and(2, mpcf_fst, mpc_newline(), mpc_eoi(), free),
+ mpc_and(2, mpcf_snd, mpc_eoi(), mpc_lift(mpcf_ctor_str), free));
}
}
-
+
/* Regex Escape */
if (s[0] == '\\') {
p = mpc_re_escape_char(s[1]);
@@ -2248,7 +2248,7 @@ static mpc_val_t *mpcf_re_escape(mpc_val_t *x, void* data) {
free(s);
return p;
}
-
+
/* Regex Standard */
p = mpc_char(s[0]);
free(s);
@@ -2273,7 +2273,7 @@ static const char *mpc_re_range_escape_char(char c) {
}
static mpc_val_t *mpcf_re_range(mpc_val_t *x) {
-
+
mpc_parser_t *out;
size_t i, j;
size_t start, end;
@@ -2281,13 +2281,13 @@ static mpc_val_t *mpcf_re_range(mpc_val_t *x) {
const char *s = x;
int comp = s[0] == '^' ? 1 : 0;
char *range = calloc(1,1);
-
- if (s[0] == '\0') { free(range); free(x); return mpc_fail("Invalid Regex Range Expression"); }
- if (s[0] == '^' &&
+
+ if (s[0] == '\0') { free(range); free(x); return mpc_fail("Invalid Regex Range Expression"); }
+ if (s[0] == '^' &&
s[1] == '\0') { free(range); free(x); return mpc_fail("Invalid Regex Range Expression"); }
-
+
for (i = comp; i < strlen(s); i++){
-
+
/* Regex Range Escape */
if (s[i] == '\\') {
tmp = mpc_re_range_escape_char(s[i+1]);
@@ -2297,11 +2297,11 @@ static mpc_val_t *mpcf_re_range(mpc_val_t *x) {
} else {
range = realloc(range, strlen(range) + 1 + 1);
range[strlen(range) + 1] = '\0';
- range[strlen(range) + 0] = s[i+1];
+ range[strlen(range) + 0] = s[i+1];
}
i++;
}
-
+
/* Regex Range...Range */
else if (s[i] == '-') {
if (s[i+1] == '\0' || i == 0) {
@@ -2314,24 +2314,24 @@ static mpc_val_t *mpcf_re_range(mpc_val_t *x) {
range = realloc(range, strlen(range) + 1 + 1 + 1);
range[strlen(range) + 1] = '\0';
range[strlen(range) + 0] = (char)j;
- }
+ }
}
}
-
+
/* Regex Range Normal */
else {
range = realloc(range, strlen(range) + 1 + 1);
range[strlen(range) + 1] = '\0';
range[strlen(range) + 0] = s[i];
}
-
+
}
-
+
out = comp == 1 ? mpc_noneof(range) : mpc_oneof(range);
-
+
free(x);
free(range);
-
+
return out;
}
@@ -2340,26 +2340,26 @@ mpc_parser_t *mpc_re(const char *re) {
}
mpc_parser_t *mpc_re_mode(const char *re, int mode) {
-
+
char *err_msg;
mpc_parser_t *err_out;
mpc_result_t r;
- mpc_parser_t *Regex, *Term, *Factor, *Base, *Range, *RegexEnclose;
-
+ mpc_parser_t *Regex, *Term, *Factor, *Base, *Range, *RegexEnclose;
+
Regex = mpc_new("regex");
Term = mpc_new("term");
Factor = mpc_new("factor");
Base = mpc_new("base");
Range = mpc_new("range");
-
+
mpc_define(Regex, mpc_and(2, mpcf_re_or,
- Term,
+ Term,
mpc_maybe(mpc_and(2, mpcf_snd_free, mpc_char('|'), Regex, free)),
(mpc_dtor_t)mpc_delete
));
-
+
mpc_define(Term, mpc_many(mpcf_re_and, Factor));
-
+
mpc_define(Factor, mpc_and(2, mpcf_re_repeat,
Base,
mpc_or(5,
@@ -2368,42 +2368,42 @@ mpc_parser_t *mpc_re_mode(const char *re, int mode) {
mpc_pass()),
(mpc_dtor_t)mpc_delete
));
-
+
mpc_define(Base, mpc_or(4,
mpc_parens(Regex, (mpc_dtor_t)mpc_delete),
mpc_squares(Range, (mpc_dtor_t)mpc_delete),
mpc_apply_to(mpc_escape(), mpcf_re_escape, &mode),
mpc_apply_to(mpc_noneof(")|"), mpcf_re_escape, &mode)
));
-
+
mpc_define(Range, mpc_apply(
mpc_many(mpcf_strfold, mpc_or(2, mpc_escape(), mpc_noneof("]"))),
mpcf_re_range
));
-
+
RegexEnclose = mpc_whole(mpc_predictive(Regex), (mpc_dtor_t)mpc_delete);
-
+
mpc_optimise(RegexEnclose);
mpc_optimise(Regex);
mpc_optimise(Term);
mpc_optimise(Factor);
mpc_optimise(Base);
mpc_optimise(Range);
-
+
if(!mpc_parse("", re, RegexEnclose, &r)) {
err_msg = mpc_err_string(r.error);
err_out = mpc_failf("Invalid Regex: %s", err_msg);
- mpc_err_delete(r.error);
+ mpc_err_delete(r.error);
free(err_msg);
r.output = err_out;
}
-
+
mpc_cleanup(6, RegexEnclose, Regex, Term, Factor, Base, Range);
-
+
mpc_optimise(r.output);
-
+
return r.output;
-
+
}
/*
@@ -2446,7 +2446,7 @@ mpc_val_t *mpcf_float(mpc_val_t *x) {
mpc_val_t *mpcf_strtriml(mpc_val_t *x) {
char *s = x;
- while (isspace(*s)) {
+ while (isspace((unsigned char)*s)) {
memmove(s, s+1, strlen(s));
}
return s;
@@ -2455,7 +2455,7 @@ mpc_val_t *mpcf_strtriml(mpc_val_t *x) {
mpc_val_t *mpcf_strtrimr(mpc_val_t *x) {
char *s = x;
size_t l = strlen(s);
- while (isspace(s[l-1])) {
+ while (isspace((unsigned char)s[l-1])) {
s[l-1] = '\0'; l--;
}
return s;
@@ -2468,9 +2468,9 @@ mpc_val_t *mpcf_strtrim(mpc_val_t *x) {
static const char mpc_escape_input_c[] = {
'\a', '\b', '\f', '\n', '\r',
'\t', '\v', '\\', '\'', '\"', '\0'};
-
+
static const char *mpc_escape_output_c[] = {
- "\\a", "\\b", "\\f", "\\n", "\\r", "\\t",
+ "\\a", "\\b", "\\f", "\\n", "\\r", "\\t",
"\\v", "\\\\", "\\'", "\\\"", "\\0", NULL};
static const char mpc_escape_input_raw_re[] = { '/' };
@@ -2483,15 +2483,15 @@ static const char mpc_escape_input_raw_cchar[] = { '\'' };
static const char *mpc_escape_output_raw_cchar[] = { "\\'", NULL };
static mpc_val_t *mpcf_escape_new(mpc_val_t *x, const char *input, const char **output) {
-
+
int i;
int found;
char buff[2];
char *s = x;
char *y = calloc(1, 1);
-
+
while (*s) {
-
+
i = 0;
found = 0;
@@ -2504,33 +2504,33 @@ static mpc_val_t *mpcf_escape_new(mpc_val_t *x, const char *input, const char **
}
i++;
}
-
+
if (!found) {
y = realloc(y, strlen(y) + 2);
buff[0] = *s; buff[1] = '\0';
strcat(y, buff);
}
-
+
s++;
}
-
-
+
+
return y;
}
static mpc_val_t *mpcf_unescape_new(mpc_val_t *x, const char *input, const char **output) {
-
+
int i;
int found = 0;
char buff[2];
char *s = x;
char *y = calloc(1, 1);
-
+
while (*s) {
-
+
i = 0;
found = 0;
-
+
while (output[i]) {
if ((*(s+0)) == output[i][0] &&
(*(s+1)) == output[i][1]) {
@@ -2543,19 +2543,19 @@ static mpc_val_t *mpcf_unescape_new(mpc_val_t *x, const char *input, const char
}
i++;
}
-
+
if (!found) {
y = realloc(y, strlen(y) + 1 + 1);
buff[0] = *s; buff[1] = '\0';
strcat(y, buff);
}
-
+
if (*s == '\0') { break; }
else { s++; }
}
-
+
return y;
-
+
}
mpc_val_t *mpcf_escape(mpc_val_t *x) {
@@ -2573,13 +2573,13 @@ mpc_val_t *mpcf_unescape(mpc_val_t *x) {
mpc_val_t *mpcf_escape_regex(mpc_val_t *x) {
mpc_val_t *y = mpcf_escape_new(x, mpc_escape_input_raw_re, mpc_escape_output_raw_re);
free(x);
- return y;
+ return y;
}
mpc_val_t *mpcf_unescape_regex(mpc_val_t *x) {
mpc_val_t *y = mpcf_unescape_new(x, mpc_escape_input_raw_re, mpc_escape_output_raw_re);
free(x);
- return y;
+ return y;
}
mpc_val_t *mpcf_escape_string_raw(mpc_val_t *x) {
@@ -2618,7 +2618,7 @@ static mpc_val_t *mpcf_nth_free(int n, mpc_val_t **xs, int x) {
}
return xs[x];
}
-
+
mpc_val_t *mpcf_fst_free(int n, mpc_val_t **xs) { return mpcf_nth_free(n, xs, 0); }
mpc_val_t *mpcf_snd_free(int n, mpc_val_t **xs) { return mpcf_nth_free(n, xs, 1); }
mpc_val_t *mpcf_trd_free(int n, mpc_val_t **xs) { return mpcf_nth_free(n, xs, 2); }
@@ -2634,24 +2634,24 @@ mpc_val_t *mpcf_freefold(int n, mpc_val_t **xs) {
mpc_val_t *mpcf_strfold(int n, mpc_val_t **xs) {
int i;
size_t l = 0;
-
+
if (n == 0) { return calloc(1, 1); }
-
+
for (i = 0; i < n; i++) { l += strlen(xs[i]); }
-
+
xs[0] = realloc(xs[0], l + 1);
-
+
for (i = 1; i < n; i++) {
strcat(xs[0], xs[i]); free(xs[i]);
}
-
+
return xs[0];
}
mpc_val_t *mpcf_maths(int n, mpc_val_t **xs) {
int **vs = (int**)xs;
(void) n;
-
+
switch(((char*)xs[1])[0])
{
case '*': { *vs[0] *= *vs[2]; }; break;
@@ -2661,9 +2661,9 @@ mpc_val_t *mpcf_maths(int n, mpc_val_t **xs) {
case '-': { *vs[0] -= *vs[2]; }; break;
default: break;
}
-
+
free(xs[1]); free(xs[2]);
-
+
return xs[0];
}
@@ -2672,19 +2672,19 @@ mpc_val_t *mpcf_maths(int n, mpc_val_t **xs) {
*/
static void mpc_print_unretained(mpc_parser_t *p, int force) {
-
+
/* TODO: Print Everything Escaped */
-
+
int i;
char *s, *e;
char buff[2];
-
+
if (p->retained && !force) {;
if (p->name) { printf("<%s>", p->name); }
else { printf(""); }
return;
}
-
+
if (p->type == MPC_TYPE_UNDEFINED) { printf(">"); }
if (p->type == MPC_TYPE_PASS) { printf("<:>"); }
if (p->type == MPC_TYPE_FAIL) { printf(""); }
@@ -2695,7 +2695,7 @@ static void mpc_print_unretained(mpc_parser_t *p, int force) {
printf("%s", p->data.expect.m);
/*mpc_print_unretained(p->data.expect.x, 0);*/
}
-
+
if (p->type == MPC_TYPE_ANY) { printf("<.>"); }
if (p->type == MPC_TYPE_SATISFY) { printf(""); }
@@ -2708,7 +2708,7 @@ static void mpc_print_unretained(mpc_parser_t *p, int force) {
printf("'%s'", s);
free(s);
}
-
+
if (p->type == MPC_TYPE_RANGE) {
buff[0] = p->data.range.x; buff[1] = '\0';
s = mpcf_escape_new(
@@ -2724,7 +2724,7 @@ static void mpc_print_unretained(mpc_parser_t *p, int force) {
free(s);
free(e);
}
-
+
if (p->type == MPC_TYPE_ONEOF) {
s = mpcf_escape_new(
p->data.string.x,
@@ -2733,7 +2733,7 @@ static void mpc_print_unretained(mpc_parser_t *p, int force) {
printf("[%s]", s);
free(s);
}
-
+
if (p->type == MPC_TYPE_NONEOF) {
s = mpcf_escape_new(
p->data.string.x,
@@ -2742,7 +2742,7 @@ static void mpc_print_unretained(mpc_parser_t *p, int force) {
printf("[^%s]", s);
free(s);
}
-
+
if (p->type == MPC_TYPE_STRING) {
s = mpcf_escape_new(
p->data.string.x,
@@ -2751,7 +2751,7 @@ static void mpc_print_unretained(mpc_parser_t *p, int force) {
printf("\"%s\"", s);
free(s);
}
-
+
if (p->type == MPC_TYPE_APPLY) { mpc_print_unretained(p->data.apply.x, 0); }
if (p->type == MPC_TYPE_APPLY_TO) { mpc_print_unretained(p->data.apply_to.x, 0); }
if (p->type == MPC_TYPE_PREDICT) { mpc_print_unretained(p->data.predict.x, 0); }
@@ -2762,7 +2762,7 @@ 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_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_OR) {
printf("(");
for(i = 0; i < p->data.or.n-1; i++) {
@@ -2772,7 +2772,7 @@ static void mpc_print_unretained(mpc_parser_t *p, int force) {
mpc_print_unretained(p->data.or.xs[p->data.or.n-1], 0);
printf(")");
}
-
+
if (p->type == MPC_TYPE_AND) {
printf("(");
for(i = 0; i < p->data.and.n-1; i++) {
@@ -2829,22 +2829,22 @@ int mpc_test_fail(mpc_parser_t *p, const char *s, const void *d,
destructor(r.output);
return 1;
}
-
+
} else {
mpc_err_delete(r.error);
return 1;
}
-
+
}
int mpc_test_pass(mpc_parser_t *p, const char *s, const void *d,
- int(*tester)(const void*, const void*),
- mpc_dtor_t destructor,
+ int(*tester)(const void*, const void*),
+ mpc_dtor_t destructor,
void(*printer)(const void*)) {
- mpc_result_t r;
+ mpc_result_t r;
if (mpc_parse("", s, p, &r)) {
-
+
if (tester(r.output, d)) {
destructor(r.output);
return 1;
@@ -2854,14 +2854,14 @@ int mpc_test_pass(mpc_parser_t *p, const char *s, const void *d,
destructor(r.output);
return 0;
}
-
- } else {
+
+ } else {
mpc_err_print(r.error);
mpc_err_delete(r.error);
return 0;
-
+
}
-
+
}
@@ -2870,20 +2870,20 @@ int mpc_test_pass(mpc_parser_t *p, const char *s, const void *d,
*/
void mpc_ast_delete(mpc_ast_t *a) {
-
+
int i;
-
+
if (a == NULL) { return; }
-
+
for (i = 0; i < a->children_num; i++) {
mpc_ast_delete(a->children[i]);
}
-
+
free(a->children);
free(a->tag);
free(a->contents);
free(a);
-
+
}
static void mpc_ast_delete_no_children(mpc_ast_t *a) {
@@ -2894,39 +2894,39 @@ static void mpc_ast_delete_no_children(mpc_ast_t *a) {
}
mpc_ast_t *mpc_ast_new(const char *tag, const char *contents) {
-
+
mpc_ast_t *a = malloc(sizeof(mpc_ast_t));
-
+
a->tag = malloc(strlen(tag) + 1);
strcpy(a->tag, tag);
-
+
a->contents = malloc(strlen(contents) + 1);
strcpy(a->contents, contents);
-
+
a->state = mpc_state_new();
-
+
a->children_num = 0;
a->children = NULL;
return a;
-
+
}
mpc_ast_t *mpc_ast_build(int n, const char *tag, ...) {
-
+
mpc_ast_t *a = mpc_ast_new(tag, "");
-
+
int i;
va_list va;
va_start(va, tag);
-
+
for (i = 0; i < n; i++) {
mpc_ast_add_child(a, va_arg(va, mpc_ast_t*));
}
-
+
va_end(va);
-
+
return a;
-
+
}
mpc_ast_t *mpc_ast_add_root(mpc_ast_t *a) {
@@ -2943,17 +2943,17 @@ mpc_ast_t *mpc_ast_add_root(mpc_ast_t *a) {
}
int mpc_ast_eq(mpc_ast_t *a, mpc_ast_t *b) {
-
+
int i;
if (strcmp(a->tag, b->tag) != 0) { return 0; }
if (strcmp(a->contents, b->contents) != 0) { return 0; }
if (a->children_num != b->children_num) { return 0; }
-
+
for (i = 0; i < a->children_num; i++) {
if (!mpc_ast_eq(a->children[i], b->children[i])) { return 0; }
}
-
+
return 1;
}
@@ -2994,29 +2994,29 @@ mpc_ast_t *mpc_ast_state(mpc_ast_t *a, mpc_state_t s) {
}
static void mpc_ast_print_depth(mpc_ast_t *a, int d, FILE *fp) {
-
+
int i;
-
+
if (a == NULL) {
fprintf(fp, "NULL\n");
return;
}
-
+
for (i = 0; i < d; i++) { fprintf(fp, " "); }
-
+
if (strlen(a->contents)) {
- fprintf(fp, "%s:%lu:%lu '%s'\n", a->tag,
+ fprintf(fp, "%s:%lu:%lu '%s'\n", a->tag,
(long unsigned int)(a->state.row+1),
(long unsigned int)(a->state.col+1),
a->contents);
} else {
fprintf(fp, "%s \n", a->tag);
}
-
+
for (i = 0; i < a->children_num; i++) {
mpc_ast_print_depth(a->children[i], d+1, fp);
}
-
+
}
void mpc_ast_print(mpc_ast_t *a) {
@@ -3196,22 +3196,22 @@ void mpc_ast_traverse_free(mpc_ast_trav_t **trav) {
}
mpc_val_t *mpcf_fold_ast(int n, mpc_val_t **xs) {
-
+
int i, j;
mpc_ast_t** as = (mpc_ast_t**)xs;
mpc_ast_t *r;
-
+
if (n == 0) { return NULL; }
if (n == 1) { return xs[0]; }
if (n == 2 && xs[1] == NULL) { return xs[0]; }
if (n == 2 && xs[0] == NULL) { return xs[1]; }
-
+
r = mpc_ast_new(">", "");
-
+
for (i = 0; i < n; i++) {
-
+
if (as[i] == NULL) { continue; }
-
+
if (as[i] && as[i]->children_num == 0) {
mpc_ast_add_child(r, as[i]);
} else if (as[i] && as[i]->children_num == 1) {
@@ -3223,13 +3223,13 @@ mpc_val_t *mpcf_fold_ast(int n, mpc_val_t **xs) {
}
mpc_ast_delete_no_children(as[i]);
}
-
+
}
-
+
if (r->children_num) {
r->state = r->children[0]->state;
}
-
+
return r;
}
@@ -3276,44 +3276,44 @@ mpc_parser_t *mpca_or(int n, ...) {
va_list va;
mpc_parser_t *p = mpc_undefined();
-
+
p->type = MPC_TYPE_OR;
p->data.or.n = n;
p->data.or.xs = malloc(sizeof(mpc_parser_t*) * n);
-
- va_start(va, n);
+
+ va_start(va, n);
for (i = 0; i < n; i++) {
p->data.or.xs[i] = va_arg(va, mpc_parser_t*);
}
va_end(va);
-
+
return p;
-
+
}
mpc_parser_t *mpca_and(int n, ...) {
-
+
int i;
va_list va;
-
+
mpc_parser_t *p = mpc_undefined();
-
+
p->type = MPC_TYPE_AND;
p->data.and.n = n;
p->data.and.f = mpcf_fold_ast;
p->data.and.xs = malloc(sizeof(mpc_parser_t*) * n);
p->data.and.dxs = malloc(sizeof(mpc_dtor_t) * (n-1));
-
+
va_start(va, n);
for (i = 0; i < n; i++) {
p->data.and.xs[i] = va_arg(va, mpc_parser_t*);
}
for (i = 0; i < (n-1); i++) {
p->data.and.dxs[i] = (mpc_dtor_t)mpc_ast_delete;
- }
+ }
va_end(va);
-
- return p;
+
+ return p;
}
mpc_parser_t *mpca_total(mpc_parser_t *a) { return mpc_total(a, (mpc_dtor_t)mpc_ast_delete); }
@@ -3346,7 +3346,7 @@ mpc_parser_t *mpca_total(mpc_parser_t *a) { return mpc_total(a, (mpc_dtor_t)mpc_
** ### Grammar Grammar
**
** : ( "|" ) |
-**
+**
** : *
**
** :
@@ -3354,7 +3354,7 @@ mpc_parser_t *mpca_total(mpc_parser_t *a) { return mpc_total(a, (mpc_dtor_t)mpc_
** | "+"
** | "?"
** | "{" "}"
-**
+**
** : "<" ( | ) ">"
** |
** |
@@ -3377,14 +3377,14 @@ static mpc_val_t *mpcaf_grammar_or(int n, mpc_val_t **xs) {
static mpc_val_t *mpcaf_grammar_and(int n, mpc_val_t **xs) {
int i;
- mpc_parser_t *p = mpc_pass();
+ mpc_parser_t *p = mpc_pass();
for (i = 0; i < n; i++) {
if (xs[i] != NULL) { p = mpca_and(2, p, xs[i]); }
}
return p;
}
-static mpc_val_t *mpcaf_grammar_repeat(int n, mpc_val_t **xs) {
+static mpc_val_t *mpcaf_grammar_repeat(int n, mpc_val_t **xs) {
int num;
(void) n;
if (xs[1] == NULL) { return xs[0]; }
@@ -3423,7 +3423,7 @@ static mpc_val_t *mpcaf_fold_regex(int n, mpc_val_t **xs) {
mpca_grammar_st_t *st = xs[2];
mpc_parser_t *p;
int mode = MPC_RE_DEFAULT;
-
+
(void)n;
if (strchr(m, 'm')) { mode |= MPC_RE_MULTILINE; }
if (strchr(m, 's')) { mode |= MPC_RE_DOTALL; }
@@ -3431,7 +3431,7 @@ static mpc_val_t *mpcaf_fold_regex(int n, mpc_val_t **xs) {
p = (st->flags & MPCA_LANG_WHITESPACE_SENSITIVE) ? mpc_re_mode(y, mode) : mpc_tok(mpc_re_mode(y, mode));
free(y);
free(m);
-
+
return mpca_state(mpca_tag(mpc_apply(p, mpcf_str_ast), "regex"));
}
@@ -3443,15 +3443,15 @@ static int is_number(const char* s) {
}
static mpc_parser_t *mpca_grammar_find_parser(char *x, mpca_grammar_st_t *st) {
-
+
int i;
mpc_parser_t *p;
-
+
/* Case of Number */
if (is_number(x)) {
i = strtol(x, NULL, 10);
-
+
while (st->parsers_num <= i) {
st->parsers_num++;
st->parsers = realloc(st->parsers, sizeof(mpc_parser_t*) * st->parsers_num);
@@ -3460,39 +3460,39 @@ static mpc_parser_t *mpca_grammar_find_parser(char *x, mpca_grammar_st_t *st) {
return mpc_failf("No Parser in position %i! Only supplied %i Parsers!", i, st->parsers_num);
}
}
-
+
return st->parsers[st->parsers_num-1];
-
+
/* Case of Identifier */
} else {
-
+
/* Search Existing Parsers */
for (i = 0; i < st->parsers_num; i++) {
mpc_parser_t *q = st->parsers[i];
if (q == NULL) { return mpc_failf("Unknown Parser '%s'!", x); }
if (q->name && strcmp(q->name, x) == 0) { return q; }
}
-
+
/* Search New Parsers */
while (1) {
-
+
p = va_arg(*st->va, mpc_parser_t*);
-
+
st->parsers_num++;
st->parsers = realloc(st->parsers, sizeof(mpc_parser_t*) * st->parsers_num);
st->parsers[st->parsers_num-1] = p;
-
+
if (p == NULL || p->name == NULL) { return mpc_failf("Unknown Parser '%s'!", x); }
if (p->name && strcmp(p->name, x) == 0) { return p; }
-
+
}
-
- }
-
+
+ }
+
}
static mpc_val_t *mpcaf_grammar_id(mpc_val_t *x, void *s) {
-
+
mpca_grammar_st_t *st = s;
mpc_parser_t *p = mpca_grammar_find_parser(x, st);
free(x);
@@ -3505,30 +3505,30 @@ static mpc_val_t *mpcaf_grammar_id(mpc_val_t *x, void *s) {
}
mpc_parser_t *mpca_grammar_st(const char *grammar, mpca_grammar_st_t *st) {
-
+
char *err_msg;
mpc_parser_t *err_out;
mpc_result_t r;
mpc_parser_t *GrammarTotal, *Grammar, *Term, *Factor, *Base;
-
+
GrammarTotal = mpc_new("grammar_total");
Grammar = mpc_new("grammar");
Term = mpc_new("term");
Factor = mpc_new("factor");
Base = mpc_new("base");
-
+
mpc_define(GrammarTotal,
mpc_predictive(mpc_total(Grammar, mpc_soft_delete))
);
-
+
mpc_define(Grammar, mpc_and(2, mpcaf_grammar_or,
Term,
mpc_maybe(mpc_and(2, mpcf_snd_free, mpc_sym("|"), Grammar, free)),
mpc_soft_delete
));
-
+
mpc_define(Term, mpc_many1(mpcaf_grammar_and, Factor));
-
+
mpc_define(Factor, mpc_and(2, mpcaf_grammar_repeat,
Base,
mpc_or(6,
@@ -3540,7 +3540,7 @@ mpc_parser_t *mpca_grammar_st(const char *grammar, mpca_grammar_st_t *st) {
mpc_pass()),
mpc_soft_delete
));
-
+
mpc_define(Base, mpc_or(5,
mpc_apply_to(mpc_tok(mpc_string_lit()), mpcaf_grammar_string, st),
mpc_apply_to(mpc_tok(mpc_char_lit()), mpcaf_grammar_char, st),
@@ -3548,13 +3548,13 @@ mpc_parser_t *mpca_grammar_st(const char *grammar, mpca_grammar_st_t *st) {
mpc_apply_to(mpc_tok_braces(mpc_or(2, mpc_digits(), mpc_ident()), free), mpcaf_grammar_id, st),
mpc_tok_parens(Grammar, mpc_soft_delete)
));
-
+
mpc_optimise(GrammarTotal);
mpc_optimise(Grammar);
mpc_optimise(Factor);
mpc_optimise(Term);
mpc_optimise(Base);
-
+
if(!mpc_parse("", grammar, GrammarTotal, &r)) {
err_msg = mpc_err_string(r.error);
err_out = mpc_failf("Invalid Grammar: %s", err_msg);
@@ -3562,13 +3562,13 @@ mpc_parser_t *mpca_grammar_st(const char *grammar, mpca_grammar_st_t *st) {
free(err_msg);
r.output = err_out;
}
-
+
mpc_cleanup(5, GrammarTotal, Grammar, Term, Factor, Base);
-
+
mpc_optimise(r.output);
-
+
return (st->flags & MPCA_LANG_PREDICTIVE) ? mpc_predictive(r.output) : r.output;
-
+
}
mpc_parser_t *mpca_grammar(int flags, const char *grammar, ...) {
@@ -3576,13 +3576,13 @@ mpc_parser_t *mpca_grammar(int flags, const char *grammar, ...) {
mpc_parser_t *res;
va_list va;
va_start(va, grammar);
-
+
st.va = &va;
st.parsers_num = 0;
st.parsers = NULL;
st.flags = flags;
-
- res = mpca_grammar_st(grammar, &st);
+
+ res = mpca_grammar_st(grammar, &st);
free(st.parsers);
va_end(va);
return res;
@@ -3602,20 +3602,20 @@ static mpc_val_t *mpca_stmt_afold(int n, mpc_val_t **xs) {
(void) n;
free(((char**)xs)[2]);
free(((char**)xs)[4]);
-
+
return stmt;
}
static mpc_val_t *mpca_stmt_fold(int n, mpc_val_t **xs) {
-
+
int i;
mpca_stmt_t **stmts = malloc(sizeof(mpca_stmt_t*) * (n+1));
-
+
for (i = 0; i < n; i++) {
stmts[i] = xs[i];
}
- stmts[n] = NULL;
-
+ stmts[n] = NULL;
+
return stmts;
}
@@ -3624,11 +3624,11 @@ static void mpca_stmt_list_delete(mpc_val_t *x) {
mpca_stmt_t **stmts = x;
while(*stmts) {
- mpca_stmt_t *stmt = *stmts;
+ mpca_stmt_t *stmt = *stmts;
free(stmt->ident);
free(stmt->name);
mpc_soft_delete(stmt->grammar);
- free(stmt);
+ free(stmt);
stmts++;
}
free(x);
@@ -3654,43 +3654,43 @@ static mpc_val_t *mpca_stmt_list_apply_to(mpc_val_t *x, void *s) {
free(stmt);
stmts++;
}
-
+
free(x);
-
+
return NULL;
}
static mpc_err_t *mpca_lang_st(mpc_input_t *i, mpca_grammar_st_t *st) {
-
+
mpc_result_t r;
mpc_err_t *e;
- mpc_parser_t *Lang, *Stmt, *Grammar, *Term, *Factor, *Base;
-
+ mpc_parser_t *Lang, *Stmt, *Grammar, *Term, *Factor, *Base;
+
Lang = mpc_new("lang");
Stmt = mpc_new("stmt");
Grammar = mpc_new("grammar");
Term = mpc_new("term");
Factor = mpc_new("factor");
Base = mpc_new("base");
-
+
mpc_define(Lang, mpc_apply_to(
mpc_total(mpc_predictive(mpc_many(mpca_stmt_fold, Stmt)), mpca_stmt_list_delete),
mpca_stmt_list_apply_to, st
));
-
+
mpc_define(Stmt, mpc_and(5, mpca_stmt_afold,
mpc_tok(mpc_ident()), mpc_maybe(mpc_tok(mpc_string_lit())), mpc_sym(":"), Grammar, mpc_sym(";"),
free, free, free, mpc_soft_delete
));
-
+
mpc_define(Grammar, mpc_and(2, mpcaf_grammar_or,
Term,
mpc_maybe(mpc_and(2, mpcf_snd_free, mpc_sym("|"), Grammar, free)),
mpc_soft_delete
));
-
+
mpc_define(Term, mpc_many1(mpcaf_grammar_and, Factor));
-
+
mpc_define(Factor, mpc_and(2, mpcaf_grammar_repeat,
Base,
mpc_or(6,
@@ -3702,7 +3702,7 @@ static mpc_err_t *mpca_lang_st(mpc_input_t *i, mpca_grammar_st_t *st) {
mpc_pass()),
mpc_soft_delete
));
-
+
mpc_define(Base, mpc_or(5,
mpc_apply_to(mpc_tok(mpc_string_lit()), mpcaf_grammar_string, st),
mpc_apply_to(mpc_tok(mpc_char_lit()), mpcaf_grammar_char, st),
@@ -3710,22 +3710,22 @@ static mpc_err_t *mpca_lang_st(mpc_input_t *i, mpca_grammar_st_t *st) {
mpc_apply_to(mpc_tok_braces(mpc_or(2, mpc_digits(), mpc_ident()), free), mpcaf_grammar_id, st),
mpc_tok_parens(Grammar, mpc_soft_delete)
));
-
+
mpc_optimise(Lang);
mpc_optimise(Stmt);
mpc_optimise(Grammar);
mpc_optimise(Term);
mpc_optimise(Factor);
mpc_optimise(Base);
-
+
if (!mpc_parse_input(i, Lang, &r)) {
e = r.error;
} else {
e = NULL;
}
-
+
mpc_cleanup(6, Lang, Stmt, Grammar, Term, Factor, Base);
-
+
return e;
}
@@ -3734,18 +3734,18 @@ mpc_err_t *mpca_lang_file(int flags, FILE *f, ...) {
mpc_input_t *i;
mpc_err_t *err;
- va_list va;
+ va_list va;
va_start(va, f);
-
+
st.va = &va;
st.parsers_num = 0;
st.parsers = NULL;
st.flags = flags;
-
+
i = mpc_input_new_file("", f);
err = mpca_lang_st(i, &st);
mpc_input_delete(i);
-
+
free(st.parsers);
va_end(va);
return err;
@@ -3756,77 +3756,77 @@ mpc_err_t *mpca_lang_pipe(int flags, FILE *p, ...) {
mpc_input_t *i;
mpc_err_t *err;
- va_list va;
+ va_list va;
va_start(va, p);
-
+
st.va = &va;
st.parsers_num = 0;
st.parsers = NULL;
st.flags = flags;
-
+
i = mpc_input_new_pipe("", p);
err = mpca_lang_st(i, &st);
mpc_input_delete(i);
-
+
free(st.parsers);
va_end(va);
return err;
}
mpc_err_t *mpca_lang(int flags, const char *language, ...) {
-
+
mpca_grammar_st_t st;
mpc_input_t *i;
mpc_err_t *err;
-
- va_list va;
+
+ va_list va;
va_start(va, language);
-
+
st.va = &va;
st.parsers_num = 0;
st.parsers = NULL;
st.flags = flags;
-
+
i = mpc_input_new_string("", language);
err = mpca_lang_st(i, &st);
mpc_input_delete(i);
-
+
free(st.parsers);
va_end(va);
return err;
}
mpc_err_t *mpca_lang_contents(int flags, const char *filename, ...) {
-
+
mpca_grammar_st_t st;
mpc_input_t *i;
mpc_err_t *err;
-
+
va_list va;
FILE *f = fopen(filename, "rb");
-
+
if (f == NULL) {
err = mpc_err_file(filename, "Unable to open file!");
return err;
}
-
+
va_start(va, filename);
-
+
st.va = &va;
st.parsers_num = 0;
st.parsers = NULL;
st.flags = flags;
-
+
i = mpc_input_new_file(filename, f);
err = mpca_lang_st(i, &st);
mpc_input_delete(i);
-
+
free(st.parsers);
- va_end(va);
-
+ va_end(va);
+
fclose(f);
-
+
return err;
}
@@ -3852,14 +3852,14 @@ static int mpc_nodecount_unretained(mpc_parser_t* p, int force) {
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_OR) {
+ if (p->type == MPC_TYPE_OR) {
total = 1;
for(i = 0; i < p->data.or.n; i++) {
total += mpc_nodecount_unretained(p->data.or.xs[i], 0);
}
return total;
}
-
+
if (p->type == MPC_TYPE_AND) {
total = 1;
for(i = 0; i < p->data.and.n; i++) {
@@ -3869,7 +3869,7 @@ static int mpc_nodecount_unretained(mpc_parser_t* p, int force) {
}
return 1;
-
+
}
void mpc_stats(mpc_parser_t* p) {
@@ -3879,14 +3879,14 @@ void mpc_stats(mpc_parser_t* p) {
}
static void mpc_optimise_unretained(mpc_parser_t *p, int force) {
-
+
int i, n, m;
mpc_parser_t *t;
-
+
if (p->retained && !force) { return; }
-
+
/* Optimise Subexpressions */
-
+
if (p->type == MPC_TYPE_EXPECT) { mpc_optimise_unretained(p->data.expect.x, 0); }
if (p->type == MPC_TYPE_APPLY) { mpc_optimise_unretained(p->data.apply.x, 0); }
if (p->type == MPC_TYPE_APPLY_TO) { mpc_optimise_unretained(p->data.apply_to.x, 0); }
@@ -3898,23 +3898,23 @@ 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_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_OR) {
+
+ if (p->type == MPC_TYPE_OR) {
for(i = 0; i < p->data.or.n; i++) {
mpc_optimise_unretained(p->data.or.xs[i], 0);
}
}
-
+
if (p->type == MPC_TYPE_AND) {
for(i = 0; i < p->data.and.n; i++) {
mpc_optimise_unretained(p->data.and.xs[i], 0);
}
- }
-
+ }
+
/* Perform optimisations */
-
+
while (1) {
-
+
/* Merge rhs `or` */
if (p->type == MPC_TYPE_OR
&& p->data.or.xs[p->data.or.n-1]->type == MPC_TYPE_OR
@@ -3941,7 +3941,7 @@ static void mpc_optimise_unretained(mpc_parser_t *p, int force) {
free(t->data.or.xs); free(t->name); free(t);
continue;
}
-
+
/* Remove ast `pass` */
if (p->type == MPC_TYPE_AND
&& p->data.and.n == 2
@@ -3955,7 +3955,7 @@ static void mpc_optimise_unretained(mpc_parser_t *p, int force) {
free(t);
continue;
}
-
+
/* Merge ast lhs `and` */
if (p->type == MPC_TYPE_AND
&& p->data.and.f == mpcf_fold_ast
@@ -3970,10 +3970,10 @@ static void mpc_optimise_unretained(mpc_parser_t *p, int force) {
memmove(p->data.and.xs + m, p->data.and.xs + 1, (n - 1) * sizeof(mpc_parser_t*));
memmove(p->data.and.xs, t->data.and.xs, m * sizeof(mpc_parser_t*));
for (i = 0; i < p->data.and.n-1; i++) { p->data.and.dxs[i] = (mpc_dtor_t)mpc_ast_delete; }
- free(t->data.and.xs); free(t->data.and.dxs); free(t->name); free(t);
+ free(t->data.and.xs); free(t->data.and.dxs); free(t->name); free(t);
continue;
}
-
+
/* Merge ast rhs `and` */
if (p->type == MPC_TYPE_AND
&& p->data.and.f == mpcf_fold_ast
@@ -3987,7 +3987,7 @@ static void mpc_optimise_unretained(mpc_parser_t *p, int force) {
p->data.and.dxs = realloc(p->data.and.dxs, sizeof(mpc_dtor_t) * (n + m - 1 - 1));
memmove(p->data.and.xs + n - 1, t->data.and.xs, m * sizeof(mpc_parser_t*));
for (i = 0; i < p->data.and.n-1; i++) { p->data.and.dxs[i] = (mpc_dtor_t)mpc_ast_delete; }
- free(t->data.and.xs); free(t->data.and.dxs); free(t->name); free(t);
+ free(t->data.and.xs); free(t->data.and.dxs); free(t->name); free(t);
continue;
}
@@ -4020,10 +4020,10 @@ static void mpc_optimise_unretained(mpc_parser_t *p, int force) {
memmove(p->data.and.xs + m, p->data.and.xs + 1, (n - 1) * sizeof(mpc_parser_t*));
memmove(p->data.and.xs, t->data.and.xs, m * sizeof(mpc_parser_t*));
for (i = 0; i < p->data.and.n-1; i++) { p->data.and.dxs[i] = free; }
- free(t->data.and.xs); free(t->data.and.dxs); free(t->name); free(t);
+ free(t->data.and.xs); free(t->data.and.dxs); free(t->name); free(t);
continue;
}
-
+
/* Merge re rhs `and` */
if (p->type == MPC_TYPE_AND
&& p->data.and.f == mpcf_strfold
@@ -4037,14 +4037,14 @@ static void mpc_optimise_unretained(mpc_parser_t *p, int force) {
p->data.and.dxs = realloc(p->data.and.dxs, sizeof(mpc_dtor_t) * (n + m - 1 - 1));
memmove(p->data.and.xs + n - 1, t->data.and.xs, m * sizeof(mpc_parser_t*));
for (i = 0; i < p->data.and.n-1; i++) { p->data.and.dxs[i] = free; }
- free(t->data.and.xs); free(t->data.and.dxs); free(t->name); free(t);
+ free(t->data.and.xs); free(t->data.and.dxs); free(t->name); free(t);
continue;
}
-
+
return;
-
+
}
-
+
}
void mpc_optimise(mpc_parser_t *p) {