summaryrefslogtreecommitdiff
path: root/src/runtime/c
diff options
context:
space:
mode:
authorKrasimir Angelov <kr.angelov@gmail.com>2017-09-06 12:38:42 +0200
committerKrasimir Angelov <kr.angelov@gmail.com>2017-09-06 12:38:42 +0200
commit15d014abb825837f0fd7c9e17d5907001135faaf (patch)
treebc569f465432042702dfaa240746b8c6db609588 /src/runtime/c
parent18f2135785a71a1e93519a060d40b7ba523cf03b (diff)
the parser in the C runtime can now detect incomplete sentences just like the parser in the Haskell runtime. This is also reflected in all bindings.
Diffstat (limited to 'src/runtime/c')
-rw-r--r--src/runtime/c/pgf/parser.c37
-rw-r--r--src/runtime/c/pgf/pgf.h7
2 files changed, 29 insertions, 15 deletions
diff --git a/src/runtime/c/pgf/parser.c b/src/runtime/c/pgf/parser.c
index ecfb7d2ea..2cae01db6 100644
--- a/src/runtime/c/pgf/parser.c
+++ b/src/runtime/c/pgf/parser.c
@@ -2139,30 +2139,37 @@ pgf_parse_result_enum_next(GuEnum* self, void* to, GuPool* pool)
*(PgfExprProb**)to = pgf_parse_result_next(ps);
}
-static GuString
-pgf_parsing_last_token(PgfParsing* ps, GuPool* pool)
+static PgfParseError*
+pgf_parsing_new_exception(PgfParsing* ps, GuPool* pool)
{
- if (ps->before == NULL)
- return "";
+ const uint8_t* p = (uint8_t*) ps->sentence;
+ const uint8_t* end = p + (ps->before ? ps->before->end_offset : 0);
- const uint8_t* start = (uint8_t*) ps->sentence;
- const uint8_t* end = (uint8_t*) ps->sentence + ps->before->end_offset;
+ PgfParseError* err = gu_new(PgfParseError, pool);
+ err->incomplete= (*end == 0);
+ err->offset = 0;
+ err->token_ptr = (char*) p;
- const uint8_t* p = start;
while (p < end) {
if (gu_ucs_is_space(gu_utf8_decode(&p))) {
- start = p;
+ err->token_ptr = (char*) p;
}
+ err->offset++;
+ }
+
+ if (err->incomplete) {
+ err->token_ptr = NULL;
+ err->token_len = 0;
+ return err;
}
while (*p && !gu_ucs_is_space(gu_utf8_decode(&p))) {
end = p;
}
- char* tok = gu_malloc(pool, end-start+1);
- memcpy(tok, start, (end-start));
- tok[end-start] = 0;
- return tok;
+ err->token_len = ((char*)end)-err->token_ptr;
+
+ return err;
}
PGF_API GuEnum*
@@ -2204,7 +2211,7 @@ pgf_parse_with_heuristics(PgfConcr* concr, PgfType* typ, GuString sentence,
while (gu_buf_length(ps->expr_queue) == 0) {
if (!pgf_parsing_proceed(ps)) {
GuExnData* exn = gu_raise(err, PgfParseError);
- exn->data = (void*) pgf_parsing_last_token(ps, exn->pool);
+ exn->data = (void*) pgf_parsing_new_exception(ps, exn->pool);
return NULL;
}
@@ -2249,7 +2256,7 @@ pgf_parse_with_oracle(PgfConcr* concr, PgfType* typ,
while (gu_buf_length(ps->expr_queue) == 0) {
if (!pgf_parsing_proceed(ps)) {
GuExnData* exn = gu_raise(err, PgfParseError);
- exn->data = (void*) pgf_parsing_last_token(ps, exn->pool);
+ exn->data = (void*) pgf_parsing_new_exception(ps, exn->pool);
return NULL;
}
@@ -2312,7 +2319,7 @@ pgf_complete(PgfConcr* concr, PgfType* type, GuString sentence,
while (ps->before->end_offset < len) {
if (!pgf_parsing_proceed(ps)) {
GuExnData* exn = gu_raise(err, PgfParseError);
- exn->data = (void*) pgf_parsing_last_token(ps, exn->pool);
+ exn->data = (void*) pgf_parsing_new_exception(ps, exn->pool);
return NULL;
}
diff --git a/src/runtime/c/pgf/pgf.h b/src/runtime/c/pgf/pgf.h
index 632a1d332..e6c1c70b8 100644
--- a/src/runtime/c/pgf/pgf.h
+++ b/src/runtime/c/pgf/pgf.h
@@ -122,6 +122,13 @@ PGF_API_DECL PgfExprEnum*
pgf_generate_all(PgfPGF* pgf, PgfType* ty,
GuExn* err, GuPool* pool, GuPool* out_pool);
+typedef struct {
+ int incomplete; // equal to !=0 if the sentence is incomplete, 0 otherwise
+ size_t offset;
+ const char* token_ptr;
+ size_t token_len;
+} PgfParseError;
+
PGF_API_DECL PgfExprEnum*
pgf_parse(PgfConcr* concr, PgfType* typ, GuString sentence,
GuExn* err, GuPool* pool, GuPool* out_pool);