forked from GitHub/gf-core
now fully functional Java API for custom literals
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -5,14 +5,4 @@
|
||||
#include <pgf/data.h>
|
||||
#include <pgf/expr.h>
|
||||
|
||||
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_
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user