Fixed bug with end of file and parsing from a file
This commit is contained in:
29
mpc.c
29
mpc.c
@@ -363,13 +363,6 @@ static char mpc_input_buffer_get(mpc_input_t *i) {
|
|||||||
return i->buffer[i->state.pos - i->marks[0].pos];
|
return i->buffer[i->state.pos - i->marks[0].pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mpc_input_terminated(mpc_input_t *i) {
|
|
||||||
if (i->type == MPC_INPUT_STRING && i->state.pos == (long)strlen(i->string)) { return 1; }
|
|
||||||
if (i->type == MPC_INPUT_FILE && feof(i->file)) { return 1; }
|
|
||||||
if (i->type == MPC_INPUT_PIPE && feof(i->file)) { return 1; }
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char mpc_input_getc(mpc_input_t *i) {
|
static char mpc_input_getc(mpc_input_t *i) {
|
||||||
|
|
||||||
char c = '\0';
|
char c = '\0';
|
||||||
@@ -431,6 +424,10 @@ static char mpc_input_peekc(mpc_input_t *i) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mpc_input_terminated(mpc_input_t *i) {
|
||||||
|
return mpc_input_peekc(i) == '\0';
|
||||||
|
}
|
||||||
|
|
||||||
static int mpc_input_failure(mpc_input_t *i, char c) {
|
static int mpc_input_failure(mpc_input_t *i, char c) {
|
||||||
|
|
||||||
switch (i->type) {
|
switch (i->type) {
|
||||||
@@ -479,38 +476,44 @@ static int mpc_input_success(mpc_input_t *i, char c, char **o) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int mpc_input_any(mpc_input_t *i, char **o) {
|
static int mpc_input_any(mpc_input_t *i, char **o) {
|
||||||
char x = mpc_input_getc(i);
|
char x;
|
||||||
if (mpc_input_terminated(i)) { return 0; }
|
if (mpc_input_terminated(i)) { return 0; }
|
||||||
|
x = mpc_input_getc(i);
|
||||||
return mpc_input_success(i, x, o);
|
return mpc_input_success(i, x, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mpc_input_char(mpc_input_t *i, char c, char **o) {
|
static int mpc_input_char(mpc_input_t *i, char c, char **o) {
|
||||||
char x = mpc_input_getc(i);
|
char x;
|
||||||
if (mpc_input_terminated(i)) { return 0; }
|
if (mpc_input_terminated(i)) { return 0; }
|
||||||
|
x = mpc_input_getc(i);
|
||||||
return x == c ? mpc_input_success(i, x, o) : mpc_input_failure(i, x);
|
return x == c ? mpc_input_success(i, x, o) : mpc_input_failure(i, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mpc_input_range(mpc_input_t *i, char c, char d, char **o) {
|
static int mpc_input_range(mpc_input_t *i, char c, char d, char **o) {
|
||||||
char x = mpc_input_getc(i);
|
char x;
|
||||||
if (mpc_input_terminated(i)) { return 0; }
|
if (mpc_input_terminated(i)) { return 0; }
|
||||||
|
x = mpc_input_getc(i);
|
||||||
return x >= c && x <= d ? mpc_input_success(i, x, o) : mpc_input_failure(i, x);
|
return x >= c && x <= d ? mpc_input_success(i, x, o) : mpc_input_failure(i, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mpc_input_oneof(mpc_input_t *i, const char *c, char **o) {
|
static int mpc_input_oneof(mpc_input_t *i, const char *c, char **o) {
|
||||||
char x = mpc_input_getc(i);
|
char x;
|
||||||
if (mpc_input_terminated(i)) { return 0; }
|
if (mpc_input_terminated(i)) { return 0; }
|
||||||
|
x = mpc_input_getc(i);
|
||||||
return strchr(c, x) != 0 ? mpc_input_success(i, x, o) : mpc_input_failure(i, x);
|
return strchr(c, x) != 0 ? mpc_input_success(i, x, o) : mpc_input_failure(i, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mpc_input_noneof(mpc_input_t *i, const char *c, char **o) {
|
static int mpc_input_noneof(mpc_input_t *i, const char *c, char **o) {
|
||||||
char x = mpc_input_getc(i);
|
char x;
|
||||||
if (mpc_input_terminated(i)) { return 0; }
|
if (mpc_input_terminated(i)) { return 0; }
|
||||||
|
x = mpc_input_getc(i);
|
||||||
return strchr(c, x) == 0 ? mpc_input_success(i, x, o) : mpc_input_failure(i, x);
|
return strchr(c, x) == 0 ? mpc_input_success(i, x, o) : mpc_input_failure(i, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mpc_input_satisfy(mpc_input_t *i, int(*cond)(char), char **o) {
|
static int mpc_input_satisfy(mpc_input_t *i, int(*cond)(char), char **o) {
|
||||||
char x = mpc_input_getc(i);
|
char x;
|
||||||
if (mpc_input_terminated(i)) { return 0; }
|
if (mpc_input_terminated(i)) { return 0; }
|
||||||
|
x = mpc_input_getc(i);
|
||||||
return cond(x) ? mpc_input_success(i, x, o) : mpc_input_failure(i, x);
|
return cond(x) ? mpc_input_success(i, x, o) : mpc_input_failure(i, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -188,7 +188,7 @@ void test_reader(void) {
|
|||||||
static int token_count = 0;
|
static int token_count = 0;
|
||||||
|
|
||||||
static mpc_val_t *print_token(mpc_val_t *x) {
|
static mpc_val_t *print_token(mpc_val_t *x) {
|
||||||
printf("Token: '%s'\n", (char*)x);
|
/*printf("Token: '%s'\n", (char*)x);*/
|
||||||
token_count++;
|
token_count++;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
1
tests/digits.txt
Normal file
1
tests/digits.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
123
|
@@ -337,6 +337,69 @@ void test_regex_mode(void) {
|
|||||||
mpc_cleanup(4, Line0, Line1, Line2, Line3);
|
mpc_cleanup(4, Line0, Line1, Line2, Line3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_digits_file(void) {
|
||||||
|
|
||||||
|
FILE *f;
|
||||||
|
mpc_result_t r;
|
||||||
|
mpc_parser_t *Digit = mpc_new("digit");
|
||||||
|
mpc_parser_t *Program = mpc_new("program");
|
||||||
|
mpc_ast_t* t0;
|
||||||
|
|
||||||
|
mpc_err_t* err = mpca_lang(MPCA_LANG_DEFAULT,
|
||||||
|
" digit : /[0-9]/ ;"
|
||||||
|
" program : /^/ <digit>+ /$/ ;"
|
||||||
|
, Digit, Program, NULL);
|
||||||
|
|
||||||
|
PT_ASSERT(err == NULL);
|
||||||
|
|
||||||
|
t0 = mpc_ast_build(5, ">",
|
||||||
|
mpc_ast_new("regex", ""),
|
||||||
|
mpc_ast_new("digit|regex", "1"),
|
||||||
|
mpc_ast_new("digit|regex", "2"),
|
||||||
|
mpc_ast_new("digit|regex", "3"),
|
||||||
|
mpc_ast_new("regex", ""));
|
||||||
|
|
||||||
|
if (mpc_parse_contents("tests/digits.txt", Program, &r)) {
|
||||||
|
PT_ASSERT(1);
|
||||||
|
PT_ASSERT(mpc_ast_eq(t0, r.output));
|
||||||
|
mpc_ast_delete(r.output);
|
||||||
|
} else {
|
||||||
|
PT_ASSERT(0);
|
||||||
|
mpc_err_print(r.error);
|
||||||
|
mpc_err_delete(r.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
f = fopen("tests/digits.txt", "r");
|
||||||
|
PT_ASSERT(f != NULL);
|
||||||
|
|
||||||
|
if (mpc_parse_file("tests/digits.txt", f, Program, &r)) {
|
||||||
|
PT_ASSERT(1);
|
||||||
|
PT_ASSERT(mpc_ast_eq(t0, r.output));
|
||||||
|
mpc_ast_delete(r.output);
|
||||||
|
} else {
|
||||||
|
PT_ASSERT(0);
|
||||||
|
mpc_err_print(r.error);
|
||||||
|
mpc_err_delete(r.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
if (mpc_parse("tests/digits.txt", "123", Program, &r)) {
|
||||||
|
PT_ASSERT(1);
|
||||||
|
PT_ASSERT(mpc_ast_eq(t0, r.output));
|
||||||
|
mpc_ast_delete(r.output);
|
||||||
|
} else {
|
||||||
|
PT_ASSERT(0);
|
||||||
|
mpc_err_print(r.error);
|
||||||
|
mpc_err_delete(r.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
mpc_ast_delete(t0);
|
||||||
|
|
||||||
|
mpc_cleanup(2, Digit, Program);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void suite_grammar(void) {
|
void suite_grammar(void) {
|
||||||
pt_add_test(test_grammar, "Test Grammar", "Suite Grammar");
|
pt_add_test(test_grammar, "Test Grammar", "Suite Grammar");
|
||||||
pt_add_test(test_language, "Test Language", "Suite Grammar");
|
pt_add_test(test_language, "Test Language", "Suite Grammar");
|
||||||
@@ -346,4 +409,5 @@ void suite_grammar(void) {
|
|||||||
pt_add_test(test_qscript, "Test QScript", "Suite Grammar");
|
pt_add_test(test_qscript, "Test QScript", "Suite Grammar");
|
||||||
pt_add_test(test_missingrule, "Test Missing Rule", "Suite Grammar");
|
pt_add_test(test_missingrule, "Test Missing Rule", "Suite Grammar");
|
||||||
pt_add_test(test_regex_mode, "Test Regex Mode", "Suite Grammar");
|
pt_add_test(test_regex_mode, "Test Regex Mode", "Suite Grammar");
|
||||||
|
pt_add_test(test_digits_file, "Test Digits File", "Suite Grammar");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user