mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-09 04:59:31 -06:00
313 lines
12 KiB
C#
313 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
/// <summary>
|
|
/// Portable grammar format PInvoke functions.
|
|
/// </summary>
|
|
namespace PGFSharp
|
|
{
|
|
internal static class Native
|
|
{
|
|
|
|
internal class NativeString : IDisposable
|
|
{
|
|
public IntPtr Ptr { get; private set; }
|
|
public int Size { get; private set; }
|
|
|
|
public NativeString(string s)
|
|
{
|
|
Ptr = NativeUtf8FromString(s);
|
|
Size = Encoding.UTF8.GetByteCount(s);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Marshal.FreeHGlobal(Ptr);
|
|
Ptr = IntPtr.Zero;
|
|
}
|
|
|
|
public static IntPtr NativeUtf8FromString(string managedString)
|
|
{
|
|
int len = Encoding.UTF8.GetByteCount(managedString);
|
|
IntPtr nativeUtf8 = Marshal.AllocHGlobal(len + 1);
|
|
CopyToPreallocated(managedString, nativeUtf8, len);
|
|
return nativeUtf8;
|
|
}
|
|
|
|
public static void CopyToPreallocated(string managedString, IntPtr ptr, int? len = null)
|
|
{
|
|
if (len == null) len = Encoding.UTF8.GetByteCount(managedString);
|
|
byte[] buffer = new byte[len.Value + 1];
|
|
Encoding.UTF8.GetBytes(managedString, 0, managedString.Length, buffer, 0);
|
|
Marshal.Copy(buffer, 0, ptr, buffer.Length);
|
|
}
|
|
|
|
public static string StringFromNativeUtf8(IntPtr nativeUtf8)
|
|
{
|
|
int len = 0;
|
|
while (Marshal.ReadByte(nativeUtf8, len) != 0) ++len;
|
|
byte[] buffer = new byte[len];
|
|
Marshal.Copy(nativeUtf8, buffer, 0, buffer.Length);
|
|
return Encoding.UTF8.GetString(buffer);
|
|
}
|
|
}
|
|
|
|
public delegate void StructAction<T>(ref T st);
|
|
public static void EditStruct<T>(IntPtr ptr, StructAction<T> f)
|
|
{
|
|
var str = Marshal.PtrToStructure<T>(ptr);
|
|
f(ref str);
|
|
Marshal.StructureToPtr<T>(str, ptr, false);
|
|
}
|
|
|
|
const string LIBNAME = "pgf.dll";
|
|
const CallingConvention CC = CallingConvention.Cdecl;
|
|
|
|
|
|
#region Basic
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern IntPtr pgf_read([MarshalAs(UnmanagedType.LPStr)] string fpath, IntPtr pool, IntPtr err);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern IntPtr pgf_read_in(IntPtr in_, IntPtr pool, IntPtr tmp_pool, IntPtr err);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern void pgf_concrete_load(IntPtr concr, IntPtr in_, IntPtr err);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern IntPtr pgf_abstract_name(IntPtr pgf);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern IntPtr pgf_concrete_name(IntPtr concr);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern IntPtr pgf_start_cat(IntPtr pgf, IntPtr pool);
|
|
|
|
#endregion
|
|
|
|
#region Linearization
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern void pgf_linearize(IntPtr concr, IntPtr expr, IntPtr out_, IntPtr err);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern IntPtr pgf_lzr_concretize(IntPtr concr, IntPtr expr, IntPtr err, IntPtr tmp_pool);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern IntPtr pgf_lzr_wrap_linref(IntPtr ctree, IntPtr tmp_pool);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern void pgf_lzr_linearize(IntPtr concr, IntPtr ctree, int lin_idx, ref IntPtr funcs, IntPtr tmp_pool);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern void pgf_lzr_linearize_simple(IntPtr concr, IntPtr ctree, int lin_idx, IntPtr out_, IntPtr exn, IntPtr tmp_pool);
|
|
#endregion
|
|
|
|
|
|
#region Iteration
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern void pgf_iter_languages(IntPtr pgf, ref GuMapItor itor, IntPtr err);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern void pgf_iter_categories(IntPtr pgf, ref GuMapItor itor, IntPtr err);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern void pgf_iter_functions(IntPtr pgf, ref GuMapItor itor, IntPtr err);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern void pgf_iter_functions_by_cat(IntPtr pgf, IntPtr catNameStr, ref GuMapItor itor, IntPtr err);
|
|
|
|
#endregion
|
|
|
|
#region Type
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern IntPtr pgf_function_type(IntPtr pgf, IntPtr funNameStr);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern IntPtr pgf_read_type(IntPtr in_, IntPtr pool, IntPtr err);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern void pgf_print_type(IntPtr expr, IntPtr ctxt, int prec, IntPtr output, IntPtr err);
|
|
#endregion
|
|
|
|
#region Expression
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern void pgf_print_expr(IntPtr expr, IntPtr ctxt, int prec, IntPtr output, IntPtr err);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern IntPtr pgf_read_expr(IntPtr in_, IntPtr pool, IntPtr err);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern IntPtr pgf_compute(IntPtr pgf, IntPtr expr, IntPtr err, IntPtr tmp_pool, IntPtr res_pool);
|
|
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern IntPtr pgf_generate_all(IntPtr pgf, IntPtr type, IntPtr err, IntPtr iter_pool, IntPtr out_pool);
|
|
#endregion
|
|
|
|
#region Concrete
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern IntPtr pgf_parse_with_heuristics(IntPtr concr, IntPtr cat, IntPtr sentence,
|
|
double heuristics, IntPtr callbacks, IntPtr exn,
|
|
IntPtr parsePl, IntPtr exprPl);
|
|
#endregion
|
|
|
|
#region Callbacks
|
|
[DllImport(LIBNAME, CallingConvention = CC)]
|
|
public static extern IntPtr pgf_new_callbacks_map(IntPtr concr, IntPtr pool);
|
|
#endregion
|
|
|
|
//public delegate void GuMapItorFn(IntPtr self, [MarshalAs(UnmanagedType.LPStr)] string key, IntPtr value, IntPtr err);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
public delegate void GuMapItorFn(IntPtr self, IntPtr key, IntPtr value, IntPtr err);
|
|
|
|
|
|
/*
|
|
public delegate void GuFinalizerFn(IntPtr self);
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct GuFinalizer
|
|
{
|
|
[MarshalAs(UnmanagedType.FunctionPtr)]
|
|
public GuFinalizerFn fn;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct PgfConcr
|
|
{
|
|
public IntPtr name, abstr, cflags, printnames,
|
|
ccats, fun_indices, coerce_idx, cncfuns,
|
|
sequences, cnccats;
|
|
public int total_cats;
|
|
public IntPtr pool;
|
|
GuFinalizer fin;
|
|
}*/
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct GuMapItor
|
|
{
|
|
[MarshalAs(UnmanagedType.FunctionPtr)]
|
|
public GuMapItorFn fn;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct PgfExprProb
|
|
{
|
|
public float prob;
|
|
public IntPtr expr; // PgfExpr type (not pointer, but typedef PgfExpr -> GuVariant -> uintptr_t)
|
|
}
|
|
|
|
|
|
#region Linearization callbacks
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
public delegate void LinFuncSymbolToken(IntPtr self, IntPtr token);
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
public delegate void LinFuncBeginPhrase(IntPtr self, IntPtr cat, int fid, int lindex, IntPtr fun);
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
public delegate void LinFuncEndPhrase(IntPtr self, IntPtr cat, int fid, int lindex, IntPtr fun);
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
public delegate void LinFuncSymbolNonexistant(IntPtr self);
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
public delegate void LinFuncSymbolBinding(IntPtr self);
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
public delegate void LinFuncSymbolCapitalization(IntPtr self);
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
public delegate void LinFuncSymbolMeta(IntPtr self, int meta_id);
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct PgfLinFuncs
|
|
{
|
|
[MarshalAs(UnmanagedType.FunctionPtr)]
|
|
public LinFuncSymbolToken symbol_token;
|
|
|
|
[MarshalAs(UnmanagedType.FunctionPtr)]
|
|
public LinFuncBeginPhrase begin_prase;
|
|
|
|
[MarshalAs(UnmanagedType.FunctionPtr)]
|
|
public LinFuncEndPhrase end_phrase;
|
|
|
|
[MarshalAs(UnmanagedType.FunctionPtr)]
|
|
public LinFuncSymbolNonexistant symbol_ne;
|
|
|
|
[MarshalAs(UnmanagedType.FunctionPtr)]
|
|
public LinFuncSymbolBinding symbol_bind;
|
|
|
|
[MarshalAs(UnmanagedType.FunctionPtr)]
|
|
public LinFuncSymbolCapitalization symbol_capit;
|
|
|
|
[MarshalAs(UnmanagedType.FunctionPtr)]
|
|
public LinFuncSymbolMeta symbol_meta;
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
/*
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct PGFClosure
|
|
{
|
|
public GuMapItor fn;
|
|
public IntPtr grammar;
|
|
public IntPtr obj;
|
|
}*/
|
|
|
|
public static string ReadString(Action<IntPtr, NativeGU.NativeExceptionContext> f)
|
|
{
|
|
var pool = new NativeGU.NativeMemoryPool();
|
|
var exn = new NativeGU.NativeExceptionContext(pool);
|
|
var sbuf = NativeGU.gu_new_string_buf(pool.Ptr);
|
|
var output = NativeGU.gu_string_buf_out(sbuf);
|
|
f(output, exn);
|
|
if (exn.IsRaised) throw new Exception();
|
|
var strPtr = NativeGU.gu_string_buf_freeze(sbuf, pool.Ptr);
|
|
var str = Native.NativeString.StringFromNativeUtf8(strPtr);
|
|
return str;
|
|
}
|
|
|
|
public delegate void MapIterFunc(IntPtr pgf, ref GuMapItor fn, IntPtr err);
|
|
public delegate void IterNameFunc(IntPtr pgf, IntPtr name, ref GuMapItor fn, IntPtr err);
|
|
|
|
public class IterFuncCurryName
|
|
{
|
|
private IntPtr name;
|
|
private IterNameFunc func;
|
|
public IterFuncCurryName(IterNameFunc f, IntPtr name)
|
|
{
|
|
this.func = f;
|
|
this.name = name;
|
|
}
|
|
|
|
public void IterFunc(IntPtr pgf, ref GuMapItor fn, IntPtr err)
|
|
{
|
|
func(pgf, name, ref fn, err);
|
|
}
|
|
}
|
|
|
|
public static void MapIter(MapIterFunc iter, IntPtr _pgf, Action<string, IntPtr> action)
|
|
{
|
|
var pool = new NativeGU.NativeMemoryPool();
|
|
var exn = new NativeGU.NativeExceptionContext(pool);
|
|
var f = new GuMapItor()
|
|
{
|
|
fn = (self, key, value, _err) =>
|
|
{
|
|
action(Native.NativeString.StringFromNativeUtf8(key), value);
|
|
if (exn.IsRaised) throw new Exception();
|
|
}
|
|
};
|
|
|
|
iter(_pgf, ref f, exn.Ptr);
|
|
}
|
|
}
|
|
}
|