From d3631d918df56969aba8fe42ec0b6876da0fd80e Mon Sep 17 00:00:00 2001 From: "kr.angelov" Date: Tue, 27 Aug 2013 21:53:13 +0000 Subject: [PATCH] parsing from the Java binding --- src/runtime/java/Test.java | 4 + src/runtime/java/jpgf.c | 133 +++++++++++++++--- .../org/grammaticalframework/pgf/Concr.java | 8 +- .../org/grammaticalframework/pgf/Expr.java | 13 ++ .../pgf/ExprIterator.java | 45 ++++++ .../grammaticalframework/pgf/ExprProb.java | 4 + .../org/grammaticalframework/pgf/Parser.java | 25 ++++ .../org/grammaticalframework/pgf/Pool.java | 15 ++ 8 files changed, 223 insertions(+), 24 deletions(-) create mode 100644 src/runtime/java/org/grammaticalframework/pgf/ExprIterator.java create mode 100644 src/runtime/java/org/grammaticalframework/pgf/Parser.java create mode 100644 src/runtime/java/org/grammaticalframework/pgf/Pool.java diff --git a/src/runtime/java/Test.java b/src/runtime/java/Test.java index 27cf18da2..d565e294f 100644 --- a/src/runtime/java/Test.java +++ b/src/runtime/java/Test.java @@ -19,5 +19,9 @@ public class Test { for (Map.Entry entry : gr.getLanguages().entrySet()) { System.out.println(entry.getKey()+" "+entry.getValue()+" "+entry.getValue().getName()); } + + for (ExprProb ep : gr.getLanguages().get("ParseEng").parse("Phr", "test")) { + System.out.println("["+ep.getProb()+"] "+ep.getExpr()); + } } } diff --git a/src/runtime/java/jpgf.c b/src/runtime/java/jpgf.c index 353be6023..3f3217ed1 100644 --- a/src/runtime/java/jpgf.c +++ b/src/runtime/java/jpgf.c @@ -45,6 +45,12 @@ gu2j_string(JNIEnv *env, GuString s) { return (*env)->NewString(env, utf16, dst-utf16); } +static GuString +j2gu_string(JNIEnv *env, jstring s, GuPool* pool) { + const char *str = (*env)->GetStringUTFChars(env, s, 0); + return gu_str_string(str, pool); +} + static PgfPGF* get_pgf(JNIEnv *env, jobject self) { jfieldID grId = (*env)->GetFieldID(env, (*env)->GetObjectClass(env, self), "gr", "J"); @@ -57,6 +63,30 @@ get_concr(JNIEnv *env, jobject self) { return (PgfPGF*) (*env)->GetLongField(env, self, concrId); } +static void +throw_jstring_exception(JNIEnv *env, const char* class_name, jstring msg) +{ + jclass exception_class = (*env)->FindClass(env, class_name); + if (!exception_class) + return NULL; + jmethodID constrId = (*env)->GetMethodID(env, exception_class, "", "(Ljava/lang/String;)V"); + if (!constrId) + return NULL; + jobject exception = (*env)->NewObject(env, exception_class, constrId, msg); + if (!exception) + return NULL; + (*env)->Throw(env, exception); +} + +static void +throw_string_exception(JNIEnv *env, const char* class_name, const char* msg) +{ + jstring jmsg = (*env)->NewStringUTF(env, msg); + if (!jmsg) + return NULL; + throw_jstring_exception(env, class_name, jmsg); +} + JNIEXPORT jobject JNICALL Java_org_grammaticalframework_pgf_PGF_readPGF(JNIEnv *env, jclass cls, jstring s) { @@ -75,30 +105,9 @@ Java_org_grammaticalframework_pgf_PGF_readPGF(JNIEnv *env, jclass cls, jstring s if (!gu_ok(err)) { if (gu_exn_caught(err) == gu_type(GuErrno)) { - jclass exception_class = (*env)->FindClass(env, "java/io/FileNotFoundException"); - if (!exception_class) - return NULL; - jmethodID constrId = (*env)->GetMethodID(env, exception_class, "", "(Ljava/lang/String;)V"); - if (!constrId) - return NULL; - jobject exception = (*env)->NewObject(env, exception_class, constrId, s); - if (!exception) - return NULL; - (*env)->Throw(env, exception); + throw_jstring_exception(env, "java/io/FileNotFoundException", s); } else { - jclass exception_class = (*env)->FindClass(env, "org/grammaticalframework/PGFError"); - if (!exception_class) - return NULL; - jmethodID constrId = (*env)->GetMethodID(env, exception_class, "", "(Ljava/lang/String;)V"); - if (!constrId) - return NULL; - jstring msg = (*env)->NewStringUTF(env, "The grammar cannot be loaded"); - if (!msg) - return NULL; - jobject exception = (*env)->NewObject(env, exception_class, constrId, msg); - if (!exception) - return NULL; - (*env)->Throw(env, exception); + throw_string_exception(env, "org/grammaticalframework/PGFError", "The grammar cannot be loaded"); } gu_pool_free(pool); gu_pool_free(tmp_pool); @@ -186,3 +195,81 @@ Java_org_grammaticalframework_pgf_Concr_getName(JNIEnv* env, jobject self) { return gu2j_string(env, pgf_concrete_name(get_concr(env, self))); } + +JNIEXPORT jobject JNICALL +Java_org_grammaticalframework_pgf_Parser_parse + (JNIEnv* env, jclass self, jobject concr, jstring jstartCat, jstring js) +{ + GuPool* pool = gu_new_pool(); + GuPool* out_pool = gu_new_pool(); + + GuString startCat = j2gu_string(env, jstartCat, pool); + GuString s = j2gu_string(env, js, pool); + + GuReader* rdr = gu_string_reader(s, pool); + PgfLexer *lexer = pgf_new_simple_lexer(rdr, pool); + + GuEnum* res = + pgf_parse(get_concr(env, concr), startCat, lexer, pool, out_pool); + + if (res == NULL) { + PgfToken tok = + pgf_lexer_current_token(lexer); + + if (gu_string_eq(tok, gu_empty_string)) + throw_string_exception(env, "org/grammaticalframework/PGFError", "The sentence cannot be parsed"); + else + throw_jstring_exception(env, "org/grammaticalframework/ParseError", gu2j_string(env, tok)); + + gu_pool_free(pool); + gu_pool_free(out_pool); + } + + jclass expiter_class = (*env)->FindClass(env, "org/grammaticalframework/pgf/ExprIterator"); + jmethodID constrId = (*env)->GetMethodID(env, expiter_class, "", "(JJJ)V"); + jobject jexpiter = (*env)->NewObject(env, expiter_class, constrId, (jlong) pool, (jlong) out_pool, (jlong) res); + + return jexpiter; +} + +JNIEXPORT jobject JNICALL +Java_org_grammaticalframework_pgf_ExprIterator_fetchExprProb + (JNIEnv* env, jobject self, jlong enumRef, jobject out_pool) +{ + GuEnum* res = (GuEnum*) enumRef; + + PgfExprProb* ep = gu_next(res, PgfExprProb*, NULL); + if (ep == NULL) + return NULL; + + jclass expprob_class = (*env)->FindClass(env, "org/grammaticalframework/pgf/ExprProb"); + jmethodID methodId = (*env)->GetStaticMethodID(env, expprob_class, "mkExprProb", "(Lorg/grammaticalframework/pgf/Pool;JD)Lorg/grammaticalframework/pgf/ExprProb;"); + jobject jexpprob = (*env)->CallStaticObjectMethod(env, expprob_class, methodId, + out_pool, (jlong) gu_variant_to_ptr(ep->expr), (double) ep->prob); + + return jexpprob; +} + +JNIEXPORT void JNICALL +Java_org_grammaticalframework_pgf_Pool_free(JNIEnv* env, jobject self, jlong ref) +{ + gu_pool_free((GuPool*) ref); +} + +JNIEXPORT jstring JNICALL +Java_org_grammaticalframework_pgf_Expr_showExpr(JNIEnv* env, jclass clazz, jlong ref) +{ + GuPool* tmp_pool = gu_local_pool(); + + GuExn* err = gu_new_exn(NULL, gu_kind(type), tmp_pool); + GuStringBuf* sbuf = gu_string_buf(tmp_pool); + GuWriter* wtr = gu_string_buf_writer(sbuf); + + pgf_print_expr(gu_variant_from_ptr(ref), NULL, 0, wtr, err); + + GuString str = gu_string_buf_freeze(sbuf, tmp_pool); + jstring jstr = gu2j_string(env, str); + + gu_pool_free(tmp_pool); + return jstr; +} diff --git a/src/runtime/java/org/grammaticalframework/pgf/Concr.java b/src/runtime/java/org/grammaticalframework/pgf/Concr.java index 095c009ba..0f91539a0 100644 --- a/src/runtime/java/org/grammaticalframework/pgf/Concr.java +++ b/src/runtime/java/org/grammaticalframework/pgf/Concr.java @@ -1,14 +1,20 @@ package org.grammaticalframework.pgf; +import java.util.*; + public class Concr { public native String getName(); + + public Iterable parse(String startCat, String s) { + return new Parser(this, startCat, s); + } ////////////////////////////////////////////////////////////////// // private stuff private PGF gr; - private long concr; + public long concr; private Concr(PGF gr, long concr) { this.gr = gr; diff --git a/src/runtime/java/org/grammaticalframework/pgf/Expr.java b/src/runtime/java/org/grammaticalframework/pgf/Expr.java index 6401ec6b9..947fdc1e2 100644 --- a/src/runtime/java/org/grammaticalframework/pgf/Expr.java +++ b/src/runtime/java/org/grammaticalframework/pgf/Expr.java @@ -1,4 +1,17 @@ package org.grammaticalframework.pgf; public class Expr { + private Pool pool; + private long ref; + + public Expr(Pool pool, long ref) { + this.pool = pool; + this.ref = ref; + } + + public String toString() { + return showExpr(ref); + } + + private static native String showExpr(long ref); } diff --git a/src/runtime/java/org/grammaticalframework/pgf/ExprIterator.java b/src/runtime/java/org/grammaticalframework/pgf/ExprIterator.java new file mode 100644 index 000000000..be90d07c5 --- /dev/null +++ b/src/runtime/java/org/grammaticalframework/pgf/ExprIterator.java @@ -0,0 +1,45 @@ +package org.grammaticalframework.pgf; + +import java.util.*; + +class ExprIterator implements Iterator { + private Pool pool, out_pool; + private long enumRef; + private ExprProb ep; + private boolean fetched; + + public ExprIterator(long pool, long out_pool, long enumRef) { + this.pool = new Pool(pool); + this.out_pool = new Pool(out_pool); + this.enumRef = enumRef; + this.ep = null; + this.fetched = false; + } + + private native ExprProb fetchExprProb(long enumRef, Pool out_pool); + + private void fetch() { + if (!fetched) { + ep = fetchExprProb(enumRef, out_pool); + fetched = true; + } + } + + public boolean hasNext() { + fetch(); + return (ep != null); + } + + public ExprProb next() { + fetch(); + fetched = false; + + if (ep == null) + throw new NoSuchElementException(); + return ep; + } + + public void remove() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/runtime/java/org/grammaticalframework/pgf/ExprProb.java b/src/runtime/java/org/grammaticalframework/pgf/ExprProb.java index fcfbdbc74..d7d4f1cdf 100644 --- a/src/runtime/java/org/grammaticalframework/pgf/ExprProb.java +++ b/src/runtime/java/org/grammaticalframework/pgf/ExprProb.java @@ -9,6 +9,10 @@ public class ExprProb { this.prob = prob; } + private static ExprProb mkExprProb(Pool pool, long expr, double prob) { + return new ExprProb(new Expr(pool, expr), prob); + } + public Expr getExpr() { return expr; } diff --git a/src/runtime/java/org/grammaticalframework/pgf/Parser.java b/src/runtime/java/org/grammaticalframework/pgf/Parser.java new file mode 100644 index 000000000..5e068b2e3 --- /dev/null +++ b/src/runtime/java/org/grammaticalframework/pgf/Parser.java @@ -0,0 +1,25 @@ +package org.grammaticalframework.pgf; + +import java.util.*; + +class Parser implements Iterable { + private Concr concr; + private String s; + private String startCat; + + public Parser(Concr concr, String startCat, String s) { + this.concr = concr; + this.startCat = startCat; + this.s = s; + } + + public Iterator iterator() { + ExprIterator iter = parse(concr, startCat, s); + if (iter == null) { + throw new PGFError("The sentence cannot be parsed"); + } + return iter; + } + + public static native ExprIterator parse(Concr concr, String startCat, String s); +} diff --git a/src/runtime/java/org/grammaticalframework/pgf/Pool.java b/src/runtime/java/org/grammaticalframework/pgf/Pool.java new file mode 100644 index 000000000..68a690871 --- /dev/null +++ b/src/runtime/java/org/grammaticalframework/pgf/Pool.java @@ -0,0 +1,15 @@ +package org.grammaticalframework.pgf; + +class Pool { + private long ref; + + public Pool(long ref) { + this.ref = ref; + } + + public void finalize() { + free(ref); + } + + private native void free(long ref); +}