From a9ebeaea449924155cbc55e784e9348b4a3a9d80 Mon Sep 17 00:00:00 2001 From: "kr.angelov" Date: Thu, 10 Apr 2014 14:14:31 +0000 Subject: [PATCH] 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 +- src/runtime/java/jpgf.c | 188 +++++++++++++++++- .../org/grammaticalframework/pgf/Expr.java | 34 +++- .../grammaticalframework/pgf/ExprBuilder.java | 16 -- .../pgf/LiteralCallback.java | 20 +- .../pgf/NercLiteralCallback.java | 33 ++- .../org/grammaticalframework/pgf/Pool.java | 17 +- 14 files changed, 399 insertions(+), 110 deletions(-) delete mode 100644 src/runtime/java/org/grammaticalframework/pgf/ExprBuilder.java 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); diff --git a/src/runtime/java/jpgf.c b/src/runtime/java/jpgf.c index 2a92aa0c6..7de1d9516 100644 --- a/src/runtime/java/jpgf.c +++ b/src/runtime/java/jpgf.c @@ -75,6 +75,14 @@ throw_string_exception(JNIEnv *env, const char* class_name, const char* msg) throw_jstring_exception(env, class_name, jmsg); } +static JavaVM* cachedJVM; + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) +{ + cachedJVM = jvm; + return JNI_VERSION_1_1; +} + JNIEXPORT jobject JNICALL Java_org_grammaticalframework_pgf_PGF_readPGF__Ljava_lang_String_2(JNIEnv *env, jclass cls, jstring s) { @@ -645,15 +653,135 @@ JNIEXPORT jboolean JNICALL Java_org_grammaticalframework_pgf_Concr_hasLinearization(JNIEnv* env, jobject self, jstring jid) { PgfConcr* concr = get_ref(env, self); - GuPool* tmp_pool = gu_new_pool(); + GuPool* tmp_pool = gu_local_pool(); PgfCId id = j2gu_string(env, jid, tmp_pool); bool res = pgf_has_linearization(concr, id); gu_pool_free(tmp_pool); return res; } +typedef struct { + PgfLiteralCallback callback; + jobject jcallback; + jmethodID match_methodId; + GuFinalizer fin; +} JPgfLiteralCallback; + +static PgfExprProb* +jpgf_literal_callback_fn(PgfLiteralCallback* self, + size_t lin_idx, + GuString sentence, size_t* poffset, + GuPool *out_pool) +{ + JPgfLiteralCallback* callback = gu_container(self, JPgfLiteralCallback, callback); + + JNIEnv *env; + (*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL); + + jstring jsentence = gu2j_string(env, sentence); + jobject result = (*env)->CallObjectMethod(env, callback->jcallback, callback->match_methodId, lin_idx, jsentence, *poffset); + + jclass result_class = (*env)->GetObjectClass(env, result); + + jfieldID epId = (*env)->GetFieldID(env, result_class, "ep", "Lorg/grammaticalframework/pgf/ExprProb;"); + jobject jep = (*env)->GetObjectField(env, result, epId); + jclass ep_class = (*env)->GetObjectClass(env, jep); + jfieldID exprId = (*env)->GetFieldID(env, ep_class, "expr", "Lorg/grammaticalframework/pgf/Expr;"); + jobject jexpr = (*env)->GetObjectField(env, jep, exprId); + jfieldID probId = (*env)->GetFieldID(env, ep_class, "prob", "D"); + double prob = (*env)->GetDoubleField(env, jep, probId); + + jfieldID offsetId = (*env)->GetFieldID(env, result_class, "offset", "I"); + *poffset = (*env)->GetIntField(env, result, offsetId); + + PgfExprProb* ep = gu_new(PgfExprProb, out_pool); + ep->expr = gu_variant_from_ptr(get_ref(env, jexpr)); + ep->prob = prob; + + + { + // This is an uggly hack. We first show the expression ep->expr + // and then we read it back but in out_pool. The whole purpose + // of this is to copy the expression from the temporary pool + // that was created in the Java binding to the parser pool. + // There should be a real copying function or even better + // there must be a way to avoid copying at all. + + GuPool* tmp_pool = gu_local_pool(); + + GuExn* err = gu_new_exn(NULL, gu_kind(type), tmp_pool); + GuStringBuf* sbuf = gu_string_buf(tmp_pool); + GuOut* out = gu_string_buf_out(sbuf); + + pgf_print_expr(ep->expr, NULL, 0, out, err); + + GuString str = gu_string_buf_freeze(sbuf, tmp_pool); + GuIn* in = gu_data_in((uint8_t*) str, strlen(str), tmp_pool); + + ep->expr = pgf_read_expr(in, out_pool, err); + if (!gu_ok(err) || gu_variant_is_null(ep->expr)) { + throw_string_exception(env, "org/grammaticalframework/pgf/PGFError", "The expression cannot be parsed"); + gu_pool_free(tmp_pool); + return NULL; + } + + gu_pool_free(tmp_pool); + } + + return ep; +} + +static void +jpgf_literal_callback_fin(GuFinalizer* self) +{ + JPgfLiteralCallback* callback = gu_container(self, JPgfLiteralCallback, fin); + + JNIEnv *env; + (*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL); + + (*env)->DeleteGlobalRef(env, callback->jcallback); +} + JNIEXPORT void JNICALL -Java_org_grammaticalframework_pgf_Pool_free(JNIEnv* env, jobject self, jlong ref) +Java_org_grammaticalframework_pgf_Concr_addLiteral(JNIEnv* env, jobject self, jstring jcat, jobject jcallback) +{ + PgfConcr* concr = get_ref(env, self); + GuPool* pool = pgf_concr_get_pool(concr); + + JPgfLiteralCallback* callback = gu_new(JPgfLiteralCallback, pool); + callback->callback.match = jpgf_literal_callback_fn; + callback->jcallback = (*env)->NewGlobalRef(env, jcallback); + callback->fin.fn = jpgf_literal_callback_fin; + + jclass callback_class = (*env)->GetObjectClass(env, jcallback); + callback->match_methodId = (*env)->GetMethodID(env, callback_class, "match", "(ILjava/lang/String;I)Lorg/grammaticalframework/pgf/LiteralCallback$CallbackResult;"); + + gu_pool_finally(pool, &callback->fin); + + GuPool* tmp_pool = gu_local_pool(); + GuExn* err = gu_new_exn(NULL, gu_kind(type), tmp_pool); + pgf_concr_add_literal(concr, j2gu_string(env, jcat, tmp_pool), &callback->callback, err); + + if (!gu_ok(err)) { + if (gu_exn_caught(err) == gu_type(PgfExn)) { + GuString msg = (GuString) gu_exn_caught_data(err); + throw_string_exception(env, "org/grammaticalframework/pgf/PGFError", msg); + } else { + throw_string_exception(env, "org/grammaticalframework/pgf/PGFError", "The literal cannot be added"); + } + } + + gu_pool_free(tmp_pool); +} + +JNIEXPORT jlong JNICALL +Java_org_grammaticalframework_pgf_Pool_alloc(JNIEnv* env, jclass clazz) +{ + return p2l(gu_new_pool()); +} + +JNIEXPORT void JNICALL +Java_org_grammaticalframework_pgf_Pool_free(JNIEnv* env, jclass clazz, jlong ref) { gu_pool_free((GuPool*) l2p(ref)); } @@ -700,10 +828,64 @@ Java_org_grammaticalframework_pgf_Expr_readExpr(JNIEnv* env, jclass clazz, jstri jmethodID pool_constrId = (*env)->GetMethodID(env, pool_class, "", "(J)V"); jobject jpool = (*env)->NewObject(env, pool_class, pool_constrId, p2l(pool)); - jmethodID constrId = (*env)->GetMethodID(env, clazz, "", "(Lorg/grammaticalframework/pgf/Pool;Lorg/grammaticalframework/pgf/PGF;J)V"); + jmethodID constrId = (*env)->GetMethodID(env, clazz, "", "(Lorg/grammaticalframework/pgf/Pool;Ljava/lang/Object;J)V"); return (*env)->NewObject(env, clazz, constrId, jpool, NULL, p2l(gu_variant_to_ptr(e))); } +JNIEXPORT jlong JNICALL +Java_org_grammaticalframework_pgf_Expr_initStringLit(JNIEnv* env, jclass clazz, jstring jstr, jlong jpool) +{ + GuPool* pool = l2p(jpool); + PgfExpr expr; + + PgfExprLit* e = + gu_new_variant(PGF_EXPR_LIT, + PgfExprLit, + &expr, pool); + + GuString str = (*env)->GetStringUTFChars(env, jstr, 0); + PgfLiteralStr* slit = + gu_new_flex_variant(PGF_LITERAL_STR, + PgfLiteralStr, + val, strlen(str)+1, + &e->lit, pool); + strcpy(slit->val, str); + (*env)->ReleaseStringUTFChars(env, jstr, str); + + return expr; +} + +JNIEXPORT jlong JNICALL +Java_org_grammaticalframework_pgf_Expr_initApp(JNIEnv* env, jclass clazz, jstring jfun, jobjectArray args, jlong jpool) +{ + GuPool* pool = l2p(jpool); + PgfExpr expr; + + GuString fun = (*env)->GetStringUTFChars(env, jfun, 0); + PgfExprFun* e = + gu_new_flex_variant(PGF_EXPR_FUN, + PgfExprFun, + fun, strlen(fun)+1, + &expr, pool); + strcpy(e->fun, fun); + (*env)->ReleaseStringUTFChars(env, jfun, fun); + + size_t n_args = (*env)->GetArrayLength(env, args); + for (size_t i = 0; i < n_args; i++) { + PgfExpr fun = expr; + PgfExpr arg = gu_variant_from_ptr(get_ref(env, (*env)->GetObjectArrayElement(env, args, i))); + + PgfExprApp* e = + gu_new_variant(PGF_EXPR_APP, + PgfExprApp, + &expr, pool); + e->fun = fun; + e->arg = arg; + } + + return expr; +} + JNIEXPORT jstring JNICALL Java_org_grammaticalframework_pgf_Type_getCategory(JNIEnv* env, jobject self) { diff --git a/src/runtime/java/org/grammaticalframework/pgf/Expr.java b/src/runtime/java/org/grammaticalframework/pgf/Expr.java index ca94d0cf7..753055ff9 100644 --- a/src/runtime/java/org/grammaticalframework/pgf/Expr.java +++ b/src/runtime/java/org/grammaticalframework/pgf/Expr.java @@ -4,18 +4,31 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; +import java.util.Arrays; public class Expr implements Serializable { private static final long serialVersionUID = 1148602474802492674L; private Pool pool; - private PGF gr; + private Object master; private long ref; - Expr(Pool pool, PGF gr, long ref) { - this.pool = pool; - this.gr = gr; - this.ref = ref; + Expr(Pool pool, Object master, long ref) { + this.pool = pool; + this.master = master; + this.ref = ref; + } + + public Expr(String s) { + this.pool = new Pool(); + this.master = null; + this.ref = initStringLit(s, pool.ref); + } + + public Expr(String fun, Expr... args) { + this.pool = new Pool(); + this.master = Arrays.copyOf(args, args.length); + this.ref = initApp(fun, args, pool.ref); } public String toString() { @@ -25,15 +38,18 @@ public class Expr implements Serializable { public static native Expr readExpr(String s) throws PGFError; private static native String showExpr(long ref); - + + private static native long initStringLit(String s, long pool); + private static native long initApp(String fun, Expr[] args, long pool); + private void writeObject(ObjectOutputStream out) throws IOException { out.writeObject(showExpr(ref)); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { Expr e = readExpr((String) in.readObject()); - pool = e.pool; - gr = e.gr; - ref = e.ref; + pool = e.pool; + master = e.master; + ref = e.ref; } } diff --git a/src/runtime/java/org/grammaticalframework/pgf/ExprBuilder.java b/src/runtime/java/org/grammaticalframework/pgf/ExprBuilder.java deleted file mode 100644 index a34a6c19d..000000000 --- a/src/runtime/java/org/grammaticalframework/pgf/ExprBuilder.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.grammaticalframework.pgf; - -public class ExprBuilder { - public ExprBuilder() { - - } - - ExprBuilder(long poolRef) { - } - - public native Expr mkApp(String fun, Expr... args); - - public native Expr mkLiteral(String s); - public native Expr mkLiteral(int n); - public native Expr mkLiteral(double d); -} diff --git a/src/runtime/java/org/grammaticalframework/pgf/LiteralCallback.java b/src/runtime/java/org/grammaticalframework/pgf/LiteralCallback.java index 4292a4116..87e832ae2 100644 --- a/src/runtime/java/org/grammaticalframework/pgf/LiteralCallback.java +++ b/src/runtime/java/org/grammaticalframework/pgf/LiteralCallback.java @@ -1,5 +1,23 @@ package org.grammaticalframework.pgf; public interface LiteralCallback { - public int match(Concr concr, int lin_idx, ExprBuilder builder, String sentence, int start_offset); + public CallbackResult match(int lin_idx, String sentence, int start_offset); + + public static class CallbackResult { + private ExprProb ep; + private int offset; + + public CallbackResult(ExprProb ep, int offset) { + this.ep = ep; + this.offset = offset; + } + + public ExprProb getExprProb() { + return ep; + } + + public int getOffset() { + return offset; + } + } } diff --git a/src/runtime/java/org/grammaticalframework/pgf/NercLiteralCallback.java b/src/runtime/java/org/grammaticalframework/pgf/NercLiteralCallback.java index ad1036c56..72f24e712 100644 --- a/src/runtime/java/org/grammaticalframework/pgf/NercLiteralCallback.java +++ b/src/runtime/java/org/grammaticalframework/pgf/NercLiteralCallback.java @@ -1,7 +1,36 @@ package org.grammaticalframework.pgf; public class NercLiteralCallback implements LiteralCallback { - public int match(Concr concr, int lin_idx, ExprBuilder builder, String sentence, int start_offset) { - return start_offset; + public CallbackResult match(int lin_idx, String sentence, int offset) { + StringBuilder sbuilder = new StringBuilder(); + + int i = 0; + int end_offset = offset; + while (offset < sentence.length() && + Character.isUpperCase(sentence.charAt(offset))) { + if (i > 0) + sbuilder.append(' '); + i++; + + while (offset < sentence.length() && + !Character.isWhitespace(sentence.charAt(offset))) { + sbuilder.append(sentence.charAt(offset)); + offset++; + } + + end_offset = offset; + while (offset < sentence.length() && + Character.isWhitespace(sentence.charAt(offset))) { + offset++; + } + } + + if (i > 0) { + Expr expr = new Expr(sbuilder.toString()); + expr = new Expr("MkSymb", expr); + return new CallbackResult(new ExprProb(expr, 0), end_offset); + } + + return null; } } diff --git a/src/runtime/java/org/grammaticalframework/pgf/Pool.java b/src/runtime/java/org/grammaticalframework/pgf/Pool.java index 68a690871..3a39babdf 100644 --- a/src/runtime/java/org/grammaticalframework/pgf/Pool.java +++ b/src/runtime/java/org/grammaticalframework/pgf/Pool.java @@ -1,15 +1,20 @@ package org.grammaticalframework.pgf; -class Pool { - private long ref; - +public class Pool { + final long ref; + public Pool(long ref) { this.ref = ref; } - + + public Pool() { + this.ref = alloc(); + } + public void finalize() { free(ref); } - - private native void free(long ref); + + public static native long alloc(); + public static native void free(long ref); }