diff options
Diffstat (limited to 'src/runtime/java')
6 files changed, 271 insertions, 37 deletions
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, "<init>", "(J)V"); jobject jpool = (*env)->NewObject(env, pool_class, pool_constrId, p2l(pool)); - jmethodID constrId = (*env)->GetMethodID(env, clazz, "<init>", "(Lorg/grammaticalframework/pgf/Pool;Lorg/grammaticalframework/pgf/PGF;J)V"); + jmethodID constrId = (*env)->GetMethodID(env, clazz, "<init>", "(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); } |
