summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn J. Camilleri <john@johnjcamilleri.com>2021-05-03 22:49:31 +0200
committerGitHub <noreply@github.com>2021-05-03 22:49:31 +0200
commit70427680541cff3eac7b8dc99241913c84898082 (patch)
tree792e929d8d6062f6c2ea6610d0ca766ae88468d0
parent60bc752a6f705cca1edcd0e48bcfe947fd98b4b5 (diff)
parent84fd431afd54644bbe4bfc2c09c444f5a99e35cb (diff)
Merge pull request #107 from GrammaticalFramework/pgf2-complete
Add complete function to PGF2
-rw-r--r--src/runtime/haskell-bind/CHANGELOG.md8
-rw-r--r--src/runtime/haskell-bind/PGF2.hsc67
-rw-r--r--src/runtime/haskell-bind/PGF2/FFI.hsc8
-rw-r--r--src/runtime/haskell-bind/pgf2.cabal2
4 files changed, 75 insertions, 10 deletions
diff --git a/src/runtime/haskell-bind/CHANGELOG.md b/src/runtime/haskell-bind/CHANGELOG.md
index aed2d9c4f..570c7fd73 100644
--- a/src/runtime/haskell-bind/CHANGELOG.md
+++ b/src/runtime/haskell-bind/CHANGELOG.md
@@ -1,7 +1,11 @@
+## 1.3.0
+
+- Add completion support.
+
## 1.2.1
-- Remove deprecated pgf_print_expr_tuple
-- Added an API for cloning expressions/types/literals
+- Remove deprecated `pgf_print_expr_tuple`.
+- Added an API for cloning expressions/types/literals.
## 1.2.0
diff --git a/src/runtime/haskell-bind/PGF2.hsc b/src/runtime/haskell-bind/PGF2.hsc
index 4204867f1..38fae67ef 100644
--- a/src/runtime/haskell-bind/PGF2.hsc
+++ b/src/runtime/haskell-bind/PGF2.hsc
@@ -43,32 +43,28 @@ module PGF2 (-- * PGF
mkCId,
exprHash, exprSize, exprFunctions, exprSubstitute,
treeProbability,
-
-- ** Types
Type, Hypo, BindType(..), startCat,
readType, showType, showContext,
mkType, unType,
-
-- ** Type checking
-- | Dynamically-built expressions should always be type-checked before using in other functions,
-- as the exceptions thrown by using invalid expressions may not catchable.
checkExpr, inferExpr, checkType,
-
-- ** Computing
compute,
-- * Concrete syntax
ConcName,Concr,languages,concreteName,languageCode,
-
-- ** Linearization
linearize,linearizeAll,tabularLinearize,tabularLinearizeAll,bracketedLinearize,bracketedLinearizeAll,
FId, BracketedString(..), showBracketedString, flattenBracketedString,
printName, categoryFields,
-
alignWords,
-- ** Parsing
ParseOutput(..), parse, parseWithHeuristics,
parseToChart, PArg(..),
+ complete,
-- ** Sentence Lookup
lookupSentence,
-- ** Generation
@@ -976,6 +972,67 @@ parseWithOracle lang cat sent (predict,complete,literal) =
return ep
Nothing -> do return nullPtr
+-- | Returns possible completions of the current partial input.
+complete :: Concr -- ^ the language with which we parse
+ -> Type -- ^ the start category
+ -> String -- ^ the input sentence (excluding token being completed)
+ -> String -- ^ prefix (partial token being completed)
+ -> ParseOutput [(String, CId, CId, Float)] -- ^ (token, category, function, probability)
+complete lang (Type ctype _) sent pfx =
+ unsafePerformIO $ do
+ parsePl <- gu_new_pool
+ exn <- gu_new_exn parsePl
+ sent <- newUtf8CString sent parsePl
+ pfx <- newUtf8CString pfx parsePl
+ enum <- pgf_complete (concr lang) ctype sent pfx exn parsePl
+ failed <- gu_exn_is_raised exn
+ if failed
+ then do
+ is_parse_error <- gu_exn_caught exn gu_exn_type_PgfParseError
+ if is_parse_error
+ then do
+ c_err <- (#peek GuExn, data.data) exn
+ c_offset <- (#peek PgfParseError, offset) c_err
+ token_ptr <- (#peek PgfParseError, token_ptr) c_err
+ token_len <- (#peek PgfParseError, token_len) c_err
+ tok <- peekUtf8CStringLen token_ptr token_len
+ gu_pool_free parsePl
+ return (ParseFailed (fromIntegral (c_offset :: CInt)) tok)
+ else do
+ is_exn <- gu_exn_caught exn gu_exn_type_PgfExn
+ if is_exn
+ then do
+ c_msg <- (#peek GuExn, data.data) exn
+ msg <- peekUtf8CString c_msg
+ gu_pool_free parsePl
+ throwIO (PGFError msg)
+ else do
+ gu_pool_free parsePl
+ throwIO (PGFError "Parsing failed")
+ else do
+ fpl <- newForeignPtr gu_pool_finalizer parsePl
+ ParseOk <$> fromCompletions enum fpl
+ where
+ fromCompletions :: Ptr GuEnum -> ForeignPtr GuPool -> IO [(String, CId, CId, Float)]
+ fromCompletions enum fpl =
+ withGuPool $ \tmpPl -> do
+ cmpEntry <- alloca $ \ptr ->
+ withForeignPtr fpl $ \pl ->
+ do gu_enum_next enum ptr pl
+ peek ptr
+ if cmpEntry == nullPtr
+ then do
+ finalizeForeignPtr fpl
+ touchConcr lang
+ return []
+ else do
+ tok <- peekUtf8CString =<< (#peek PgfTokenProb, tok) cmpEntry
+ cat <- peekUtf8CString =<< (#peek PgfTokenProb, cat) cmpEntry
+ fun <- peekUtf8CString =<< (#peek PgfTokenProb, fun) cmpEntry
+ prob <- (#peek PgfTokenProb, prob) cmpEntry
+ toks <- unsafeInterleaveIO (fromCompletions enum fpl)
+ return ((tok, cat, fun, prob) : toks)
+
-- | Returns True if there is a linearization defined for that function in that language
hasLinearization :: Concr -> Fun -> Bool
hasLinearization lang id = unsafePerformIO $
diff --git a/src/runtime/haskell-bind/PGF2/FFI.hsc b/src/runtime/haskell-bind/PGF2/FFI.hsc
index c72c48e3b..16f9ad46d 100644
--- a/src/runtime/haskell-bind/PGF2/FFI.hsc
+++ b/src/runtime/haskell-bind/PGF2/FFI.hsc
@@ -103,7 +103,7 @@ foreign import ccall unsafe "gu/file.h gu_file_in"
foreign import ccall safe "gu/enum.h gu_enum_next"
gu_enum_next :: Ptr a -> Ptr (Ptr b) -> Ptr GuPool -> IO ()
-
+
foreign import ccall unsafe "gu/string.h gu_string_buf_freeze"
gu_string_buf_freeze :: Ptr GuStringBuf -> Ptr GuPool -> IO CString
@@ -241,7 +241,7 @@ newSequence elem_size pokeElem values pool = do
type FId = Int
data PArg = PArg [FId] {-# UNPACK #-} !FId deriving (Eq,Ord,Show)
-peekFId :: Ptr a -> IO FId
+peekFId :: Ptr a -> IO FId
peekFId c_ccat = do
c_fid <- (#peek PgfCCat, fid) c_ccat
return (fromIntegral (c_fid :: CInt))
@@ -256,6 +256,7 @@ data PgfApplication
data PgfConcr
type PgfExpr = Ptr ()
data PgfExprProb
+data PgfTokenProb
data PgfExprParser
data PgfFullFormEntry
data PgfMorphoCallback
@@ -422,6 +423,9 @@ foreign import ccall
foreign import ccall "pgf/pgf.h pgf_parse_with_oracle"
pgf_parse_with_oracle :: Ptr PgfConcr -> CString -> CString -> Ptr PgfOracleCallback -> Ptr GuExn -> Ptr GuPool -> Ptr GuPool -> IO (Ptr GuEnum)
+foreign import ccall "pgf/pgf.h pgf_complete"
+ pgf_complete :: Ptr PgfConcr -> PgfType -> CString -> CString -> Ptr GuExn -> Ptr GuPool -> IO (Ptr GuEnum)
+
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/pgf2.cabal b/src/runtime/haskell-bind/pgf2.cabal
index 4ef9ed4f0..91e77c77b 100644
--- a/src/runtime/haskell-bind/pgf2.cabal
+++ b/src/runtime/haskell-bind/pgf2.cabal
@@ -1,5 +1,5 @@
name: pgf2
-version: 1.2.1
+version: 1.3.0
synopsis: Bindings to the C version of the PGF runtime
description:
GF, Grammatical Framework, is a programming language for multilingual grammar applications.