summaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/c/pgf/data.h3
-rw-r--r--src/runtime/c/pgf/literals.c13
-rw-r--r--src/runtime/c/pgf/literals.h3
-rw-r--r--src/runtime/c/pgf/parser.c24
-rw-r--r--src/runtime/c/pgf/pgf.c42
-rw-r--r--src/runtime/c/pgf/pgf.h18
-rw-r--r--src/runtime/c/pgf/reader.c3
-rw-r--r--src/runtime/c/utils/pgf-parse.c7
-rw-r--r--src/runtime/c/utils/pgf-translate.c6
-rw-r--r--src/runtime/haskell-bind/PGF2.hsc42
-rw-r--r--src/runtime/haskell-bind/PGF2/FFI.hs14
-rw-r--r--src/runtime/haskell-bind/utils.c14
-rw-r--r--src/runtime/java/Test.java1
-rw-r--r--src/runtime/java/jpgf.c344
-rw-r--r--src/runtime/java/org/grammaticalframework/pgf/Concr.java13
-rw-r--r--src/runtime/java/org/grammaticalframework/pgf/ExprIterator.java4
-rw-r--r--src/runtime/java/org/grammaticalframework/pgf/Parser.java28
-rw-r--r--src/runtime/python/pypgf.c250
18 files changed, 413 insertions, 416 deletions
diff --git a/src/runtime/c/pgf/data.h b/src/runtime/c/pgf/data.h
index a3554ef45..6b62cfe4e 100644
--- a/src/runtime/c/pgf/data.h
+++ b/src/runtime/c/pgf/data.h
@@ -199,8 +199,6 @@ typedef GuMap PgfCncOverloadMap;
typedef struct PgfItem PgfItem;
-typedef GuMap PgfCallbacksMap;
-
typedef GuVariant PgfSymbol;
typedef enum {
@@ -280,7 +278,6 @@ struct PgfConcr {
PgfSequences* sequences;
GuBuf* pre_sequences;
PgfCIdMap* cnccats;
- PgfCallbacksMap* callbacks;
int total_cats;
GuPool* pool; // if the language is loaded separately then this is the pool
diff --git a/src/runtime/c/pgf/literals.c b/src/runtime/c/pgf/literals.c
index 51a426031..1376c8beb 100644
--- a/src/runtime/c/pgf/literals.c
+++ b/src/runtime/c/pgf/literals.c
@@ -274,6 +274,19 @@ pgf_new_callbacks_map(PgfConcr* concr, GuPool *pool)
return callbacks;
}
+void
+pgf_callbacks_map_add_literal(PgfConcr* concr, PgfCallbacksMap* callbacks,
+ PgfCId cat, PgfLiteralCallback* callback)
+{
+ PgfCncCat* cnccat =
+ gu_map_get(concr->cnccats, cat, PgfCncCat*);
+ if (cnccat == NULL)
+ return;
+
+ gu_map_put(callbacks, cnccat,
+ PgfLiteralCallback*, callback);
+}
+
PgfCCat*
pgf_literal_cat(PgfConcr* concr, PgfLiteral lit)
{
diff --git a/src/runtime/c/pgf/literals.h b/src/runtime/c/pgf/literals.h
index 88f9304a1..bf071c202 100644
--- a/src/runtime/c/pgf/literals.h
+++ b/src/runtime/c/pgf/literals.h
@@ -3,9 +3,6 @@
#include <pgf/data.h>
-PgfCallbacksMap*
-pgf_new_callbacks_map(PgfConcr* concr, GuPool *pool);
-
// literal for named entities recognition
extern PgfLiteralCallback pgf_nerc_literal_callback;
diff --git a/src/runtime/c/pgf/parser.c b/src/runtime/c/pgf/parser.c
index 2ff98d772..bbdcd3cf6 100644
--- a/src/runtime/c/pgf/parser.c
+++ b/src/runtime/c/pgf/parser.c
@@ -57,6 +57,7 @@ typedef struct {
PgfItem* free_item;
prob_t heuristic_factor;
+ PgfCallbacksMap* callbacks;
prob_t meta_prob;
prob_t meta_token_prob;
} PgfParsing;
@@ -1616,7 +1617,7 @@ pgf_parsing_symbol(PgfParsing* ps, PgfItem* item, PgfSymbol sym)
* literal category so we must call the callback */
PgfLiteralCallback* callback =
- gu_map_get(ps->concr->callbacks,
+ gu_map_get(ps->callbacks,
parg->ccat->cnccat,
PgfLiteralCallback*);
@@ -1861,7 +1862,7 @@ pgf_parsing_set_default_factors(PgfParsing* ps, PgfAbstr* abstr)
}
static PgfParsing*
-pgf_new_parsing(PgfConcr* concr, GuString sentence,
+pgf_new_parsing(PgfConcr* concr, GuString sentence, PgfCallbacksMap* callbacks,
GuPool* pool, GuPool* out_pool)
{
PgfParsing* ps = gu_new(PgfParsing, pool);
@@ -1884,6 +1885,7 @@ pgf_new_parsing(PgfConcr* concr, GuString sentence,
ps->tp = NULL;
ps->free_item = NULL;
ps->heuristic_factor = 0;
+ ps->callbacks = callbacks;
ps->meta_prob = INFINITY;
ps->meta_token_prob = INFINITY;
@@ -2087,9 +2089,9 @@ pgf_parse_result_is_new(PgfExprState* st)
// TODO: s/CId/Cat, add the cid to Cat, make Cat the key to CncCat
static PgfParsing*
pgf_parsing_init(PgfConcr* concr, PgfCId cat, size_t lin_idx,
- GuString sentence, double heuristic_factor,
- GuExn* err,
- GuPool* pool, GuPool* out_pool)
+ GuString sentence,
+ double heuristic_factor, PgfCallbacksMap* callbacks,
+ GuExn* err, GuPool* pool, GuPool* out_pool)
{
PgfCncCat* cnccat =
gu_map_get(concr->cnccats, cat, PgfCncCat*);
@@ -2102,7 +2104,7 @@ pgf_parsing_init(PgfConcr* concr, PgfCId cat, size_t lin_idx,
gu_assert(lin_idx < cnccat->n_lins);
PgfParsing* ps =
- pgf_new_parsing(concr, sentence, pool, out_pool);
+ pgf_new_parsing(concr, sentence, callbacks, pool, out_pool);
if (heuristic_factor >= 0) {
ps->heuristic_factor = heuristic_factor;
@@ -2312,12 +2314,14 @@ pgf_parse(PgfConcr* concr, PgfCId cat, GuString sentence,
GuExn* err,
GuPool* pool, GuPool* out_pool)
{
- return pgf_parse_with_heuristics(concr, cat, sentence, -1.0, err, pool, out_pool);
+ PgfCallbacksMap* callbacks = pgf_new_callbacks_map(concr, out_pool);
+ return pgf_parse_with_heuristics(concr, cat, sentence, -1.0, callbacks, err, pool, out_pool);
}
GuEnum*
pgf_parse_with_heuristics(PgfConcr* concr, PgfCId cat, GuString sentence,
double heuristics,
+ PgfCallbacksMap* callbacks,
GuExn* err,
GuPool* pool, GuPool* out_pool)
{
@@ -2333,7 +2337,7 @@ pgf_parse_with_heuristics(PgfConcr* concr, PgfCId cat, GuString sentence,
// Begin parsing a sentence with the specified category
PgfParsing* ps =
- pgf_parsing_init(concr, cat, 0, sentence, heuristics, err, pool, out_pool);
+ pgf_parsing_init(concr, cat, 0, sentence, heuristics, callbacks, err, pool, out_pool);
if (ps == NULL) {
return NULL;
}
@@ -2393,8 +2397,10 @@ pgf_complete(PgfConcr* concr, PgfCId cat, GuString sentence,
}
// Begin parsing a sentence with the specified category
+ PgfCallbacksMap* callbacks =
+ pgf_new_callbacks_map(concr, pool);
PgfParsing* ps =
- pgf_parsing_init(concr, cat, 0, sentence, -1.0, err, pool, pool);
+ pgf_parsing_init(concr, cat, 0, sentence, -1.0, callbacks, err, pool, pool);
if (ps == NULL) {
return NULL;
}
diff --git a/src/runtime/c/pgf/pgf.c b/src/runtime/c/pgf/pgf.c
index 0412099e1..4fc909acf 100644
--- a/src/runtime/c/pgf/pgf.c
+++ b/src/runtime/c/pgf/pgf.c
@@ -32,6 +32,16 @@ pgf_read(const char* fpath,
return pgf;
}
+PgfPGF*
+pgf_read_in(GuIn* in,
+ GuPool* pool, GuPool* tmp_pool, GuExn* err)
+{
+ PgfReader* rdr = pgf_new_reader(in, pool, tmp_pool, err);
+ PgfPGF* pgf = pgf_read_pgf(rdr);
+ pgf_reader_done(rdr, pgf);
+ return pgf;
+}
+
GuString
pgf_abstract_name(PgfPGF* pgf)
{
@@ -171,38 +181,6 @@ pgf_has_linearization(PgfConcr* concr, PgfCId id)
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);
-}
-
PgfExprProb*
pgf_fun_get_ep(void* value)
{
diff --git a/src/runtime/c/pgf/pgf.h b/src/runtime/c/pgf/pgf.h
index 49f522278..e542e4213 100644
--- a/src/runtime/c/pgf/pgf.h
+++ b/src/runtime/c/pgf/pgf.h
@@ -25,6 +25,10 @@ PgfPGF*
pgf_read(const char* fpath,
GuPool* pool, GuExn* err);
+PgfPGF*
+pgf_read_in(GuIn* in,
+ GuPool* pool, GuPool* tmp_pool, GuExn* err);
+
void
pgf_concrete_load(PgfConcr* concr, GuIn* in, GuExn* err);
@@ -114,9 +118,12 @@ GuEnum*
pgf_lookup_word_prefix(PgfConcr *concr, GuString prefix,
GuPool* pool, GuExn* err);
+typedef GuMap PgfCallbacksMap;
+
PgfExprEnum*
pgf_parse_with_heuristics(PgfConcr* concr, PgfCId cat,
GuString sentence, double heuristics,
+ PgfCallbacksMap* callbacks,
GuExn* err,
GuPool* pool, GuPool* out_pool);
@@ -130,9 +137,6 @@ 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 {
@@ -146,10 +150,12 @@ struct PgfLiteralCallback {
GuPool *out_pool);
};
+PgfCallbacksMap*
+pgf_new_callbacks_map(PgfConcr* concr, GuPool *pool);
+
void
-pgf_concr_add_literal(PgfConcr *concr, PgfCId cat,
- PgfLiteralCallback* callback,
- GuExn* err);
+pgf_callbacks_map_add_literal(PgfConcr* concr, PgfCallbacksMap* callbacks,
+ PgfCId cat, PgfLiteralCallback* callback);
void
pgf_print(PgfPGF* pgf, GuOut* out, GuExn* err);
diff --git a/src/runtime/c/pgf/reader.c b/src/runtime/c/pgf/reader.c
index 8314fef5f..1c250f559 100644
--- a/src/runtime/c/pgf/reader.c
+++ b/src/runtime/c/pgf/reader.c
@@ -1,6 +1,5 @@
#include "data.h"
#include "expr.h"
-#include "literals.h"
#include "evaluator.h"
#include "reader.h"
@@ -1148,7 +1147,6 @@ pgf_read_concrete_content(PgfReader* rdr, PgfConcr* concr)
pgf_read_linrefs(rdr, concr);
pgf_read_ccats(rdr, concr);
concr->cnccats = pgf_read_cnccats(rdr, concr->abstr, concr);
- concr->callbacks = pgf_new_callbacks_map(concr, rdr->opool);
concr->total_cats = pgf_read_int(rdr);
GuMapItor clo1 = { pgf_read_ccat_cb };
@@ -1166,7 +1164,6 @@ pgf_read_concrete_init_header(PgfConcr* concr)
concr->fun_indices = NULL;
concr->coerce_idx = NULL;
concr->cnccats = NULL;
- concr->callbacks = NULL;
concr->total_cats = 0;
}
diff --git a/src/runtime/c/utils/pgf-parse.c b/src/runtime/c/utils/pgf-parse.c
index eb417d5e7..088fe409d 100644
--- a/src/runtime/c/utils/pgf-parse.c
+++ b/src/runtime/c/utils/pgf-parse.c
@@ -58,10 +58,6 @@ int main(int argc, char* argv[]) {
goto fail;
}
- /* // Register a callback for the literal category Symbol */
- /* pgf_parser_add_literal(from_concr, "Symb", */
- /* &pgf_nerc_literal_callback); */
-
clock_t end = clock();
double cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
@@ -109,7 +105,8 @@ int main(int argc, char* argv[]) {
clock_t start = clock();
GuExn* parse_err = gu_new_exn(ppool);
- GuEnum* result = pgf_parse_with_heuristics(concr, cat, line, heuristics, parse_err, ppool, ppool);
+ PgfCallbacksMap* callbacks = pgf_new_callbacks_map(concr, ppool);
+ GuEnum* result = pgf_parse_with_heuristics(concr, cat, line, heuristics, callbacks, parse_err, ppool, ppool);
PgfExprProb* ep = NULL;
if (gu_ok(parse_err))
diff --git a/src/runtime/c/utils/pgf-translate.c b/src/runtime/c/utils/pgf-translate.c
index 0f3b297aa..065853215 100644
--- a/src/runtime/c/utils/pgf-translate.c
+++ b/src/runtime/c/utils/pgf-translate.c
@@ -87,8 +87,10 @@ int main(int argc, char* argv[]) {
}
// Register a callback for the literal category Symbol
- pgf_concr_add_literal(from_concr, "Symb",
- &pgf_nerc_literal_callback, err);
+ PgfCallbacksMap* callbacks =
+ pgf_new_callbacks_map(from_concr, pool);
+ pgf_callbacks_map_add_literal(from_concr, callbacks,
+ "PN", &pgf_nerc_literal_callback);
// Create an output stream for stdout
GuOut* out = gu_file_out(stdout, pool);
diff --git a/src/runtime/haskell-bind/PGF2.hsc b/src/runtime/haskell-bind/PGF2.hsc
index 629e020ce..8fb4e9387 100644
--- a/src/runtime/haskell-bind/PGF2.hsc
+++ b/src/runtime/haskell-bind/PGF2.hsc
@@ -26,6 +26,7 @@ module PGF2 (-- * PGF
import Prelude hiding (fromEnum)
import Control.Exception(Exception,throwIO)
+import Control.Monad(forM_)
import System.IO.Unsafe(unsafePerformIO,unsafeInterleaveIO)
import PGF2.FFI
@@ -231,14 +232,18 @@ getAnalysis ref self c_lemma c_anal prob exn = do
writeIORef ref ((lemma, anal, prob):ans)
parse :: Concr -> String -> String -> Either String [(Expr,Float)]
-parse lang cat sent =
+parse lang cat sent = parse_with_heuristics lang cat sent (-1.0) []
+
+parse_with_heuristics :: Concr -> String -> String -> Double -> [(String, Int -> String -> Int -> Maybe (Expr,Float,Int))] -> Either String [(Expr,Float)]
+parse_with_heuristics lang cat sent heuristic callbacks =
unsafePerformIO $
do parsePl <- gu_new_pool
exprPl <- gu_new_pool
exn <- gu_new_exn parsePl
enum <- withCString cat $ \cat ->
- withCString sent $ \sent ->
- pgf_parse (concr lang) cat sent exn parsePl exprPl
+ withCString sent $ \sent -> do
+ callbacks_map <- mkCallbacksMap (concr lang) callbacks parsePl
+ pgf_parse_with_heuristics (concr lang) cat sent heuristic callbacks_map exn parsePl exprPl
failed <- gu_exn_is_raised exn
if failed
then do is_parse_error <- gu_exn_caught exn gu_exn_type_PgfParseError
@@ -263,28 +268,17 @@ parse lang cat sent =
exprs <- fromPgfExprEnum enum parseFPl (lang,exprFPl)
return (Right exprs)
-addLiteral :: Concr -> String -> (Int -> String -> Int -> Maybe (Expr,Float,Int)) -> IO ()
-addLiteral lang cat match =
- withCString cat $ \ccat ->
- withGuPool $ \tmp_pool -> do
- callback <- hspgf_new_literal_callback (concr lang)
- match <- wrapLiteralMatchCallback match_callback
- predict <- wrapLiteralPredictCallback predict_callback
- (#poke PgfLiteralCallback, match) callback match
- (#poke PgfLiteralCallback, predict) callback predict
- exn <- gu_new_exn tmp_pool
- pgf_concr_add_literal (concr lang) ccat callback exn
- failed <- gu_exn_is_raised exn
- if failed
- then do is_exn <- gu_exn_caught exn gu_exn_type_PgfExn
- if is_exn
- then do c_msg <- (#peek GuExn, data.data) exn
- msg <- peekCString c_msg
- throwIO (PGFError msg)
- else throwIO (PGFError "The literal cannot be added")
- else return ()
+mkCallbacksMap :: Ptr PgfConcr -> [(String, Int -> String -> Int -> Maybe (Expr,Float,Int))] -> Ptr GuPool -> IO (Ptr PgfCallbacksMap)
+mkCallbacksMap concr callbacks pool = do
+ callbacks_map <- pgf_new_callbacks_map concr pool
+ forM_ callbacks $ \(cat,match) ->
+ withCString cat $ \ccat -> do
+ match <- wrapLiteralMatchCallback (match_callback match)
+ predict <- wrapLiteralPredictCallback predict_callback
+ hspgf_callbacks_map_add_literal concr callbacks_map ccat match predict pool
+ return callbacks_map
where
- match_callback _ clin_idx csentence poffset out_pool = do
+ match_callback match _ clin_idx csentence poffset out_pool = do
sentence <- peekCString csentence
coffset <- peek poffset
offset <- alloca $ \pcsentence -> do
diff --git a/src/runtime/haskell-bind/PGF2/FFI.hs b/src/runtime/haskell-bind/PGF2/FFI.hs
index 96c5b19fa..863431bca 100644
--- a/src/runtime/haskell-bind/PGF2/FFI.hs
+++ b/src/runtime/haskell-bind/PGF2/FFI.hs
@@ -91,7 +91,7 @@ data PgfFullFormEntry
data PgfMorphoCallback
data PgfPrintContext
data PgfType
-data PgfLiteralCallback
+data PgfCallbacksMap
foreign import ccall "pgf/pgf.h pgf_read"
pgf_read :: CString -> Ptr GuPool -> Ptr GuExn -> IO (Ptr PgfPGF)
@@ -138,8 +138,8 @@ foreign import ccall "pgf/pgf.h pgf_print_name"
foreign import ccall "pgf/pgf.h pgf_linearize"
pgf_linearize :: Ptr PgfConcr -> PgfExpr -> Ptr GuOut -> Ptr GuExn -> IO ()
-foreign import ccall "pgf/pgf.h pgf_parse"
- pgf_parse :: Ptr PgfConcr -> CString -> CString -> Ptr GuExn -> Ptr GuPool -> Ptr GuPool -> IO (Ptr GuEnum)
+foreign import ccall "pgf/pgf.h pgf_parse_with_heuristics"
+ pgf_parse_with_heuristics :: Ptr PgfConcr -> CString -> CString -> Double -> Ptr PgfCallbacksMap -> Ptr GuExn -> Ptr GuPool -> Ptr GuPool -> IO (Ptr GuEnum)
type LiteralMatchCallback = Ptr () -> CInt -> CString -> Ptr CInt -> Ptr GuPool -> IO (Ptr PgfExprProb)
@@ -151,11 +151,11 @@ type LiteralPredictCallback = Ptr () -> CInt -> CString -> Ptr GuPool -> IO (Ptr
foreign import ccall "wrapper"
wrapLiteralPredictCallback :: LiteralPredictCallback -> IO (FunPtr LiteralPredictCallback)
-foreign import ccall
- hspgf_new_literal_callback :: Ptr PgfConcr -> IO (Ptr PgfLiteralCallback)
+foreign import ccall "pgf/pgf.h pgf_new_callbacks_map"
+ pgf_new_callbacks_map :: Ptr PgfConcr -> Ptr GuPool -> IO (Ptr PgfCallbacksMap)
-foreign import ccall "pgf/pgf.h pgf_concr_add_literal"
- pgf_concr_add_literal :: Ptr PgfConcr -> CString -> Ptr PgfLiteralCallback -> Ptr GuExn -> IO ()
+foreign import ccall
+ hspgf_callbacks_map_add_literal :: Ptr PgfConcr -> Ptr PgfCallbacksMap -> CString -> FunPtr LiteralMatchCallback -> FunPtr LiteralPredictCallback -> Ptr GuPool -> IO ()
foreign import ccall "pgf/pgf.h pgf_lookup_morpho"
pgf_lookup_morpho :: Ptr PgfConcr -> CString -> Ptr PgfMorphoCallback -> Ptr GuExn -> IO ()
diff --git a/src/runtime/haskell-bind/utils.c b/src/runtime/haskell-bind/utils.c
index 8ab1e53e3..8bdb99038 100644
--- a/src/runtime/haskell-bind/utils.c
+++ b/src/runtime/haskell-bind/utils.c
@@ -17,13 +17,15 @@ hspgf_literal_callback_fin(GuFinalizer* self)
hs_free_fun_ptr((HsFunPtr) callback->callback.predict);
}
-PgfLiteralCallback*
-hspgf_new_literal_callback(PgfConcr* concr) {
- GuPool* pool = pgf_concr_get_pool(concr);
+void
+hspgf_callbacks_map_add_literal(PgfConcr* concr, PgfCallbacksMap* callbacks,
+ PgfCId cat, HsFunPtr match, HsFunPtr predict,
+ GuPool* pool)
+{
HSPgfLiteralCallback* callback = gu_new(HSPgfLiteralCallback, pool);
- callback->callback.match = NULL;
- callback->callback.predict = NULL;
+ callback->callback.match = (void*) match;
+ callback->callback.predict = (void*) predict;
callback->fin.fn = hspgf_literal_callback_fin;
gu_pool_finally(pool, &callback->fin);
- return &callback->callback;
+ pgf_callbacks_map_add_literal(concr, callbacks, cat, &callback->callback);
}
diff --git a/src/runtime/java/Test.java b/src/runtime/java/Test.java
index 08d6445cb..3c27e641b 100644
--- a/src/runtime/java/Test.java
+++ b/src/runtime/java/Test.java
@@ -20,7 +20,6 @@ public class Test {
System.out.println(gr.getAbstractName());
for (Map.Entry<String,Concr> entry : gr.getLanguages().entrySet()) {
System.out.println(entry.getKey()+" "+entry.getValue()+" "+entry.getValue().getName());
- entry.getValue().addLiteral("PN", new NercLiteralCallback(gr,entry.getValue()));
}
Concr eng = gr.getLanguages().get("SimpleEng");
diff --git a/src/runtime/java/jpgf.c b/src/runtime/java/jpgf.c
index 49a7e04dc..308811b81 100644
--- a/src/runtime/java/jpgf.c
+++ b/src/runtime/java/jpgf.c
@@ -1,5 +1,4 @@
#include <pgf/pgf.h>
-#include <pgf/reader.h>
#include <pgf/linearizer.h>
#include <gu/mem.h>
#include <gu/exn.h>
@@ -223,10 +222,7 @@ Java_org_grammaticalframework_pgf_PGF_readPGF__Ljava_io_InputStream_2(JNIEnv *en
GuExn* err = gu_exn(tmp_pool);
// Read the PGF grammar.
- PgfReader* rdr = pgf_new_reader(in, pool, tmp_pool, err);
- PgfPGF* pgf = pgf_read_pgf(rdr);
- pgf_reader_done(rdr, pgf);
-
+ PgfPGF* pgf = pgf_read_in(in, pool, tmp_pool, err);
if (!gu_ok(err)) {
throw_string_exception(env, "org/grammaticalframework/pgf/PGFError", "The grammar cannot be loaded");
gu_pool_free(pool);
@@ -371,11 +367,169 @@ Java_org_grammaticalframework_pgf_Concr_unload(JNIEnv* env, jobject self)
pgf_concrete_unload(get_ref(env, self));
}
+JNIEXPORT jlong JNICALL
+Java_org_grammaticalframework_pgf_Parser_newCallbacksMap
+ (JNIEnv* env, jclass clazz, jobject jconcr, jobject jpool)
+{
+ return p2l(pgf_new_callbacks_map(get_ref(env, jconcr), get_ref(env, jpool)));
+}
+
+typedef struct {
+ PgfLiteralCallback callback;
+ jobject jcallback;
+ jmethodID match_methodId;
+ jmethodID predict_methodId;
+ GuFinalizer fin;
+} JPgfLiteralCallback;
+
+typedef struct {
+ GuEnum en;
+ jobject jiterator;
+ GuFinalizer fin;
+} JPgfTokenProbEnum;
+
+static PgfExprProb*
+jpgf_literal_callback_match(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, &env, NULL);
+
+ jstring jsentence = gu2j_string(env, sentence);
+ size_t joffset = gu2j_string_offset(sentence, *poffset);
+ jobject result = (*env)->CallObjectMethod(env, callback->jcallback, callback->match_methodId, lin_idx, jsentence, joffset);
+ if (result == NULL)
+ return NULL;
+
+ 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 = j2gu_string_offset(sentence, (*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_exn(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_token_prob_enum_fin(GuFinalizer* self)
+{
+ JPgfTokenProbEnum* en = gu_container(self, JPgfTokenProbEnum, fin);
+
+ JNIEnv *env;
+ (*cachedJVM)->AttachCurrentThread(cachedJVM, &env, NULL);
+
+ (*env)->DeleteGlobalRef(env, en->jiterator);
+}
+
+static GuEnum*
+jpgf_literal_callback_predict(PgfLiteralCallback* self,
+ size_t lin_idx,
+ GuString prefix,
+ GuPool *out_pool)
+{
+ JPgfLiteralCallback* callback = gu_container(self, JPgfLiteralCallback, callback);
+
+ JNIEnv *env;
+ (*cachedJVM)->AttachCurrentThread(cachedJVM, &env, NULL);
+
+ jstring jprefix = gu2j_string(env, prefix);
+ jobject jiterator = (*env)->CallObjectMethod(env, callback->jcallback, callback->predict_methodId, lin_idx, jprefix);
+ if (jiterator == NULL)
+ return NULL;
+
+ JPgfTokenProbEnum* en = gu_new(JPgfTokenProbEnum, out_pool);
+ en->en.next = NULL;
+ en->jiterator = (*env)->NewGlobalRef(env, jiterator);
+ en->fin.fn = jpgf_token_prob_enum_fin;
+
+ gu_pool_finally(out_pool, &en->fin);
+
+ return &en->en;
+}
+
+static void
+jpgf_literal_callback_fin(GuFinalizer* self)
+{
+ JPgfLiteralCallback* callback = gu_container(self, JPgfLiteralCallback, fin);
+
+ JNIEnv *env;
+ (*cachedJVM)->AttachCurrentThread(cachedJVM, &env, NULL);
+
+ (*env)->DeleteGlobalRef(env, callback->jcallback);
+}
+
+JNIEXPORT void JNICALL Java_org_grammaticalframework_pgf_Parser_addLiteralCallback
+ (JNIEnv* env, jclass clazz, jobject jconcr, jlong callbacksRef, jstring jcat, jobject jcallback, jobject jpool)
+{
+ PgfConcr* concr = get_ref(env, jconcr);
+ GuPool* pool = get_ref(env, jpool);
+
+ JPgfLiteralCallback* callback = gu_new(JPgfLiteralCallback, pool);
+ callback->callback.match = jpgf_literal_callback_match;
+ callback->callback.predict = jpgf_literal_callback_predict;
+ 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;");
+ callback->predict_methodId = (*env)->GetMethodID(env, callback_class, "predict", "(ILjava/lang/String;)Ljava/util/Iterator;");
+
+ gu_pool_finally(pool, &callback->fin);
+
+ pgf_callbacks_map_add_literal(concr, l2p(callbacksRef),
+ j2gu_string(env, jcat, pool), &callback->callback);
+}
+
JNIEXPORT jobject JNICALL
-Java_org_grammaticalframework_pgf_Parser_parse
- (JNIEnv* env, jclass clazz, jobject concr, jstring jstartCat, jstring js)
+Java_org_grammaticalframework_pgf_Parser_parseWithHeuristics
+ (JNIEnv* env, jclass clazz, jobject jconcr, jstring jstartCat, jstring js, jdouble heuristics, jlong callbacksRef, jobject jpool)
{
- GuPool* pool = gu_new_pool();
+ GuPool* pool = get_ref(env, jpool);
GuPool* out_pool = gu_new_pool();
GuString startCat = j2gu_string(env, jstartCat, pool);
@@ -383,7 +537,7 @@ Java_org_grammaticalframework_pgf_Parser_parse
GuExn* parse_err = gu_new_exn(pool);
GuEnum* res =
- pgf_parse(get_ref(env, concr), startCat, s, parse_err, pool, out_pool);
+ pgf_parse_with_heuristics(get_ref(env, jconcr), startCat, s, heuristics, l2p(callbacksRef), parse_err, pool, out_pool);
if (!gu_ok(parse_err)) {
if (gu_exn_caught(parse_err, PgfExn)) {
@@ -394,17 +548,16 @@ Java_org_grammaticalframework_pgf_Parser_parse
throw_string_exception(env, "org/grammaticalframework/pgf/ParseError", tok);
}
- gu_pool_free(pool);
gu_pool_free(out_pool);
return NULL;
}
- jfieldID refId = (*env)->GetFieldID(env, (*env)->GetObjectClass(env, concr), "gr", "Lorg/grammaticalframework/pgf/PGF;");
- jobject jpgf = (*env)->GetObjectField(env, concr, refId);
+ jfieldID refId = (*env)->GetFieldID(env, (*env)->GetObjectClass(env, jconcr), "gr", "Lorg/grammaticalframework/pgf/PGF;");
+ jobject jpgf = (*env)->GetObjectField(env, jconcr, refId);
jclass expiter_class = (*env)->FindClass(env, "org/grammaticalframework/pgf/ExprIterator");
- jmethodID constrId = (*env)->GetMethodID(env, expiter_class, "<init>", "(Lorg/grammaticalframework/pgf/PGF;JJJ)V");
- jobject jexpiter = (*env)->NewObject(env, expiter_class, constrId, jpgf, p2l(pool), p2l(out_pool), p2l(res));
+ jmethodID constrId = (*env)->GetMethodID(env, expiter_class, "<init>", "(Lorg/grammaticalframework/pgf/PGF;Lorg/grammaticalframework/pgf/Pool;JJ)V");
+ jobject jexpiter = (*env)->NewObject(env, expiter_class, constrId, jpgf, jpool, p2l(out_pool), p2l(res));
return jexpiter;
}
@@ -878,169 +1031,6 @@ Java_org_grammaticalframework_pgf_Concr_hasLinearization(JNIEnv* env, jobject se
return res;
}
-typedef struct {
- PgfLiteralCallback callback;
- jobject jcallback;
- jmethodID match_methodId;
- jmethodID predict_methodId;
- GuFinalizer fin;
-} JPgfLiteralCallback;
-
-typedef struct {
- GuEnum en;
- jobject jiterator;
- GuFinalizer fin;
-} JPgfTokenProbEnum;
-
-static PgfExprProb*
-jpgf_literal_callback_match(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, &env, NULL);
-
- jstring jsentence = gu2j_string(env, sentence);
- size_t joffset = gu2j_string_offset(sentence, *poffset);
- jobject result = (*env)->CallObjectMethod(env, callback->jcallback, callback->match_methodId, lin_idx, jsentence, joffset);
- if (result == NULL)
- return NULL;
-
- 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 = j2gu_string_offset(sentence, (*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_exn(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_token_prob_enum_fin(GuFinalizer* self)
-{
- JPgfTokenProbEnum* en = gu_container(self, JPgfTokenProbEnum, fin);
-
- JNIEnv *env;
- (*cachedJVM)->AttachCurrentThread(cachedJVM, &env, NULL);
-
- (*env)->DeleteGlobalRef(env, en->jiterator);
-}
-
-static GuEnum*
-jpgf_literal_callback_predict(PgfLiteralCallback* self,
- size_t lin_idx,
- GuString prefix,
- GuPool *out_pool)
-{
- JPgfLiteralCallback* callback = gu_container(self, JPgfLiteralCallback, callback);
-
- JNIEnv *env;
- (*cachedJVM)->AttachCurrentThread(cachedJVM, &env, NULL);
-
- jstring jprefix = gu2j_string(env, prefix);
- jobject jiterator = (*env)->CallObjectMethod(env, callback->jcallback, callback->predict_methodId, lin_idx, jprefix);
- if (jiterator == NULL)
- return NULL;
-
- JPgfTokenProbEnum* en = gu_new(JPgfTokenProbEnum, out_pool);
- en->en.next = NULL;
- en->jiterator = (*env)->NewGlobalRef(env, jiterator);
- en->fin.fn = jpgf_token_prob_enum_fin;
-
- gu_pool_finally(out_pool, &en->fin);
-
- return &en->en;
-}
-
-static void
-jpgf_literal_callback_fin(GuFinalizer* self)
-{
- JPgfLiteralCallback* callback = gu_container(self, JPgfLiteralCallback, fin);
-
- JNIEnv *env;
- (*cachedJVM)->AttachCurrentThread(cachedJVM, &env, NULL);
-
- (*env)->DeleteGlobalRef(env, callback->jcallback);
-}
-
-JNIEXPORT void JNICALL
-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_match;
- callback->callback.predict = jpgf_literal_callback_predict;
- 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;");
- callback->predict_methodId = (*env)->GetMethodID(env, callback_class, "predict", "(ILjava/lang/String;)Ljava/util/Iterator;");
-
- gu_pool_finally(pool, &callback->fin);
-
- GuPool* tmp_pool = gu_local_pool();
- GuExn* err = gu_exn(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, 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)
{
diff --git a/src/runtime/java/org/grammaticalframework/pgf/Concr.java b/src/runtime/java/org/grammaticalframework/pgf/Concr.java
index ca90c4466..b25a83a52 100644
--- a/src/runtime/java/org/grammaticalframework/pgf/Concr.java
+++ b/src/runtime/java/org/grammaticalframework/pgf/Concr.java
@@ -8,16 +8,11 @@ public class Concr {
public native String getName();
public Iterable<ExprProb> parse(String startCat, String s) throws ParseError {
- return new Parser(this, startCat, s);
+ return new Parser(this, startCat, s, -1, null);
}
- public Expr parseBest(String startCat, String s) throws ParseError {
- Iterator<ExprProb> iter = Parser.parse(this, startCat, s);
- if (iter.hasNext()) {
- return iter.next().getExpr();
- } else {
- return null;
- }
+ public Iterable<ExprProb> parseWithHeuristics(String startCat, String s, double heuristics, Map<String,LiteralCallback> callbacks) throws ParseError {
+ return new Parser(this, startCat, s, heuristics, callbacks);
}
public Iterable<TokenProb> complete(String startCat, String s, String prefix) throws ParseError {
@@ -44,8 +39,6 @@ public class Concr {
public native void unload();
- public native void addLiteral(String cat, LiteralCallback callback);
-
//////////////////////////////////////////////////////////////////
// private stuff
diff --git a/src/runtime/java/org/grammaticalframework/pgf/ExprIterator.java b/src/runtime/java/org/grammaticalframework/pgf/ExprIterator.java
index ffd8a45cb..c1504d9da 100644
--- a/src/runtime/java/org/grammaticalframework/pgf/ExprIterator.java
+++ b/src/runtime/java/org/grammaticalframework/pgf/ExprIterator.java
@@ -9,9 +9,9 @@ class ExprIterator implements Iterator<ExprProb> {
private ExprProb ep;
private boolean fetched;
- public ExprIterator(PGF gr, long pool, long out_pool, long ref) {
+ public ExprIterator(PGF gr, Pool pool, long out_pool, long ref) {
this.gr = gr;
- this.pool = new Pool(pool);
+ this.pool = pool;
this.out_pool = new Pool(out_pool);
this.ref = ref;
this.ep = null;
diff --git a/src/runtime/java/org/grammaticalframework/pgf/Parser.java b/src/runtime/java/org/grammaticalframework/pgf/Parser.java
index 8892d423a..c8ec3663e 100644
--- a/src/runtime/java/org/grammaticalframework/pgf/Parser.java
+++ b/src/runtime/java/org/grammaticalframework/pgf/Parser.java
@@ -6,13 +6,19 @@ class Parser implements Iterable<ExprProb> {
private Concr concr;
private String s;
private String startCat;
+ private double heuristics;
+ private Map<String,LiteralCallback> callbacks;
private ExprIterator iter;
- public Parser(Concr concr, String startCat, String s) throws ParseError {
+ public Parser(Concr concr, String startCat, String s,
+ double heuristics,
+ Map<String,LiteralCallback> callbacks) throws ParseError {
this.concr = concr;
this.startCat = startCat;
this.s = s;
- this.iter = parse(concr, startCat, s);
+ this.heuristics = heuristics;
+ this.callbacks = callbacks;
+ this.iter = doParse();
}
public Iterator<ExprProb> iterator() {
@@ -20,7 +26,7 @@ class Parser implements Iterable<ExprProb> {
// If someone has asked for a second iterator over
// the same parse results then we have to parse again.
try {
- return parse(concr, startCat, s);
+ return doParse();
} catch (ParseError e) {
return null;
}
@@ -31,5 +37,19 @@ class Parser implements Iterable<ExprProb> {
}
}
- static native ExprIterator parse(Concr concr, String startCat, String s) throws ParseError;
+ private ExprIterator doParse() throws ParseError
+ {
+ Pool pool = new Pool();
+ long callbacksRef = newCallbacksMap(concr, pool);
+ for (Map.Entry<String, LiteralCallback> entry : callbacks.entrySet()) {
+ addLiteralCallback(concr, callbacksRef,
+ entry.getKey(), entry.getValue(),
+ pool);
+ }
+ return parseWithHeuristics(concr, startCat, s, heuristics, callbacksRef, pool);
+ }
+
+ static native long newCallbacksMap(Concr concr, Pool pool);
+ static native void addLiteralCallback(Concr concr, long callbacksRef, String cat, LiteralCallback callback, Pool pool);
+ static native ExprIterator parseWithHeuristics(Concr concr, String startCat, String s, double heuristics, long callbacksRef, Pool pool) throws ParseError;
}
diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pypgf.c
index c356e5c76..c38a483f7 100644
--- a/src/runtime/python/pypgf.c
+++ b/src/runtime/python/pypgf.c
@@ -1194,17 +1194,135 @@ void pypgf_container_descructor(PyObject *capsule)
#endif
+typedef struct {
+ PgfLiteralCallback callback;
+ PyObject* pycallback;
+ GuFinalizer fin;
+} PyPgfLiteralCallback;
+
+static PgfExprProb*
+pypgf_literal_callback_match(PgfLiteralCallback* self,
+ size_t lin_idx,
+ GuString sentence, size_t* poffset,
+ GuPool *out_pool)
+{
+ PyPgfLiteralCallback* callback =
+ gu_container(self, PyPgfLiteralCallback, callback);
+
+ PyObject* result =
+ PyObject_CallFunction(callback->pycallback, "isi",
+ lin_idx, sentence, *poffset);
+ if (result == NULL || result == Py_None)
+ return NULL;
+
+ PgfExprProb* ep = gu_new(PgfExprProb, out_pool);
+
+ ExprObject* pyexpr;
+ if (!PyArg_ParseTuple(result, "Ofi", &pyexpr, &ep->prob, poffset))
+ return NULL;
+ ep->expr = pyexpr->expr;
+
+ {
+ // 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_exn(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)) {
+ PyErr_SetString(PGFError, "The expression cannot be parsed");
+ gu_pool_free(tmp_pool);
+ return NULL;
+ }
+
+ gu_pool_free(tmp_pool);
+ }
+
+ Py_DECREF(pyexpr);
+
+ return ep;
+}
+
+static GuEnum*
+pypgf_literal_callback_predict(PgfLiteralCallback* self,
+ size_t lin_idx,
+ GuString prefix,
+ GuPool *out_pool)
+{
+ return NULL;
+}
+
+static void
+pypgf_literal_callback_fin(GuFinalizer* self)
+{
+ PyPgfLiteralCallback* callback =
+ gu_container(self, PyPgfLiteralCallback, fin);
+
+ Py_XDECREF(callback->pycallback);
+}
+
+static PgfCallbacksMap*
+pypgf_new_callbacks_map(PgfConcr* concr, PyObject *py_callbacks,
+ GuPool* pool)
+{
+ PgfCallbacksMap* callbacks =
+ pgf_new_callbacks_map(concr, pool);
+
+ if (py_callbacks == NULL)
+ return callbacks;
+
+ size_t n_callbacks = PyList_Size(py_callbacks);
+ for (size_t i = 0; i < n_callbacks; i++) {
+ PyObject* item =
+ PyList_GetItem(py_callbacks, i);
+
+ PyObject* pycallback = NULL;
+ const char* cat = NULL;
+ if (!PyArg_ParseTuple(item, "sO", &cat, &pycallback))
+ return NULL;
+
+ PyPgfLiteralCallback* callback = gu_new(PyPgfLiteralCallback, pool);
+ callback->callback.match = pypgf_literal_callback_match;
+ callback->callback.predict = pypgf_literal_callback_predict;
+ callback->pycallback = pycallback;
+ callback->fin.fn = pypgf_literal_callback_fin;
+
+ gu_pool_finally(pool, &callback->fin);
+
+ pgf_callbacks_map_add_literal(concr, callbacks,
+ cat, &callback->callback);
+ }
+
+ return callbacks;
+}
+
static IterObject*
Concr_parse(ConcrObject* self, PyObject *args, PyObject *keywds)
{
- static char *kwlist[] = {"sentence", "cat", "n", "heuristics", NULL};
+ static char *kwlist[] = {"sentence", "cat", "n", "heuristics", "callbacks", NULL};
const char *sentence = NULL;
PgfCId catname = pgf_start_cat(self->grammar->pgf);
int max_count = -1;
double heuristics = -1;
- if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|sid", kwlist,
- &sentence, &catname, &max_count, &heuristics))
+ PyObject* py_callbacks = NULL;
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|sidO!", kwlist,
+ &sentence, &catname, &max_count,
+ &heuristics,
+ &PyList_Type, &py_callbacks))
return NULL;
IterObject* pyres = (IterObject*)
@@ -1229,9 +1347,13 @@ Concr_parse(ConcrObject* self, PyObject *args, PyObject *keywds)
GuExn* parse_err = gu_exn(pyres->pool);
+ PgfCallbacksMap* callbacks =
+ pypgf_new_callbacks_map(self->concr, py_callbacks, pyres->pool);
+ if (callbacks == NULL)
+ return NULL;
pyres->res =
pgf_parse_with_heuristics(self->concr, catname, sentence,
- heuristics, parse_err,
+ heuristics, callbacks, parse_err,
pyres->pool, out_pool);
if (!gu_ok(parse_err)) {
@@ -1333,120 +1455,6 @@ Concr_parseval(ConcrObject* self, PyObject *args) {
return Py_BuildValue("ddd", precision, recall, exact);
}
-typedef struct {
- PgfLiteralCallback callback;
- PyObject* pycallback;
- GuFinalizer fin;
-} PyPgfLiteralCallback;
-
-static PgfExprProb*
-pypgf_literal_callback_match(PgfLiteralCallback* self,
- size_t lin_idx,
- GuString sentence, size_t* poffset,
- GuPool *out_pool)
-{
- PyPgfLiteralCallback* callback =
- gu_container(self, PyPgfLiteralCallback, callback);
-
- PyObject* result =
- PyObject_CallFunction(callback->pycallback, "isi",
- lin_idx, sentence, *poffset);
- if (result == NULL || result == Py_None)
- return NULL;
-
- PgfExprProb* ep = gu_new(PgfExprProb, out_pool);
-
- ExprObject* pyexpr;
- if (!PyArg_ParseTuple(result, "Ofi", &pyexpr, &ep->prob, poffset))
- return NULL;
- ep->expr = pyexpr->expr;
-
- {
- // 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_exn(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)) {
- PyErr_SetString(PGFError, "The expression cannot be parsed");
- gu_pool_free(tmp_pool);
- return NULL;
- }
-
- gu_pool_free(tmp_pool);
- }
-
- Py_DECREF(pyexpr);
-
- return ep;
-}
-
-static GuEnum*
-pypgf_literal_callback_predict(PgfLiteralCallback* self,
- size_t lin_idx,
- GuString prefix,
- GuPool *out_pool)
-{
- return NULL;
-}
-
-static void
-pypgf_literal_callback_fin(GuFinalizer* self)
-{
- PyPgfLiteralCallback* callback =
- gu_container(self, PyPgfLiteralCallback, fin);
-
- Py_XDECREF(callback->pycallback);
-}
-
-static PyObject*
-Concr_addLiteral(ConcrObject* self, PyObject *args) {
- PyObject* pycallback = NULL;
- const char* cat = NULL;
- if (!PyArg_ParseTuple(args, "sO", &cat, &pycallback))
- return NULL;
-
- GuPool* pool = pgf_concr_get_pool(self->concr);
-
- PyPgfLiteralCallback* callback = gu_new(PyPgfLiteralCallback, pool);
- callback->callback.match = pypgf_literal_callback_match;
- callback->callback.predict = pypgf_literal_callback_predict;
- callback->pycallback = pycallback;
- callback->fin.fn = pypgf_literal_callback_fin;
-
- gu_pool_finally(pool, &callback->fin);
-
- GuPool* tmp_pool = gu_local_pool();
- GuExn* err = gu_exn(tmp_pool);
- pgf_concr_add_literal(self->concr, cat, &callback->callback, err);
-
- if (!gu_ok(err)) {
- if (gu_exn_caught(err, PgfExn)) {
- GuString msg = (GuString) gu_exn_caught_data(err);
- PyErr_SetString(PGFError, msg);
- } else {
- PyErr_SetString(PGFError, "The literal cannot be added");
- }
- }
-
- gu_pool_free(tmp_pool);
- Py_RETURN_NONE;
-}
-
static PyObject*
Concr_linearize(ConcrObject* self, PyObject *args)
{
@@ -2027,7 +2035,8 @@ static PyMethodDef Concr_methods[] = {
"- sentence (string) or tokens (list of strings)\n"
"- cat (string); OPTIONAL, default: the startcat of the grammar\n"
"- n (int), max. trees; OPTIONAL, default: extract all trees\n"
- "- heuristics (double >= 0.0); OPTIONAL, default: taken from the flags in the grammar"
+ "- heuristics (double >= 0.0); OPTIONAL, default: taken from the flags in the grammar\n"
+ "- callbacks (list of category and callback); OPTIONAL, default: built-in callbacks only for Int, String and Float"
},
{"complete", (PyCFunction)Concr_complete, METH_VARARGS | METH_KEYWORDS,
"Parses a partial string and returns a list with the top n possible next tokens"
@@ -2035,9 +2044,6 @@ static PyMethodDef Concr_methods[] = {
{"parseval", (PyCFunction)Concr_parseval, METH_VARARGS,
"Computes precision, recall and exact match for the parser on a given abstract tree"
},
- {"addLiteral", (PyCFunction)Concr_addLiteral, METH_VARARGS,
- "adds callbacks for custom literals in the grammar"
- },
{"linearize", (PyCFunction)Concr_linearize, METH_VARARGS,
"Takes an abstract tree and linearizes it to a string"
},