From 1ca09448f9032b92ef436f4e0f658309d60e7ffd Mon Sep 17 00:00:00 2001 From: "kr.angelov" Date: Thu, 10 Apr 2014 14:14:31 +0000 Subject: now fully functional Java API for custom literals --- src/runtime/c/pgf/data.h | 8 +---- src/runtime/c/pgf/literals.c | 71 +++++++++++++++++++++---------------- src/runtime/c/pgf/parser.c | 53 ++++++++++++++++----------- src/runtime/c/pgf/parser.h | 10 ------ src/runtime/c/pgf/pgf.c | 32 +++++++++++++++++ src/runtime/c/pgf/pgf.h | 17 +++++++++ src/runtime/c/pgf/reader.c | 6 ++-- src/runtime/c/utils/pgf-translate.c | 4 +-- 8 files changed, 128 insertions(+), 73 deletions(-) (limited to 'src/runtime/c') diff --git a/src/runtime/c/pgf/data.h b/src/runtime/c/pgf/data.h index 6b1dd1780..d75b17f85 100644 --- a/src/runtime/c/pgf/data.h +++ b/src/runtime/c/pgf/data.h @@ -108,7 +108,7 @@ struct PgfPGF { PgfFlags* gflags; PgfAbstr abstract; PgfCIdMap* concretes; // |-> PgfConcr* - GuPool* pool; + GuPool* pool; // the pool in which the grammar is allocated }; typedef struct { @@ -203,12 +203,6 @@ typedef struct { typedef struct { } PgfSymbolBIND; -typedef struct { - PgfExprProb* (*match)(PgfConcr* concr, PgfSymbol* psym, size_t lin_idx, - GuString sentence, size_t* poffset, - GuPool *pool, GuPool *out_pool); -} PgfLiteralCallback; - typedef GuBuf PgfProductionIdx; typedef struct { diff --git a/src/runtime/c/pgf/literals.c b/src/runtime/c/pgf/literals.c index 89ddfdaf2..6b47aaf31 100644 --- a/src/runtime/c/pgf/literals.c +++ b/src/runtime/c/pgf/literals.c @@ -12,9 +12,10 @@ GU_DEFINE_TYPE(PgfCallbacksMap, GuMap, static PgfExprProb* -pgf_match_string_lit(PgfConcr* concr, PgfSymbol* psym, size_t lin_idx, +pgf_match_string_lit(PgfLiteralCallback* self, + size_t lin_idx, GuString sentence, size_t* poffset, - GuPool *pool, GuPool *out_pool) + GuPool *out_pool) { gu_assert(lin_idx == 0); @@ -40,7 +41,6 @@ pgf_match_string_lit(PgfConcr* concr, PgfSymbol* psym, size_t lin_idx, memcpy(lit_str->val, sentence+*poffset, len); lit_str->val[len] = 0; - pgf_add_extern_tok(psym, lit_str->val, pool); *poffset = offset; return ep; } else { @@ -54,9 +54,10 @@ static PgfLiteralCallback pgf_string_literal_callback = static PgfExprProb* -pgf_match_int_lit(PgfConcr* concr, PgfSymbol* psym, size_t lin_idx, +pgf_match_int_lit(PgfLiteralCallback* self, + size_t lin_idx, GuString sentence, size_t* poffset, - GuPool *pool, GuPool *out_pool) + GuPool *out_pool) { gu_assert(lin_idx == 0); @@ -66,28 +67,32 @@ pgf_match_int_lit(PgfConcr* concr, PgfSymbol* psym, size_t lin_idx, size_t len = offset - *poffset; if (len > 0) { - PgfToken tok = gu_malloc(pool, len+1); + GuPool* tmp_pool = gu_local_pool(); + PgfToken tok = gu_malloc(tmp_pool, len+1); memcpy((char*) tok, sentence+*poffset, len); ((char*) tok)[len] = 0; int val; - if (!gu_string_to_int(tok, &val)) + if (!gu_string_to_int(tok, &val)) { + gu_pool_free(tmp_pool); return NULL; + } + + gu_pool_free(tmp_pool); - PgfExprProb* ep = gu_new(PgfExprProb, pool); + PgfExprProb* ep = gu_new(PgfExprProb, out_pool); ep->prob = 0; PgfExprLit *expr_lit = gu_new_variant(PGF_EXPR_LIT, PgfExprLit, - &ep->expr, pool); + &ep->expr, out_pool); PgfLiteralInt *lit_int = gu_new_variant(PGF_LITERAL_INT, PgfLiteralInt, - &expr_lit->lit, pool); + &expr_lit->lit, out_pool); lit_int->val = val; - pgf_add_extern_tok(psym, tok, pool); *poffset = offset; return ep; } else { @@ -101,9 +106,10 @@ static PgfLiteralCallback pgf_int_literal_callback = static PgfExprProb* -pgf_match_float_lit(PgfConcr* concr, PgfSymbol* psym, size_t lin_idx, +pgf_match_float_lit(PgfLiteralCallback* self, + size_t lin_idx, GuString sentence, size_t* poffset, - GuPool *pool, GuPool *out_pool) + GuPool *out_pool) { gu_assert(lin_idx == 0); @@ -113,28 +119,32 @@ pgf_match_float_lit(PgfConcr* concr, PgfSymbol* psym, size_t lin_idx, size_t len = offset - *poffset; if (len > 0) { - PgfToken tok = gu_malloc(pool, len+1); + GuPool* tmp_pool = gu_local_pool(); + PgfToken tok = gu_malloc(tmp_pool, len+1); memcpy((char*) tok, sentence+*poffset, len); ((char*) tok)[len] = 0; double val; - if (!gu_string_to_double(tok, &val)) + if (!gu_string_to_double(tok, &val)) { + gu_pool_free(tmp_pool); return NULL; + } + + gu_pool_free(tmp_pool); - PgfExprProb* ep = gu_new(PgfExprProb, pool); + PgfExprProb* ep = gu_new(PgfExprProb, out_pool); ep->prob = 0; PgfExprLit *expr_lit = gu_new_variant(PGF_EXPR_LIT, PgfExprLit, - &ep->expr, pool); + &ep->expr, out_pool); PgfLiteralFlt *lit_flt = gu_new_variant(PGF_LITERAL_FLT, PgfLiteralFlt, - &expr_lit->lit, pool); + &expr_lit->lit, out_pool); lit_flt->val = val; - pgf_add_extern_tok(psym, tok, pool); *poffset = offset; return ep; } else { @@ -148,13 +158,14 @@ static PgfLiteralCallback pgf_float_literal_callback = static PgfExprProb* -pgf_match_name_lit(PgfConcr* concr, PgfSymbol* psym, size_t lin_idx, - GuString sentence, size_t* poffset, - GuPool *pool, GuPool *out_pool) +pgf_match_name_lit(PgfLiteralCallback* self, + size_t lin_idx, + GuString sentence, size_t* poffset, + GuPool *out_pool) { gu_assert(lin_idx == 0); - GuPool* tmp_pool = gu_new_pool(); + GuPool* tmp_pool = gu_local_pool(); GuStringBuf *sbuf = gu_string_buf(tmp_pool); GuOut* out = gu_string_buf_out(sbuf); GuExn* err = gu_new_exn(NULL, gu_kind(type), tmp_pool); @@ -168,12 +179,10 @@ pgf_match_name_lit(PgfConcr* concr, PgfSymbol* psym, size_t lin_idx, len++; } - PgfToken tok = gu_malloc(pool, len+1); + PgfToken tok = gu_malloc(tmp_pool, len+1); memcpy((char*) tok, sentence+offset, len); ((char*) tok)[len] = 0; - pgf_add_extern_tok(psym, tok, pool); - if (i > 0) gu_putc(' ', out, err); gu_string_write(tok, out, err); @@ -189,30 +198,30 @@ pgf_match_name_lit(PgfConcr* concr, PgfSymbol* psym, size_t lin_idx, PgfExprProb* ep = NULL; if (i > 0) { - ep = gu_new(PgfExprProb, pool); + ep = gu_new(PgfExprProb, out_pool); ep->prob = 0; PgfExprApp *expr_app = gu_new_variant(PGF_EXPR_APP, PgfExprApp, - &ep->expr, pool); + &ep->expr, out_pool); GuString con = "MkSymb"; PgfExprFun *expr_fun = gu_new_flex_variant(PGF_EXPR_FUN, PgfExprFun, fun, strlen(con)+1, - &expr_app->fun, pool); + &expr_app->fun, out_pool); strcpy(expr_fun->fun, con); PgfExprLit *expr_lit = gu_new_variant(PGF_EXPR_LIT, PgfExprLit, - &expr_app->arg, pool); + &expr_app->arg, out_pool); GuString val = gu_string_buf_freeze(sbuf, tmp_pool); PgfLiteralStr *lit_str = gu_new_flex_variant(PGF_LITERAL_STR, PgfLiteralStr, val, strlen(val)+1, - &expr_lit->lit, pool); + &expr_lit->lit, out_pool); strcpy(lit_str->val, val); } diff --git a/src/runtime/c/pgf/parser.c b/src/runtime/c/pgf/parser.c index ee2d13415..f944bc88d 100644 --- a/src/runtime/c/pgf/parser.c +++ b/src/runtime/c/pgf/parser.c @@ -155,7 +155,7 @@ pgf_prev_extern_sym(PgfSymbol sym) } } -void +static void pgf_add_extern_tok(PgfSymbol* psym, PgfToken tok, GuPool* pool) { PgfSymbol new_sym; size_t tok_len = strlen(tok); @@ -169,7 +169,7 @@ pgf_add_extern_tok(PgfSymbol* psym, PgfToken tok, GuPool* pool) { *psym = new_sym; } -void +static void pgf_add_extern_cat(PgfSymbol* psym, int d, int r, GuPool* pool) { PgfSymbol new_sym; PgfSymbolCat* scat = (PgfSymbolCat*) @@ -183,6 +183,32 @@ pgf_add_extern_cat(PgfSymbol* psym, int d, int r, GuPool* pool) { *psym = new_sym; } +PgfSymbol +pgf_collect_extern_tok(PgfParsing* ps, size_t start, size_t end) +{ + PgfSymbol sym = gu_null_variant; + + size_t offset = start; + while (offset < end) { + size_t len = 0; + while (!gu_is_space(ps->sentence[offset+len])) { + len++; + } + + PgfToken tok = gu_malloc(ps->pool, len+1); + memcpy((char*) tok, ps->sentence+offset, len); + ((char*) tok)[len] = 0; + + pgf_add_extern_tok(&sym, tok, ps->pool); + + offset += len; + while (gu_is_space(ps->sentence[offset])) + offset++; + } + + return sym; +} + static size_t pgf_item_symbols_length(PgfItem* item) { @@ -1581,13 +1607,13 @@ pgf_parsing_symbol(PgfParsing* ps, PgfItem* item, PgfSymbol sym) PgfLiteralCallback*); if (callback != NULL) { - size_t offset = ps->before->end_offset; - PgfSymbol curr_sym = gu_null_variant; + size_t start = ps->before->end_offset; + size_t offset = start; PgfExprProb *ep = - callback->match(ps->concr, &curr_sym, + callback->match(callback, slit->r, ps->sentence, &offset, - ps->pool, ps->out_pool); + ps->out_pool); if (ep != NULL) { PgfProduction prod; @@ -1602,7 +1628,7 @@ pgf_parsing_symbol(PgfParsing* ps, PgfItem* item, PgfSymbol sym) pgf_new_parse_state(ps, offset, BIND_NONE); PgfItem* item = pgf_new_item(ps, conts, prod); - item->curr_sym = curr_sym; + item->curr_sym = pgf_collect_extern_tok(ps,start,offset); item->sym_idx = pgf_item_symbols_length(item); gu_buf_heap_push(state->agenda, pgf_item_prob_order, &item); } @@ -2506,19 +2532,6 @@ pgf_complete(PgfConcr* concr, PgfCId cat, GuString sentence, return pgf_parsing_completions(ps, prefix); } -void -pgf_parser_add_literal(PgfConcr *concr, PgfCId cat, - PgfLiteralCallback* callback) -{ - PgfCncCat* cnccat = - gu_map_get(concr->cnccats, cat, PgfCncCat*); - if (cnccat == NULL) - return; - - gu_map_put(concr->callbacks, cnccat, - PgfLiteralCallback*, callback); -} - static void pgf_morpho_iter(PgfProductionIdx* idx, PgfMorphoCallback* callback, diff --git a/src/runtime/c/pgf/parser.h b/src/runtime/c/pgf/parser.h index 93addbf7f..afe443042 100644 --- a/src/runtime/c/pgf/parser.h +++ b/src/runtime/c/pgf/parser.h @@ -5,14 +5,4 @@ #include #include -void -pgf_add_extern_tok(PgfSymbol* psym, PgfToken tok, GuPool* pool); - -void -pgf_add_extern_cat(PgfSymbol* psym, int d, int r, GuPool* pool); - -void -pgf_parser_add_literal(PgfConcr *concr, PgfCId cat, - PgfLiteralCallback* callback); - #endif // PGF_PARSER_H_ diff --git a/src/runtime/c/pgf/pgf.c b/src/runtime/c/pgf/pgf.c index 155b93135..ee736616c 100644 --- a/src/runtime/c/pgf/pgf.c +++ b/src/runtime/c/pgf/pgf.c @@ -166,3 +166,35 @@ pgf_has_linearization(PgfConcr* concr, PgfCId id) gu_map_get(concr->fun_indices, id, PgfCncOverloadMap*); return (overl_table != NULL); } + +GuPool* +pgf_concr_get_pool(PgfConcr* concr) +{ + GuPool* pool = concr->pool; + if (pool == NULL) + pool = gu_container(concr->abstr, PgfPGF, abstract)->pool; + return pool; +} + +void +pgf_concr_add_literal(PgfConcr *concr, PgfCId cat, + PgfLiteralCallback* callback, + GuExn* err) +{ + if (concr->cnccats == NULL || + concr->callbacks == NULL) { + GuExnData* err_data = gu_raise(err, PgfExn); + if (err_data) { + err_data->data = "The concrete syntax is not loaded"; + return; + } + } + + PgfCncCat* cnccat = + gu_map_get(concr->cnccats, cat, PgfCncCat*); + if (cnccat == NULL) + return; + + gu_map_put(concr->callbacks, cnccat, + PgfLiteralCallback*, callback); +} diff --git a/src/runtime/c/pgf/pgf.h b/src/runtime/c/pgf/pgf.h index 87ca3ae28..d8c364b56 100644 --- a/src/runtime/c/pgf/pgf.h +++ b/src/runtime/c/pgf/pgf.h @@ -151,6 +151,23 @@ GuEnum* pgf_complete(PgfConcr* concr, PgfCId cat, GuString string, GuString prefix, GuExn* err, GuPool* pool); +GuPool* +pgf_concr_get_pool(PgfConcr* concr); + +typedef struct PgfLiteralCallback PgfLiteralCallback; + +struct PgfLiteralCallback { + PgfExprProb* (*match)(PgfLiteralCallback* self, + size_t lin_idx, + GuString sentence, size_t* poffset, + GuPool *out_pool); +}; + +void +pgf_concr_add_literal(PgfConcr *concr, PgfCId cat, + PgfLiteralCallback* callback, + GuExn* err); + /// @} void diff --git a/src/runtime/c/pgf/reader.c b/src/runtime/c/pgf/reader.c index 2dd1e73b3..afbd42242 100644 --- a/src/runtime/c/pgf/reader.c +++ b/src/runtime/c/pgf/reader.c @@ -1243,8 +1243,6 @@ pgf_read_concrete(PgfReader* rdr, PgfAbstr* abstr, bool with_content) } gu_return_on_exn(rdr->err, NULL); - pgf_parser_add_literal(concr, "Symb", &pgf_nerc_literal_callback); - return concr; } @@ -1283,7 +1281,7 @@ pgf_concrete_load(PgfConcr* concr, GuIn* in, GuExn* err) if (gu_exn_is_raised(rdr->err)) goto end; -end: +end: gu_pool_free(tmp_pool); } @@ -1338,6 +1336,8 @@ pgf_read_pgf(PgfReader* rdr) { gu_variant_is_null(gu_map_get(pgf->gflags, "split", PgfLiteral)); pgf->concretes = pgf_read_concretes(rdr, &pgf->abstract, with_content); gu_return_on_exn(rdr->err, NULL); + + pgf->pool = rdr->opool; return pgf; } diff --git a/src/runtime/c/utils/pgf-translate.c b/src/runtime/c/utils/pgf-translate.c index 79420cf49..fbc6e553e 100644 --- a/src/runtime/c/utils/pgf-translate.c +++ b/src/runtime/c/utils/pgf-translate.c @@ -88,8 +88,8 @@ int main(int argc, char* argv[]) { } // Register a callback for the literal category Symbol - pgf_parser_add_literal(from_concr, "Symb", - &pgf_nerc_literal_callback); + pgf_concr_add_literal(from_concr, "Symb", + &pgf_nerc_literal_callback, err); // Create an output stream for stdout GuOut* out = gu_file_out(stdout, pool); -- cgit v1.2.3