diff --git a/src/runtime/java/Makefile b/src/runtime/java/Makefile index 596735f11..65bb4fe1a 100644 --- a/src/runtime/java/Makefile +++ b/src/runtime/java/Makefile @@ -1,7 +1,28 @@ -all: - libtool --mode=compile gcc -I /usr/lib/jvm/java-6-openjdk/include -std=c99 -c jpgf.c - libtool --mode=link gcc -g -O -o libjpgf.la jpgf.lo -rpath /usr/lib -lpgf -lgu +all: libjpgf.la Test.class + +install: libtool --mode=install cp libjpgf.la /usr/lib/libjpgf.la -headers: - javah org.grammaticalframework.PGF +doc: + javadoc org.grammaticalframework.pgf + +Test.class: Test.java + javac Test.java + +org/grammaticalframework/pgf/PGF.class: org/grammaticalframework/pgf/PGF.java + javac Test.java + +org/grammaticalframework/pgf/Concr.class: org/grammaticalframework/pgf/Concr.java + javac Test.java + +libjpgf.la: jpgf.lo + libtool --mode=link gcc -g -O -o libjpgf.la jpgf.lo -rpath /usr/lib -lpgf -lgu + +jpgf.lo: jpgf.c org_grammaticalframework_pgf_PGF.h org_grammaticalframework_pgf_Concr.h + libtool --mode=compile gcc -I /usr/lib/jvm/java-6-openjdk/include -std=c99 -c jpgf.c + +org_grammaticalframework_pgf_PGF.h: org/grammaticalframework/pgf/PGF.class + javah org.grammaticalframework.pgf.PGF + +org_grammaticalframework_pgf_Concr.h: org/grammaticalframework/pgf/Concr.class + javah org.grammaticalframework.pgf.Concr diff --git a/src/runtime/java/Test.java b/src/runtime/java/Test.java index c58a90c77..27cf18da2 100644 --- a/src/runtime/java/Test.java +++ b/src/runtime/java/Test.java @@ -1,8 +1,23 @@ -import org.grammaticalframework.*; +import java.io.*; +import java.util.*; +import org.grammaticalframework.pgf.*; public class Test { public static void main(String[] args) { - PGF gr = PGF.readPGF("/home/krasimir/www.grammaticalframework.org/treebanks/PennTreebank/ParseEngAbs.pgf"); - gr.close(); + PGF gr = null; + try { + gr = PGF.readPGF("/home/krasimir/www.grammaticalframework.org/treebanks/PennTreebank/ParseEngAbs.pgf"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + return; + } catch (PGFError e) { + e.printStackTrace(); + return; + } + + System.out.println(gr.getAbstractName()); + for (Map.Entry entry : gr.getLanguages().entrySet()) { + System.out.println(entry.getKey()+" "+entry.getValue()+" "+entry.getValue().getName()); + } } } diff --git a/src/runtime/java/jpgf.c b/src/runtime/java/jpgf.c index 44b72d269..353be6023 100644 --- a/src/runtime/java/jpgf.c +++ b/src/runtime/java/jpgf.c @@ -1,9 +1,64 @@ #include #include -#include "org_grammaticalframework_PGF.h" +#include +#include +#include "org_grammaticalframework_pgf_PGF.h" + +static jstring +gu2j_string(JNIEnv *env, GuString s) { + GuWord w = s.w_; + uint8_t buf[sizeof(GuWord)]; + + uint8_t* utf8; + size_t len; + if (w & 1) { + len = (w & 0xff) >> 1; + gu_assert(len <= sizeof(GuWord)); + size_t i = len; + while (i > 0) { + w >>= 8; + buf[--i] = w & 0xff; + } + utf8 = buf; + } else { + uint8_t* p = (void*) w; + len = (p[0] == 0) ? ((size_t*) p)[-1] : p[0]; + utf8 = &p[1]; + } + + const uint8_t* src = utf8; + + jchar* utf16 = alloca(len*sizeof(jchar)); + jchar* dst = utf16; + while (src-utf8 < len) { + GuUCS ucs = gu_utf8_decode(&src); + + if (ucs <= 0xFFFF) { + *dst++ = ucs; + } else { + ucs -= 0x10000; + *dst++ = 0xD800+(ucs >> 10) & 0x3FF; + *dst++ = 0xDC00+ucs & 0x3FF; + } + } + + return (*env)->NewString(env, utf16, dst-utf16); +} + +static PgfPGF* +get_pgf(JNIEnv *env, jobject self) { + jfieldID grId = (*env)->GetFieldID(env, (*env)->GetObjectClass(env, self), "gr", "J"); + return (PgfPGF*) (*env)->GetLongField(env, self, grId); +} + +static PgfPGF* +get_concr(JNIEnv *env, jobject self) { + jfieldID concrId = (*env)->GetFieldID(env, (*env)->GetObjectClass(env, self), "concr", "J"); + return (PgfPGF*) (*env)->GetLongField(env, self, concrId); +} JNIEXPORT jobject JNICALL -Java_org_grammaticalframework_PGF_readPGF(JNIEnv *env, jclass cls, jstring s) +Java_org_grammaticalframework_pgf_PGF_readPGF(JNIEnv *env, jclass cls, jstring s) { GuPool* pool = gu_new_pool(); GuPool* tmp_pool = gu_local_pool(); @@ -19,6 +74,32 @@ Java_org_grammaticalframework_PGF_readPGF(JNIEnv *env, jclass cls, jstring s) (*env)->ReleaseStringUTFChars(env, s, fpath); 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); + } 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); + } gu_pool_free(pool); gu_pool_free(tmp_pool); return NULL; @@ -27,12 +108,81 @@ Java_org_grammaticalframework_PGF_readPGF(JNIEnv *env, jclass cls, jstring s) gu_pool_free(tmp_pool); jmethodID constrId = (*env)->GetMethodID(env, cls, "", "(JJ)V"); + return (*env)->NewObject(env, cls, constrId, (jlong) pool, (jlong) pgf); +} - return (*env)->NewObject(env, cls, constrId, (long) pool, (long) pgf); +JNIEXPORT jstring JNICALL +Java_org_grammaticalframework_pgf_PGF_getAbstractName(JNIEnv* env, jobject self) +{ + return gu2j_string(env, pgf_abstract_name(get_pgf(env, self))); } JNIEXPORT void JNICALL -Java_org_grammaticalframework_PGF_free(JNIEnv* env, jclass cls, jlong pool) +Java_org_grammaticalframework_pgf_PGF_free(JNIEnv* env, jclass cls, jlong pool) { gu_pool_free((GuPool*) pool); } + +typedef struct { + GuMapItor fn; + JNIEnv *env; + jobject grammar; + jobject object; +} JPGFClosure; + +static void +pgf_collect_langs(GuMapItor* fn, const void* key, void* value, GuExn* err) +{ + PgfCId name = *((PgfCId*) key); + PgfConcr* concr = *((PgfConcr**) value); + JPGFClosure* clo = (JPGFClosure*) fn; + + jstring jname = gu2j_string(clo->env, name); + + jclass map_class = (*clo->env)->GetObjectClass(clo->env, clo->object); + jmethodID put_method = (*clo->env)->GetMethodID(clo->env, map_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + + jclass concr_class = (*clo->env)->FindClass(clo->env, "org/grammaticalframework/pgf/Concr"); + jmethodID constrId = (*clo->env)->GetMethodID(clo->env, concr_class, "", "(Lorg/grammaticalframework/pgf/PGF;J)V"); + jobject jconcr = (*clo->env)->NewObject(clo->env, concr_class, constrId, clo->grammar, (jlong) concr); + + (*clo->env)->CallObjectMethod(clo->env, clo->object, put_method, jname, jconcr); +} + +JNIEXPORT jobject JNICALL +Java_org_grammaticalframework_pgf_PGF_getLanguages(JNIEnv* env, jobject self) +{ + jclass map_class = (*env)->FindClass(env, "java/util/HashMap"); + if (!map_class) + return NULL; + jmethodID constrId = (*env)->GetMethodID(env, map_class, "", "()V"); + if (!constrId) + return NULL; + jobject languages = (*env)->NewObject(env, map_class, constrId); + if (!languages) + return NULL; + + PgfPGF* pgf = get_pgf(env, self); + + GuPool* tmp_pool = gu_local_pool(); + + // Create an exception frame that catches all errors. + GuExn* err = gu_new_exn(NULL, gu_kind(type), tmp_pool); + + JPGFClosure clo = { { pgf_collect_langs }, env, self, languages }; + pgf_iter_languages(pgf, &clo.fn, err); + if (!gu_ok(err)) { + gu_pool_free(tmp_pool); + return NULL; + } + + gu_pool_free(tmp_pool); + + return languages; +} + +JNIEXPORT jstring JNICALL +Java_org_grammaticalframework_pgf_Concr_getName(JNIEnv* env, jobject self) +{ + return gu2j_string(env, pgf_concrete_name(get_concr(env, self))); +} diff --git a/src/runtime/java/org/grammaticalframework/PGF.java b/src/runtime/java/org/grammaticalframework/PGF.java deleted file mode 100644 index 6ff0a21a4..000000000 --- a/src/runtime/java/org/grammaticalframework/PGF.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.grammaticalframework; - -public class PGF { - public static native PGF readPGF(String path); - - public void close() { - if (pool != 0) { - free(pool); - pool = 0; - gr = 0; - } - } - - private static native void free(long pool); - - private long pool; - private long gr; - - private PGF(long pool, long gr) { - this.pool = pool; - this.gr = gr; - } - - protected void finalize () throws Throwable { - close(); - } - - static { - System.loadLibrary("jpgf"); - } -} diff --git a/src/runtime/java/org/grammaticalframework/pgf/Concr.java b/src/runtime/java/org/grammaticalframework/pgf/Concr.java new file mode 100644 index 000000000..095c009ba --- /dev/null +++ b/src/runtime/java/org/grammaticalframework/pgf/Concr.java @@ -0,0 +1,17 @@ +package org.grammaticalframework.pgf; + +public class Concr { + + public native String getName(); + + ////////////////////////////////////////////////////////////////// + // private stuff + + private PGF gr; + private long concr; + + private Concr(PGF gr, long concr) { + this.gr = gr; + this.concr = concr; + } +} diff --git a/src/runtime/java/org/grammaticalframework/pgf/Expr.java b/src/runtime/java/org/grammaticalframework/pgf/Expr.java new file mode 100644 index 000000000..6401ec6b9 --- /dev/null +++ b/src/runtime/java/org/grammaticalframework/pgf/Expr.java @@ -0,0 +1,4 @@ +package org.grammaticalframework.pgf; + +public class Expr { +} diff --git a/src/runtime/java/org/grammaticalframework/pgf/ExprProb.java b/src/runtime/java/org/grammaticalframework/pgf/ExprProb.java new file mode 100644 index 000000000..fcfbdbc74 --- /dev/null +++ b/src/runtime/java/org/grammaticalframework/pgf/ExprProb.java @@ -0,0 +1,19 @@ +package org.grammaticalframework.pgf; + +public class ExprProb { + private Expr expr; + private double prob; + + public ExprProb(Expr expr, double prob) { + this.expr = expr; + this.prob = prob; + } + + public Expr getExpr() { + return expr; + } + + public double getProb() { + return prob; + } +} diff --git a/src/runtime/java/org/grammaticalframework/pgf/PGF.java b/src/runtime/java/org/grammaticalframework/pgf/PGF.java new file mode 100644 index 000000000..35ff8d044 --- /dev/null +++ b/src/runtime/java/org/grammaticalframework/pgf/PGF.java @@ -0,0 +1,51 @@ +package org.grammaticalframework.pgf; + +import java.io.*; +import java.util.*; + +public class PGF { + public static native PGF readPGF(String path) throws FileNotFoundException; + + public native String getAbstractName(); + + public native Map getLanguages(); + + public native List getCategories(); + + public native String getStartCat(); + + public native List getFunctions(); + + public native List getFunctionsByCat(String cat); + + public native Type getFunctionType(String fun); + + public native Iterator generate(Type type); + + public native Expr compute(Expr expr); + + ////////////////////////////////////////////////////////////////// + // private stuff + + private static native void free(long pool); + + private long pool; + private long gr; + + private PGF(long pool, long gr) { + this.pool = pool; + this.gr = gr; + } + + protected void finalize () throws Throwable { + if (pool != 0) { + free(pool); + pool = 0; + gr = 0; + } + } + + static { + System.loadLibrary("jpgf"); + } +} diff --git a/src/runtime/java/org/grammaticalframework/pgf/PGFError.java b/src/runtime/java/org/grammaticalframework/pgf/PGFError.java new file mode 100644 index 000000000..fb55349c4 --- /dev/null +++ b/src/runtime/java/org/grammaticalframework/pgf/PGFError.java @@ -0,0 +1,7 @@ +package org.grammaticalframework.pgf; + +public class PGFError extends RuntimeException { + public PGFError(String message) { + super(message); + } +} diff --git a/src/runtime/java/org/grammaticalframework/pgf/Type.java b/src/runtime/java/org/grammaticalframework/pgf/Type.java new file mode 100644 index 000000000..061771b71 --- /dev/null +++ b/src/runtime/java/org/grammaticalframework/pgf/Type.java @@ -0,0 +1,4 @@ +package org.grammaticalframework.pgf; + +public class Type { +}