Various fixes
This commit is contained in:
15
README.md
15
README.md
@@ -7,6 +7,7 @@ Using _mpc_ might be of interest to you if you are...
|
|||||||
|
|
||||||
* Building a new programming language
|
* Building a new programming language
|
||||||
* Building a new data format
|
* Building a new data format
|
||||||
|
* Parsing an existing programming languages
|
||||||
* Parsing an existing data format
|
* Parsing an existing data format
|
||||||
* Embedding a Domain Specific Language
|
* Embedding a Domain Specific Language
|
||||||
* Implementing [Greenspun's Tenth Rule](http://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule)
|
* Implementing [Greenspun's Tenth Rule](http://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule)
|
||||||
@@ -15,12 +16,12 @@ Using _mpc_ might be of interest to you if you are...
|
|||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
|
|
||||||
* Type-Generic Parser Combinators
|
* Type-Generic
|
||||||
* Predictive Recursive Descent Parsers
|
* Predictive, Recursive Descent
|
||||||
* Error Message Support
|
|
||||||
* Regular Expression Support
|
|
||||||
* Grammar Support
|
|
||||||
* Easy to Integrate (One Source File in ANSI C)
|
* Easy to Integrate (One Source File in ANSI C)
|
||||||
|
* Error Messages
|
||||||
|
* Regular Expression Parser Generator
|
||||||
|
* Grammar Parser Generator
|
||||||
|
|
||||||
|
|
||||||
Alternatives
|
Alternatives
|
||||||
@@ -28,7 +29,7 @@ Alternatives
|
|||||||
|
|
||||||
The current main alternative C based parser combinator is a branch of [Cesium3](https://github.com/wbhart/Cesium3/tree/combinators).
|
The current main alternative C based parser combinator is a branch of [Cesium3](https://github.com/wbhart/Cesium3/tree/combinators).
|
||||||
|
|
||||||
This project has several downsides which _mpc_ overcomes:
|
_mpc_ provides a number of features that this project does not offer, but it also overcomes a number of potential downsides:
|
||||||
|
|
||||||
* _mpc_ Works for Generic Types
|
* _mpc_ Works for Generic Types
|
||||||
* _mpc_ Doesn't rely on Boehm-Demers-Weiser Garbage Collection
|
* _mpc_ Doesn't rely on Boehm-Demers-Weiser Garbage Collection
|
||||||
@@ -73,7 +74,7 @@ mpc_ast_t* parse_maths(const char* input) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
If you were to input something like `"(4 * 2 * 11 + 2) - 5"` into this function the `mpc_ast_t` you get out would look something like this:
|
If you were to input `"(4 * 2 * 11 + 2) - 5"` into this function, the `mpc_ast_t` output would look something like this:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
>:
|
>:
|
||||||
|
5
TODO.md
5
TODO.md
@@ -1,3 +1,8 @@
|
|||||||
|
- Escape/Crop String Literals
|
||||||
|
- Escale/Crop Char Literals
|
||||||
|
- Escape/Crop Regex Literals
|
||||||
|
- Combinator that scans input then returns cursor.
|
||||||
|
|
||||||
- Test All Regex Features
|
- Test All Regex Features
|
||||||
- Test Regex Range Feature
|
- Test Regex Range Feature
|
||||||
- Add proper tests for everything in general
|
- Add proper tests for everything in general
|
||||||
|
60
mpc.c
60
mpc.c
@@ -269,10 +269,6 @@ static mpc_err_t* mpc_err_count(mpc_err_t* x, int n) {
|
|||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* mpc_err_filename(mpc_err_t* x) {
|
|
||||||
return x->filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mpc_err_expected(mpc_err_t* x, char** out, int* out_num, int out_max) {
|
void mpc_err_expected(mpc_err_t* x, char** out, int* out_num, int out_max) {
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
@@ -284,17 +280,10 @@ void mpc_err_expected(mpc_err_t* x, char** out, int* out_num, int out_max) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int mpc_err_line(mpc_err_t* x) {
|
char* mpc_err_filename(mpc_err_t* x) { return x->filename; }
|
||||||
return x->state.row;
|
int mpc_err_line(mpc_err_t* x) { return x->state.row; }
|
||||||
}
|
int mpc_err_column(mpc_err_t* x) { return x->state.col; }
|
||||||
|
char mpc_err_unexpected(mpc_err_t* x) { return x->state.next; }
|
||||||
int mpc_err_column(mpc_err_t* x) {
|
|
||||||
return x->state.col;
|
|
||||||
}
|
|
||||||
|
|
||||||
char mpc_err_unexpected(mpc_err_t* x) {
|
|
||||||
return x->state.next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Input Type
|
** Input Type
|
||||||
@@ -878,20 +867,21 @@ static mpc_err_t* mpc_stack_merger_err(mpc_stack_t* s, int n) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** This is rather pleasant. The core parsing routine
|
** This is rather pleasant. The core parsing routine
|
||||||
** is written in about 300 lines of C.
|
** is written in about 200 lines of C.
|
||||||
**
|
**
|
||||||
** I also love the way in which each parsing type
|
** I also love the way in which each parsing type
|
||||||
** concisely matches some construct or pattern.
|
** concisely matches some construct or pattern.
|
||||||
**
|
**
|
||||||
** Particularly nice are the `either` and `also`
|
** Particularly nice are the `or` and `and`
|
||||||
** types which have a broken but mirrored structure
|
** types which have a broken but mirrored structure
|
||||||
** with return value and error reflected.
|
** with return value and error reflected.
|
||||||
**
|
**
|
||||||
** When this function was written in recursive form
|
** When this function was written in recursive form
|
||||||
** it looked pretty nice. But I've since switched
|
** it looked pretty nice. But I've since switched
|
||||||
** it around to an akward while loop. It was an
|
** it around to an akward while loop. It was an
|
||||||
** unfortunate change but if was a noble attempt
|
** unfortunate change for code simplicity but it
|
||||||
** in the name of performance (and not smashing the stack).
|
** is noble in the name of performance (and
|
||||||
|
** not smashing the stack).
|
||||||
**
|
**
|
||||||
** But it is now a pretty ugly beast...
|
** But it is now a pretty ugly beast...
|
||||||
*/
|
*/
|
||||||
@@ -910,7 +900,6 @@ int mpc_parse_input(mpc_input_t* i, mpc_parser_t* init, mpc_result_t* final) {
|
|||||||
|
|
||||||
/* Variables */
|
/* Variables */
|
||||||
char* s;
|
char* s;
|
||||||
mpc_val_t* t;
|
|
||||||
mpc_result_t r;
|
mpc_result_t r;
|
||||||
|
|
||||||
/* Go! */
|
/* Go! */
|
||||||
@@ -1178,9 +1167,7 @@ static void mpc_undefine_unretained(mpc_parser_t* p, int force) {
|
|||||||
|
|
||||||
switch (p->type) {
|
switch (p->type) {
|
||||||
|
|
||||||
case MPC_TYPE_FAIL:
|
case MPC_TYPE_FAIL: free(p->data.fail.m); break;
|
||||||
free(p->data.fail.m);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MPC_TYPE_ONEOF:
|
case MPC_TYPE_ONEOF:
|
||||||
case MPC_TYPE_NONEOF:
|
case MPC_TYPE_NONEOF:
|
||||||
@@ -1188,17 +1175,9 @@ static void mpc_undefine_unretained(mpc_parser_t* p, int force) {
|
|||||||
free(p->data.string.x);
|
free(p->data.string.x);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MPC_TYPE_APPLY:
|
case MPC_TYPE_APPLY: mpc_undefine_unretained(p->data.apply.x, 0); break;
|
||||||
mpc_undefine_unretained(p->data.apply.x, 0);
|
case MPC_TYPE_APPLY_TO: mpc_undefine_unretained(p->data.apply_to.x, 0); break;
|
||||||
break;
|
case MPC_TYPE_PREDICT: mpc_undefine_unretained(p->data.predict.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_MAYBE:
|
||||||
case MPC_TYPE_NOT:
|
case MPC_TYPE_NOT:
|
||||||
@@ -1216,13 +1195,8 @@ 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_OR:
|
case MPC_TYPE_OR: mpc_undefine_or(p); break;
|
||||||
mpc_undefine_or(p);
|
case MPC_TYPE_AND: mpc_undefine_and(p); break;
|
||||||
break;
|
|
||||||
|
|
||||||
case MPC_TYPE_AND:
|
|
||||||
mpc_undefine_and(p);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
@@ -1889,6 +1863,10 @@ static mpc_val_t* mpcf_re_range(mpc_val_t* x) {
|
|||||||
if (tmp != NULL) {
|
if (tmp != NULL) {
|
||||||
range = realloc(range, strlen(range) + strlen(tmp) + 1);
|
range = realloc(range, strlen(range) + strlen(tmp) + 1);
|
||||||
strcat(range, tmp);
|
strcat(range, tmp);
|
||||||
|
} else {
|
||||||
|
range = realloc(range, strlen(range) + 1 + 1);
|
||||||
|
range[strlen(range) + 1] = '\0';
|
||||||
|
range[strlen(range) + 0] = s[i+1];
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user