forked from GitHub/gf-core
Compare commits
154 Commits
GF-3.10
...
js-binding
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c91c325be | ||
|
|
ba93141317 | ||
|
|
12079550f8 | ||
|
|
1ceb8c0342 | ||
|
|
eab9fb88aa | ||
|
|
acd4a5e8cd | ||
|
|
a4b1fb03aa | ||
|
|
cb88b56016 | ||
|
|
ecf9b41db0 | ||
|
|
c5a75c482c | ||
|
|
32379a8d11 | ||
|
|
b56591c6b6 | ||
|
|
b94bb50ec9 | ||
|
|
e2395335cb | ||
|
|
2d9478b973 | ||
|
|
17e3f753fb | ||
|
|
498ad572ac | ||
|
|
bc61f8c191 | ||
|
|
d252cfd610 | ||
|
|
46a1bdc7ea | ||
|
|
18d0e1fad0 | ||
|
|
ab94e93b94 | ||
|
|
a229507392 | ||
|
|
6a9c917b29 | ||
|
|
9ba4a42426 | ||
|
|
bbd1c9147a | ||
|
|
4793d376d9 | ||
|
|
63606fd2d0 | ||
|
|
d6a1e87f4a | ||
|
|
ffcdaa921f | ||
|
|
f2e03bfc51 | ||
|
|
c89656f3ee | ||
|
|
c9b4318e9e | ||
|
|
1e43e7be4b | ||
|
|
44261b7582 | ||
|
|
b980bce334 | ||
|
|
bd7753db1a | ||
|
|
8c18d7162f | ||
|
|
ac039ec74f | ||
|
|
9f0ea19a1c | ||
|
|
8df2121650 | ||
|
|
8b9719bd2d | ||
|
|
b7249adf63 | ||
|
|
7a3efdfeb9 | ||
|
|
86066d4b12 | ||
|
|
af62a99bf5 | ||
|
|
ac1f304722 | ||
|
|
92720b92a4 | ||
|
|
078440ffbf | ||
|
|
68919a5e42 | ||
|
|
a5a019a124 | ||
|
|
61fe167392 | ||
|
|
fd29925173 | ||
|
|
bea6aa1d2d | ||
|
|
c628e11c01 | ||
|
|
61e7df4d1c | ||
|
|
de53a7c4db | ||
|
|
1e9188ea60 | ||
|
|
a55c7c7889 | ||
|
|
b3387e80e4 | ||
|
|
de0a997fcd | ||
|
|
0f53431221 | ||
|
|
099f2de5b4 | ||
|
|
2f2b39c5d2 | ||
|
|
f3d7d55752 | ||
|
|
2979864752 | ||
|
|
b11d7d93dc | ||
|
|
ba9aeb3322 | ||
|
|
8e2424af49 | ||
|
|
01b9e8da8d | ||
|
|
926a5cf414 | ||
|
|
21140fc0c0 | ||
|
|
3328279120 | ||
|
|
8cf4446e8c | ||
|
|
5b401f3880 | ||
|
|
b783299b73 | ||
|
|
0970d678cf | ||
|
|
bf17fa0bb2 | ||
|
|
0b3c278f49 | ||
|
|
c710bf0e84 | ||
|
|
eb46577f58 | ||
|
|
52f2739da1 | ||
|
|
fc37bc26cd | ||
|
|
bde1a6d586 | ||
|
|
25dc934871 | ||
|
|
2fdfef13d8 | ||
|
|
a928e4657e | ||
|
|
b6fd9a7744 | ||
|
|
64a2483b12 | ||
|
|
1d1e65185a | ||
|
|
c32cd7133f | ||
|
|
409731413e | ||
|
|
8a5e7fa25d | ||
|
|
e05c79a751 | ||
|
|
ef21d08225 | ||
|
|
f8346c4557 | ||
|
|
47ac01e4b9 | ||
|
|
a0c1da2548 | ||
|
|
951b884118 | ||
|
|
fc5c2b5a22 | ||
|
|
e4abff7725 | ||
|
|
a40130ddc4 | ||
|
|
71307d6518 | ||
|
|
fc1b51aa95 | ||
|
|
5fe963dd02 | ||
|
|
f32d222e71 | ||
|
|
a131b244df | ||
|
|
0accd97691 | ||
|
|
f8bd35543c | ||
|
|
a7b10ea936 | ||
|
|
7c97e5566d | ||
|
|
7288425daf | ||
|
|
260c0d07e0 | ||
|
|
26dabeab9b | ||
|
|
f7c2fb8a7d | ||
|
|
4bda53acb7 | ||
|
|
54204d2d95 | ||
|
|
9834b89a30 | ||
|
|
b3a2b53df2 | ||
|
|
77c0a8e100 | ||
|
|
86233e9c28 | ||
|
|
40e7544a2b | ||
|
|
61c1510620 | ||
|
|
eb22112178 | ||
|
|
083aa96e57 | ||
|
|
d82a53ebc6 | ||
|
|
5006b520d1 | ||
|
|
f78dfe80a2 | ||
|
|
44ac326da0 | ||
|
|
a8b23d52a8 | ||
|
|
d880a61857 | ||
|
|
7bd086ba19 | ||
|
|
ff0fe0a6c5 | ||
|
|
ef4df27d1b | ||
|
|
e9e2bd6b89 | ||
|
|
72a9eb0c8a | ||
|
|
b73f033b08 | ||
|
|
b974c09951 | ||
|
|
159b6ee331 | ||
|
|
3dec78c21c | ||
|
|
6ad9bf3dbf | ||
|
|
ee5ac81dfc | ||
|
|
1a842efeaf | ||
|
|
de005b9df3 | ||
|
|
52bc0f566e | ||
|
|
b509d08cbf | ||
|
|
fd0ee2756a | ||
|
|
34e89ac710 | ||
|
|
331d73b566 | ||
|
|
8d460ac402 | ||
|
|
5546c6d6da | ||
|
|
c380288db8 | ||
|
|
bd7bb9b34a | ||
|
|
18251e57a3 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -49,11 +49,12 @@ demos/index-numbers.html
|
||||
demos/resourcegrammars.html
|
||||
demos/translation.html
|
||||
doc/tutorial/gf-tutorial.html
|
||||
doc/index.html
|
||||
doc/gf-bibliography.html
|
||||
doc/gf-developers.html
|
||||
doc/gf-editor-modes.html
|
||||
doc/gf-people.html
|
||||
doc/gf-reference.html
|
||||
doc/gf-refman.html
|
||||
doc/gf-shell-reference.html
|
||||
doc/icfp-2012.html
|
||||
download/*.html
|
||||
|
||||
5
Setup.hs
5
Setup.hs
@@ -1,3 +1,4 @@
|
||||
import Distribution.System(Platform(..),OS(..))
|
||||
import Distribution.Simple(defaultMainWithHooks,UserHooks(..),simpleUserHooks)
|
||||
import Distribution.Simple.LocalBuildInfo(LocalBuildInfo(..),absoluteInstallDirs,datadir)
|
||||
import Distribution.Simple.Setup(BuildFlags(..),Flag(..),InstallFlags(..),CopyDest(..),CopyFlags(..),SDistFlags(..))
|
||||
@@ -73,5 +74,9 @@ dataDirFile = "DATA_DIR"
|
||||
default_gf :: LocalBuildInfo -> FilePath
|
||||
default_gf lbi = buildDir lbi </> exeName' </> exeNameReal
|
||||
where
|
||||
-- shadows Distribution.Simple.BuildPaths.exeExtension, which changed type signature in Cabal 2.4
|
||||
exeExtension = case hostPlatform lbi of
|
||||
Platform arch Windows -> "exe"
|
||||
_ -> ""
|
||||
exeName' = "gf"
|
||||
exeNameReal = exeName' <.> exeExtension
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### This script builds a binary distribution of GF from the source
|
||||
### package that this script is a part of. It assumes that you have installed
|
||||
### the Haskell Platform, version 2013.2.0.0 or 2012.4.0.0.
|
||||
### a recent version of the Haskell Platform.
|
||||
### Two binary package formats are supported: plain tar files (.tar.gz) and
|
||||
### OS X Installer packages (.pkg).
|
||||
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
### This script finds all .t2t (txt2tags) files and deletes the corresponding html file
|
||||
# This script finds all .t2t (txt2tags) and .md (Markdown) files
|
||||
# and deletes the corresponding HTML file of the same name.
|
||||
|
||||
find . -name '*.t2t' | while read t2t ; do
|
||||
html="${t2t%.t2t}.html"
|
||||
rm -f "$html"
|
||||
if [ -f "$html" ] ; then
|
||||
echo "$html"
|
||||
rm -f "$html"
|
||||
fi
|
||||
done
|
||||
|
||||
find . -name '*.md' | while read md ; do
|
||||
html="${md%.md}.html"
|
||||
if [ -f "$html" ] ; then
|
||||
echo "$html"
|
||||
rm -f "$html"
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -28,16 +28,17 @@ $for(header-includes)$
|
||||
$header-includes$
|
||||
$endfor$
|
||||
</head>
|
||||
<body>
|
||||
<body class="bg-light">
|
||||
<div class="bg-white pb-5">
|
||||
$for(include-before)$
|
||||
$include-before$
|
||||
$endfor$
|
||||
<div class="container-fluid my-5" style="max-width:1200px">
|
||||
<div class="container-fluid py-5" style="max-width:1200px">
|
||||
|
||||
$if(title)$
|
||||
<header id="title-block-header">
|
||||
<a href="$rel-root$" title="Home">
|
||||
<img src="$rel-root$/doc/Logos/gf1.svg" height="200px" class="float-md-right mb-3 bg-white" alt="GF Logo">
|
||||
<img src="$rel-root$/doc/Logos/gf1.svg" height="200" class="float-md-right ml-3 mb-3 bg-white" alt="GF Logo">
|
||||
</a>
|
||||
<h1 class="title">$title$</h1>
|
||||
$if(subtitle)$
|
||||
@@ -53,13 +54,20 @@ $endif$
|
||||
$endif$
|
||||
$if(toc)$
|
||||
<nav id="$idprefix$TOC">
|
||||
$table-of-contents$
|
||||
$if(table-of-contents)$
|
||||
<!-- pandoc >= 2.0 -->
|
||||
$table-of-contents$
|
||||
$else$
|
||||
<!-- pandoc < 2.0 -->
|
||||
$toc$
|
||||
$endif$
|
||||
</nav>
|
||||
$endif$
|
||||
$body$
|
||||
</div><!-- .container -->
|
||||
</div><!-- .bg-white -->
|
||||
|
||||
<footer class="bg-light mt-5 py-5">
|
||||
<footer class="py-5">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
|
||||
@@ -72,7 +80,11 @@ $body$
|
||||
<ul class="list-unstyled">
|
||||
<li><a href="https://www.youtube.com/watch?v=x1LFbDQhbso">Google Tech Talk</a></li>
|
||||
<li><a href="http://cloud.grammaticalframework.org/">GF Cloud</a></li>
|
||||
<li><a href="$rel-root$/doc/tutorial/gf-tutorial.html">Tutorial</a></li>
|
||||
<li>
|
||||
<a href="$rel-root$/doc/tutorial/gf-tutorial.html">Tutorial</a>
|
||||
/
|
||||
<a href="$rel-root$/lib/doc/rgl-tutorial/index.html">RGL Tutorial</a>
|
||||
</li>
|
||||
<li><a href="$rel-root$/download"><strong>Download GF</strong></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -100,8 +112,7 @@ $body$
|
||||
</div>
|
||||
|
||||
<div class="col-6 col-sm-3">
|
||||
<h6 class="text-muted">Contribute</i>
|
||||
</h6>
|
||||
<h6 class="text-muted">Contribute</h6>
|
||||
<ul class="list-unstyled">
|
||||
<li><a href="http://groups.google.com/group/gf-dev">Mailing List</a></li>
|
||||
<li><a href="https://github.com/GrammaticalFramework/gf-core/issues">Issue Tracker</a></li>
|
||||
@@ -116,8 +127,8 @@ $body$
|
||||
<a href="https://github.com/GrammaticalFramework/gf-rgl">RGL</a> ·
|
||||
<a href="https://github.com/GrammaticalFramework/gf-contrib">Contributions</a>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
$for(include-after)$
|
||||
$include-after$
|
||||
|
||||
@@ -1,9 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Generate HTML from txt2tags (.t2t) and Markdown (.md)
|
||||
# Usage:
|
||||
# - update_html
|
||||
# Look for all .t2t and .md files in the current directory and below,
|
||||
# generating the output HTML when the source is newer than the HTML.
|
||||
# - update_html path/to/file.t2t path/to/another.md
|
||||
# Generate HTML for the specified file(s), ignoring modification time.
|
||||
#
|
||||
# Requires:
|
||||
# - txt2tags for .t2t files. Tested with 2.6.
|
||||
# - pandoc for both .t2t and .md files. Tested with 1.16.0.2 and 2.3.1.
|
||||
# - the template file `template.html` in the same directory as this script.
|
||||
#
|
||||
# Tested with Ubuntu 16.04 and macOS Mojave.
|
||||
#
|
||||
# See also clean_html for removing the files generated by this script.
|
||||
|
||||
# Path to directory where this script is
|
||||
# https://stackoverflow.com/a/246128/98600
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||
|
||||
# HTML template
|
||||
template="$DIR/template.html"
|
||||
|
||||
# Render txt2tags into html file
|
||||
# Arguments:
|
||||
# 1. txt2tags source file, e.g. download/index.t2t
|
||||
@@ -22,6 +42,12 @@ function render_t2t_html {
|
||||
--outfile="$tmp" \
|
||||
--infile="$t2t"
|
||||
|
||||
# Replace <A NAME="toc3"></A> with <div id="toc3"></div> so that Pandoc retains it
|
||||
# Do this for both cases since BSD sed doesn't support /i
|
||||
sed -i.bak "s/<a name=\"\(.*\)\"><\/a>/<div id=\"\1\"><\/div>/" "$tmp"
|
||||
sed -i.bak "s/<A NAME=\"\(.*\)\"><\/A>/<div id=\"\1\"><\/div>/" "$tmp"
|
||||
rm -f "$tmp.bak"
|
||||
|
||||
# Capture first 3 lines of t2t file: title, author, date
|
||||
# Documentation here: https://txt2tags.org/userguide/headerarea
|
||||
l1=$(head -n 1 "$t2t")
|
||||
@@ -41,7 +67,8 @@ function render_t2t_html {
|
||||
--from=html \
|
||||
--to=html5 \
|
||||
--standalone \
|
||||
--template="$DIR/template.html" \
|
||||
--template="$template" \
|
||||
--variable="lang:en" \
|
||||
--variable="rel-root:$relroot" \
|
||||
--metadata="title:$title" \
|
||||
--metadata="author:$author" \
|
||||
@@ -60,28 +87,43 @@ function render_t2t_html {
|
||||
# Render markdown into html file
|
||||
# Arguments:
|
||||
# 1. markdown source file, e.g. download/index.md
|
||||
# 2. html target filen, e.g. download/index.html
|
||||
# 2. html target file, e.g. download/index.html
|
||||
function render_md_html {
|
||||
md="$1"
|
||||
html="$2"
|
||||
relroot="$( dirname $md | sed -E 's/^.\///' | sed -E 's/[^/]+/../g' )"
|
||||
|
||||
# Look for `show-toc: true` in metadata (first ten lines of file)
|
||||
if head -n 10 "$md" | grep --quiet 'show-toc: true' ; then
|
||||
tocflag='--table-of-contents'
|
||||
else
|
||||
tocflag=''
|
||||
fi
|
||||
|
||||
pandoc \
|
||||
--from=markdown \
|
||||
--to=html5 \
|
||||
--standalone \
|
||||
--template="$DIR/template.html" \
|
||||
$tocflag \
|
||||
--template="$template" \
|
||||
--variable="lang:en" \
|
||||
--variable="rel-root:$relroot" \
|
||||
"$md" \
|
||||
--output="$html"
|
||||
|
||||
# Final post-processing
|
||||
if [ -f "$html" ] ; then
|
||||
sed -i.bak "s/<table/<table class=\"table\"/" "$html" && rm "$html.bak"
|
||||
# add "table" class to tables
|
||||
sed -i.bak "s/<table/<table class=\"table\"/" "$html"
|
||||
# rewrite anchors that Pandoc 1.16 ignores: [content]{#anchor} -> <span id="anchor">content</span>
|
||||
sed -i.bak -E "s/\[(.*)\]\{#(.+)\}/<span id=\"\2\">\1<\/span>/" "$html"
|
||||
rm -f "$html.bak"
|
||||
echo "$html"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main entry point
|
||||
# Script can be run in one of two modes:
|
||||
if [ $# -gt 0 ] ; then
|
||||
# Render specific file(s) from args, ignoring dates
|
||||
for file in "$@" ; do
|
||||
@@ -100,14 +142,14 @@ else
|
||||
# Render all files found in cwd and deeper if source is newer
|
||||
find . -name '*.t2t' | while read file ; do
|
||||
html="${file%.t2t}.html"
|
||||
if [ "$file" -nt "$html" ] ; then
|
||||
if [ "$file" -nt "$html" ] || [ "$template" -nt "$html" ] ; then
|
||||
render_t2t_html "$file" "$html"
|
||||
fi
|
||||
done
|
||||
find . -name '*.md' | while read file ; do
|
||||
if [[ "$file" == *"README.md" ]] ; then continue ; fi
|
||||
html="${file%.md}.html"
|
||||
if [ "$file" -nt "$html" ] ; then
|
||||
if [ "$file" -nt "$html" ] || [ "$template" -nt "$html" ] ; then
|
||||
render_md_html "$file" "$html"
|
||||
fi
|
||||
done
|
||||
|
||||
14
debian/changelog
vendored
14
debian/changelog
vendored
@@ -1,8 +1,20 @@
|
||||
gf (3.10.3-1) xenial bionic cosmic; urgency=low
|
||||
|
||||
* GF 3.10.3
|
||||
|
||||
-- Thomas Hallgren <hallgren@chalmers.se> Fri, 5 Mar 2019 19:30:00 +0100
|
||||
|
||||
gf (3.10-2) xenial bionic cosmic; urgency=low
|
||||
|
||||
* GF 3.10
|
||||
|
||||
-- Thomas Hallgren <hallgren@chalmers.se> Fri, 5 Mar 2019 16:00:00 +0100
|
||||
|
||||
gf (3.10-1) xenial bionic cosmic; urgency=low
|
||||
|
||||
* GF 3.10
|
||||
|
||||
-- Thomas Hallgren <hallgren@chalmers.se> Fri, 30 Nov 2018 20:00:00 +0100
|
||||
-- Thomas Hallgren <hallgren@chalmers.se> Fri, 2 Dec 2018 15:00:00 +0100
|
||||
|
||||
gf (3.9-1) vivid xenial zesty; urgency=low
|
||||
|
||||
|
||||
2
debian/control
vendored
2
debian/control
vendored
@@ -3,7 +3,7 @@ Section: devel
|
||||
Priority: optional
|
||||
Maintainer: Thomas Hallgren <hallgren@chalmers.se>
|
||||
Standards-Version: 3.9.2
|
||||
Build-Depends: debhelper (>= 5), haskell-platform (>= 2011.2.0.1), libghc-haskeline-dev, libghc-mtl-dev, libghc-json-dev, autoconf, automake, libtool-bin, python-dev, java-sdk, txt2tags
|
||||
Build-Depends: debhelper (>= 5), haskell-platform (>= 2011.2.0.1), libghc-haskeline-dev, libghc-mtl-dev, libghc-json-dev, autoconf, automake, libtool-bin, python-dev, java-sdk, txt2tags, pandoc
|
||||
Homepage: http://www.grammaticalframework.org/
|
||||
|
||||
Package: gf
|
||||
|
||||
35
debian/rules
vendored
35
debian/rules
vendored
@@ -13,21 +13,6 @@
|
||||
override_dh_shlibdeps:
|
||||
dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info
|
||||
|
||||
override_dh_auto_build:
|
||||
cd src/runtime/python && EXTRA_INCLUDE_DIRS=$(CURDIR)/src/runtime/c EXTRA_LIB_DIRS=$(CURDIR)/src/runtime/c/.libs python setup.py build
|
||||
cd src/runtime/java && make CFLAGS="-I$(CURDIR)/src/runtime/c -L$(CURDIR)/src/runtime/c/.libs" INSTALL_PATH=/usr/lib
|
||||
echo LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:$(CURDIR)/src/runtime/c/.libs
|
||||
LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:$(CURDIR)/src/runtime/c/.libs cabal build
|
||||
LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:$(CURDIR)/src/runtime/c/.libs cabal copy --destdir=$(CURDIR)/debian/gf # create www directory
|
||||
PATH=$(CURDIR)/dist/build/gf:$$PATH && export GF_LIB_PATH="$$(dirname $$(find "$(CURDIR)/debian/gf" -name www))/lib" && echo "GF_LIB_PATH=$$GF_LIB_PATH" && mkdir -p "$$GF_LIB_PATH" && ( cd ../gf-rgl && make build && make copy ) && LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:$(CURDIR)/src/runtime/c/.libs cabal build
|
||||
make html
|
||||
|
||||
override_dh_auto_clean:
|
||||
rm -fr dist/build
|
||||
-cd src/runtime/python && rm -fr build
|
||||
-cd src/runtime/java && make clean
|
||||
-cd src/runtime/c && make clean
|
||||
|
||||
override_dh_auto_configure:
|
||||
cd src/runtime/c && bash setup.sh configure --prefix=/usr
|
||||
cd src/runtime/c && bash setup.sh build
|
||||
@@ -35,13 +20,31 @@ override_dh_auto_configure:
|
||||
cabal install --only-dependencies
|
||||
cabal configure --prefix=/usr -fserver -fc-runtime --extra-lib-dirs=$(CURDIR)/src/runtime/c/.libs --extra-include-dirs=$(CURDIR)/src/runtime/c
|
||||
|
||||
SET_LDL=LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:$(CURDIR)/src/runtime/c/.libs
|
||||
|
||||
override_dh_auto_build:
|
||||
cd src/runtime/python && EXTRA_INCLUDE_DIRS=$(CURDIR)/src/runtime/c EXTRA_LIB_DIRS=$(CURDIR)/src/runtime/c/.libs python setup.py build
|
||||
cd src/runtime/java && make CFLAGS="-I$(CURDIR)/src/runtime/c -L$(CURDIR)/src/runtime/c/.libs" INSTALL_PATH=/usr/lib
|
||||
echo $(SET_LDL)
|
||||
$(SET_LDL) cabal build # builds gf, fails to build example grammars
|
||||
PATH=$(CURDIR)/dist/build/gf:$$PATH && make -C ../gf-rgl build
|
||||
GF_LIB_PATH=$(CURDIR)/../gf-rgl/dist $(SET_LDL) cabal build # have RGL now, ok to build example grammars
|
||||
make html
|
||||
|
||||
override_dh_auto_install:
|
||||
LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:$(CURDIR)/src/runtime/c/.libs cabal copy --destdir=$(CURDIR)/debian/gf
|
||||
$(SET_LDL) cabal copy --destdir=$(CURDIR)/debian/gf # creates www directory
|
||||
export GF_LIB_PATH="$$(dirname $$(find "$(CURDIR)/debian/gf" -name www))/lib" && echo "GF_LIB_PATH=$$GF_LIB_PATH" && mkdir -p "$$GF_LIB_PATH" && make -C ../gf-rgl copy
|
||||
cd src/runtime/c && bash setup.sh copy prefix=$(CURDIR)/debian/gf/usr
|
||||
cd src/runtime/python && python setup.py install --prefix=$(CURDIR)/debian/gf/usr
|
||||
cd src/runtime/java && make INSTALL_PATH=$(CURDIR)/debian/gf/usr/lib install
|
||||
D="`find debian/gf -name site-packages`" && [ -n "$$D" ] && cd $$D && cd .. && mv site-packages dist-packages
|
||||
|
||||
override_dh_auto_clean:
|
||||
rm -fr dist/build
|
||||
-cd src/runtime/python && rm -fr build
|
||||
-cd src/runtime/java && make clean
|
||||
-cd src/runtime/c && make clean
|
||||
|
||||
override_dh_auto_test:
|
||||
ifneq (nocheck,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
|
||||
true
|
||||
|
||||
551
doc/error-messages.txt
Normal file
551
doc/error-messages.txt
Normal file
@@ -0,0 +1,551 @@
|
||||
Compiler.hs
|
||||
mainGFC :: Options -> [FilePath] -> IO ()
|
||||
_ | null fs -> fail $ "No input files."
|
||||
_ | all (extensionIs ".pgf") fs -> unionPGFFiles opts fs
|
||||
_ -> fail $ "Don't know what to do with these input files: " ++ unwords fs)
|
||||
|
||||
|
||||
----------------------------------------
|
||||
Compile.hs
|
||||
|
||||
compileModule
|
||||
case length file1s of
|
||||
0 -> raise (render ("Unable to find: " $$ nest 2 candidates))
|
||||
1 -> do return $ head file1s
|
||||
_ -> do putIfVerb opts1 ("matched multiple candidates: " +++ show file1s)
|
||||
return $ head file1s
|
||||
else raise (render ("File" <+> file <+> "does not exist"))
|
||||
|
||||
---------------------------------------
|
||||
Grammar.Lexer.x
|
||||
token :: P Token
|
||||
AlexError (AI pos _ _) -> PFailed pos "lexical error"
|
||||
|
||||
|
||||
---------------------------------------
|
||||
Grammar.Parser.y
|
||||
|
||||
happyError = fail "syntax error"
|
||||
|
||||
tryLoc (c,mty,Just e) = return (c,(mty,e))
|
||||
tryLoc (c,_ ,_ ) = fail ("local definition of" +++ showIdent c +++ "without value")
|
||||
|
||||
mkR [] = return $ RecType [] --- empty record always interpreted as record type
|
||||
mkR fs@(f:_) =
|
||||
case f of
|
||||
(lab,Just ty,Nothing) -> mapM tryRT fs >>= return . RecType
|
||||
_ -> mapM tryR fs >>= return . R
|
||||
where
|
||||
tryRT (lab,Just ty,Nothing) = return (ident2label lab,ty)
|
||||
tryRT (lab,_ ,_ ) = fail $ "illegal record type field" +++ showIdent lab --- manifest fields ?!
|
||||
|
||||
tryR (lab,mty,Just t) = return (ident2label lab,(mty,t))
|
||||
tryR (lab,_ ,_ ) = fail $ "illegal record field" +++ showIdent lab
|
||||
|
||||
|
||||
---------------------------------------
|
||||
ModDeps.hs
|
||||
|
||||
mkSourceGrammar :: [SourceModule] -> Err SourceGrammar
|
||||
deplist <- either
|
||||
return
|
||||
(\ms -> Bad $ "circular modules" +++ unwords (map show ms)) $
|
||||
|
||||
|
||||
checkUniqueImportNames :: [Ident] -> SourceModInfo -> Err ()
|
||||
test ms = testErr (all (`notElem` ns) ms)
|
||||
("import names clashing with module names among" +++ unwords (map prt ms))
|
||||
|
||||
|
||||
moduleDeps :: [SourceModule] -> Err Dependencies
|
||||
deps (c,m) = errIn ("checking dependencies of module" +++ prt c) $ case mtype m of
|
||||
MTConcrete a -> do
|
||||
am <- lookupModuleType gr a
|
||||
testErr (mtype am == MTAbstract) "the of-module is not an abstract syntax"
|
||||
|
||||
testErr (all (compatMType ety . mtype) ests) "inappropriate extension module type"
|
||||
|
||||
|
||||
---------------------------------------
|
||||
Update.hs
|
||||
|
||||
buildAnyTree
|
||||
Just i -> case unifyAnyInfo m i j of
|
||||
Ok k -> go (Map.insert c k map) is
|
||||
Bad _ -> fail $ render ("conflicting information in module"<+>m $$
|
||||
nest 4 (ppJudgement Qualified (c,i)) $$
|
||||
"and" $+$
|
||||
nest 4 (ppJudgement Qualified (c,j)))
|
||||
extendModule
|
||||
unless (sameMType (mtype m) (mtype mo))
|
||||
(checkError ("illegal extension type to module" <+> name))
|
||||
|
||||
rebuildModule
|
||||
unless (null is || mstatus mi == MSIncomplete)
|
||||
(checkError ("module" <+> i <+>
|
||||
"has open interfaces and must therefore be declared incomplete"))
|
||||
|
||||
unless (isModRes m1)
|
||||
(checkError ("interface expected instead of" <+> i0))
|
||||
js' <- extendMod gr False ((i0,m1), isInherited mincl) i (jments mi)
|
||||
|
||||
unless (stat' == MSComplete || stat == MSIncomplete)
|
||||
(checkError ("module" <+> i <+> "remains incomplete"))
|
||||
|
||||
|
||||
extendMod
|
||||
checkError ("cannot unify the information" $$
|
||||
nest 4 (ppJudgement Qualified (c,i)) $$
|
||||
"in module" <+> name <+> "with" $$
|
||||
nest 4 (ppJudgement Qualified (c,j)) $$
|
||||
"in module" <+> base)
|
||||
|
||||
unifyAnyInfo
|
||||
(ResValue (L l1 t1), ResValue (L l2 t2))
|
||||
| t1==t2 -> return (ResValue (L l1 t1))
|
||||
| otherwise -> fail ""
|
||||
|
||||
(AnyInd b1 m1, AnyInd b2 m2) -> do
|
||||
testErr (b1 == b2) $ "indirection status"
|
||||
testErr (m1 == m2) $ "different sources of indirection"
|
||||
|
||||
unifAbsDefs _ _ = fail ""
|
||||
|
||||
----------------------------------
|
||||
|
||||
Rename.hs
|
||||
|
||||
renameIdentTerm'
|
||||
_ -> case lookupTreeManyAll showIdent opens c of
|
||||
[f] -> return (f c)
|
||||
[] -> alt c ("constant not found:" <+> c $$
|
||||
"given" <+> fsep (punctuate ',' (map fst qualifs)))
|
||||
|
||||
ts@(t:_) -> do checkWarn ("atomic term" <+> ppTerm Qualified 0 t0 $$
|
||||
"conflict" <+> hsep (punctuate ',' (map (ppTerm Qualified 0) ts)) $$
|
||||
"given" <+> fsep (punctuate ',' (map fst qualifs)))
|
||||
return t
|
||||
|
||||
renameInfo
|
||||
renLoc ren (L loc x) =
|
||||
checkInModule cwd mi loc ("Happened in the renaming of" <+> i) $ do
|
||||
|
||||
renameTerm
|
||||
| otherwise -> checks [ renid' (Q (MN r,label2ident l)) -- .. and qualified expression second.
|
||||
, renid' t >>= \t -> return (P t l) -- try as a constant at the end
|
||||
, checkError ("unknown qualified constant" <+> trm)
|
||||
]
|
||||
|
||||
renamePattern env patt =
|
||||
do r@(p',vs) <- renp patt
|
||||
let dupl = vs \\ nub vs
|
||||
unless (null dupl) $ checkError (hang ("[C.4.13] Pattern is not linear:") 4
|
||||
patt)
|
||||
return r
|
||||
|
||||
case c' of
|
||||
Q d -> renp $ PM d
|
||||
_ -> checkError ("unresolved pattern" <+> patt)
|
||||
|
||||
Q _ -> checkError ("data constructor expected but" <+> ppTerm Qualified 0 c' <+> "is found instead")
|
||||
_ -> checkError ("unresolved data constructor" <+> ppTerm Qualified 0 c')
|
||||
|
||||
PM c -> do
|
||||
x <- renid (Q c)
|
||||
c' <- case x of
|
||||
(Q c') -> return c'
|
||||
_ -> checkError ("not a pattern macro" <+> ppPatt Qualified 0 patt)
|
||||
|
||||
PV x -> checks [ renid' (Vr x) >>= \t' -> case t' of
|
||||
QC c -> return (PP c [],[])
|
||||
_ -> checkError (pp "not a constructor")
|
||||
, return (patt, [x])
|
||||
|
||||
|
||||
|
||||
-----------------------------------
|
||||
CheckGrammar.hs
|
||||
|
||||
checkRestrictedInheritance :: FilePath -> SourceGrammar -> SourceModule -> Check ()
|
||||
let illegals = [(f,is) |
|
||||
(f,cs) <- allDeps, incld f, let is = filter illegal cs, not (null is)]
|
||||
case illegals of
|
||||
[] -> return ()
|
||||
cs -> checkWarn ("In inherited module" <+> i <> ", dependence of excluded constants:" $$
|
||||
nest 2 (vcat [f <+> "on" <+> fsep is | (f,is) <- cs]))
|
||||
|
||||
checkCompleteGrammar :: Options -> FilePath -> Grammar -> Module -> Module -> Check Module
|
||||
case info of
|
||||
CncCat (Just (L loc (RecType []))) _ _ _ _ -> return (foldr (\_ -> Abs Explicit identW) (R []) cxt)
|
||||
_ -> Bad "no def lin"
|
||||
|
||||
where noLinOf c = checkWarn ("no linearization of" <+> c)
|
||||
|
||||
Ok (CncCat Nothing md mr mp mpmcfg) -> do
|
||||
checkWarn ("no linearization type for" <+> c <> ", inserting default {s : Str}")
|
||||
return $ updateTree (c,CncCat (Just (L NoLoc defLinType)) md mr mp mpmcfg) js
|
||||
_ -> do
|
||||
checkWarn ("no linearization type for" <+> c <> ", inserting default {s : Str}")
|
||||
|
||||
_ -> do checkWarn ("function" <+> c <+> "is not in abstract")
|
||||
|
||||
Ok (_,AbsFun {}) ->
|
||||
checkError ("lincat:"<+>c<+>"is a fun, not a cat")
|
||||
-}
|
||||
_ -> do checkWarn ("category" <+> c <+> "is not in abstract")
|
||||
|
||||
checkInfo :: Options -> FilePath -> SourceGrammar -> SourceModule -> Ident -> Info -> Check Info
|
||||
(Just (L loct ty), Nothing) -> do
|
||||
chIn loct "operation" $
|
||||
checkError (pp "No definition given to the operation")
|
||||
|
||||
ResOverload os tysts -> chIn NoLoc "overloading" $ do
|
||||
|
||||
checkUniq xss = case xss of
|
||||
x:y:xs
|
||||
| x == y -> checkError $ "ambiguous for type" <+>
|
||||
ppType (mkFunType (tail x) (head x))
|
||||
|
||||
compAbsTyp g t = case t of
|
||||
Vr x -> maybe (checkError ("no value given to variable" <+> x)) return $ lookup x g
|
||||
|
||||
checkReservedId x =
|
||||
when (isReservedWord x) $
|
||||
checkWarn ("reserved word used as identifier:" <+> x)
|
||||
|
||||
|
||||
--------------------------------
|
||||
TypeCheck/Abstract.hs
|
||||
|
||||
grammar2theory :: SourceGrammar -> Theory
|
||||
Bad s -> case lookupCatContext gr m f of
|
||||
Ok cont -> return $ cont2val cont
|
||||
_ -> Bad s
|
||||
|
||||
|
||||
--------------------------------
|
||||
TypeCheck/ConcreteNew.hs
|
||||
-- Concrete.hs has all its code commented out
|
||||
|
||||
|
||||
--------------------------------
|
||||
TypeCheck/RConcrete.hs
|
||||
-- seems to be used more than ConcreteNew
|
||||
|
||||
computeLType :: SourceGrammar -> Context -> Type -> Check Type
|
||||
AdHocOverload ts -> do
|
||||
over <- getOverload gr g (Just typeType) t
|
||||
case over of
|
||||
Just (tr,_) -> return tr
|
||||
_ -> checkError ("unresolved overloading of constants" <+> ppTerm Qualified 0 t)
|
||||
|
||||
inferLType :: SourceGrammar -> Context -> Term -> Check (Term, Type)
|
||||
Q (m,ident) | isPredef m -> termWith trm $ case typPredefined ident of
|
||||
Nothing -> checkError ("unknown in Predef:" <+> ident)
|
||||
|
||||
Q ident -> checks [
|
||||
checkError ("cannot infer type of constant" <+> ppTerm Unqualified 0 trm)
|
||||
]
|
||||
|
||||
QC ident -> checks [
|
||||
checkError ("cannot infer type of canonical constant" <+> ppTerm Unqualified 0 trm)
|
||||
]
|
||||
|
||||
Vr ident -> termWith trm $ checkLookup ident g
|
||||
|
||||
AdHocOverload ts -> do
|
||||
_ -> checkError ("unresolved overloading of constants" <+> ppTerm Qualified 0 trm)
|
||||
|
||||
App f a -> do
|
||||
case fty' of
|
||||
Prod bt z arg val -> do
|
||||
_ -> checkError ("A function type is expected for" <+> ppTerm Unqualified 0 f <+> "instead of type" <+> ppType fty)
|
||||
|
||||
S f x -> do
|
||||
_ -> checkError ("table lintype expected for the table in" $$ nest 2 (ppTerm Unqualified 0 trm))
|
||||
|
||||
P t i -> do
|
||||
Nothing -> checkError ("unknown label" <+> i <+> "in" $$ nest 2 (ppTerm Unqualified 0 ty'))
|
||||
_ -> checkError ("record type expected for:" <+> ppTerm Unqualified 0 t $$
|
||||
" instead of the inferred:" <+> ppTerm Unqualified 0 ty')
|
||||
|
||||
R r -> do
|
||||
checkCond ("cannot infer type of record" $$ nest 2 (ppTerm Unqualified 0 trm)) (length ts == length fsts)
|
||||
|
||||
T ti pts -> do -- tries to guess: good in oper type inference
|
||||
[] -> checkError ("cannot infer table type of" <+> ppTerm Unqualified 0 trm)
|
||||
|
||||
---- hack from Rename.identRenameTerm, to live with files with naming conflicts 18/6/2007
|
||||
Strs (Cn c : ts) | c == cConflict -> do
|
||||
checkWarn ("unresolved constant, could be any of" <+> hcat (map (ppTerm Unqualified 0) ts))
|
||||
|
||||
ExtR r s -> do
|
||||
case (rT', sT') of
|
||||
(RecType rs, RecType ss) -> do
|
||||
_ -> checkError ("records or record types expected in" <+> ppTerm Unqualified 0 trm)
|
||||
|
||||
_ -> checkError ("cannot infer lintype of" <+> ppTerm Unqualified 0 trm)
|
||||
|
||||
|
||||
getOverload :: SourceGrammar -> Context -> Maybe Type -> Term -> Check (Maybe (Term,Type))
|
||||
matchOverload f typs ttys = do
|
||||
checkWarn $ "ignoring lock fields in resolving" <+> ppTerm Unqualified 0 ot $$
|
||||
"for" $$
|
||||
nest 2 (showTypes tys) $$
|
||||
"using" $$
|
||||
nest 2 (showTypes pre)
|
||||
([],[]) -> do
|
||||
checkError $ "no overload instance of" <+> ppTerm Unqualified 0 f $$
|
||||
"for" $$
|
||||
nest 2 stysError $$
|
||||
"among" $$
|
||||
nest 2 (vcat stypsError) $$
|
||||
maybe empty (\x -> "with value type" <+> ppType x) mt
|
||||
([],[(val,fun)]) -> do
|
||||
checkWarn ("ignoring lock fields in resolving" <+> ppTerm Unqualified 0 ot)
|
||||
(nps1,nps2) -> do
|
||||
checkWarn $ "ambiguous overloading of" <+> ppTerm Unqualified 0 f <+>
|
||||
---- "with argument types" <+> hsep (map (ppTerm Qualified 0) tys) $$
|
||||
"resolved by selecting the first of the alternatives" $$
|
||||
nest 2 (vcat [ppTerm Qualified 0 fun | (_,ty,fun) <- vfs1 ++ if null vfs1 then vfs2 else []])
|
||||
case [(mkApp fun tts,val) | (val,fun) <- nps1 ++ nps2] of
|
||||
[] -> checkError $ "no alternatives left when resolving" <+> ppTerm Unqualified 0 f
|
||||
|
||||
checkLType :: SourceGrammar -> Context -> Term -> Type -> Check (Term, Type)
|
||||
Abs bt x c -> do
|
||||
case typ of
|
||||
Prod bt' z a b -> do
|
||||
_ -> checkError $ "function type expected instead of" <+> ppType typ
|
||||
AdHocOverload ts -> do
|
||||
_ -> checkError ("unresolved overloading of constants" <+> ppTerm Qualified 0 trm)
|
||||
T _ [] ->
|
||||
checkError ("found empty table in type" <+> ppTerm Unqualified 0 typ)
|
||||
T _ cs -> case typ of
|
||||
else checkWarn ("patterns never reached:" $$
|
||||
nest 2 (vcat (map (ppPatt Unqualified 0) ps)))
|
||||
_ -> checkError $ "table type expected for table instead of" $$ nest 2 (ppType typ)
|
||||
V arg0 vs ->
|
||||
if length vs1 == length vs
|
||||
then return ()
|
||||
else checkError $ "wrong number of values in table" <+> ppTerm Unqualified 0 trm
|
||||
|
||||
R r -> case typ of --- why needed? because inference may be too difficult
|
||||
RecType rr -> do
|
||||
_ -> checkError ("record type expected in type checking instead of" $$ nest 2 (ppTerm Unqualified 0 typ))
|
||||
|
||||
ExtR r s -> case typ of
|
||||
case trm' of
|
||||
RecType _ -> termWith trm' $ return typeType
|
||||
ExtR (Vr _) (RecType _) -> termWith trm' $ return typeType
|
||||
-- ext t = t ** ...
|
||||
_ -> checkError ("invalid record type extension" <+> nest 2 (ppTerm Unqualified 0 trm))
|
||||
|
||||
case typ2 of
|
||||
RecType ss -> return $ map fst ss
|
||||
_ -> checkError ("cannot get labels from" $$ nest 2 (ppTerm Unqualified 0 typ2))
|
||||
_ -> checkError ("record extension not meaningful for" <+> ppTerm Unqualified 0 typ)
|
||||
|
||||
S tab arg -> checks [ do
|
||||
_ -> checkError ("table type expected for applied table instead of" <+> ppType ty')
|
||||
|
||||
_ -> do
|
||||
(trm',ty') <- inferLType gr g trm
|
||||
termWith trm' $ checkEqLType gr g typ ty' trm'
|
||||
|
||||
checkM rms (l,ty) = case lookup l rms of
|
||||
_ -> checkError $
|
||||
if isLockLabel l
|
||||
then let cat = drop 5 (showIdent (label2ident l))
|
||||
in ppTerm Unqualified 0 (R rms) <+> "is not in the lincat of" <+> cat <>
|
||||
"; try wrapping it with lin" <+> cat
|
||||
else "cannot find value for label" <+> l <+> "in" <+> ppTerm Unqualified 0 (R rms)
|
||||
|
||||
checkEqLType :: SourceGrammar -> Context -> Type -> Type -> Term -> Check Type
|
||||
False -> checkError $ s <+> "type of" <+> ppTerm Unqualified 0 trm $$
|
||||
"expected:" <+> ppTerm Qualified 0 t $$ -- ppqType t u $$
|
||||
"inferred:" <+> ppTerm Qualified 0 u -- ppqType u t
|
||||
|
||||
checkIfEqLType :: SourceGrammar -> Context -> Type -> Type -> Term -> Check (Bool,Type,Type,String)
|
||||
Ok lo -> do
|
||||
checkWarn $ "missing lock field" <+> fsep lo
|
||||
|
||||
missingLock g t u = case (t,u) of
|
||||
_:_ -> Bad $ render ("missing record fields:" <+> fsep (punctuate ',' (others)))
|
||||
|
||||
|
||||
|
||||
pattContext :: SourceGrammar -> Context -> Type -> Patt -> Check Context
|
||||
checkCond ("wrong number of arguments for constructor in" <+> ppPatt Unqualified 0 p)
|
||||
(length cont == length ps)
|
||||
PR r -> do
|
||||
_ -> checkError ("record type expected for pattern instead of" <+> ppTerm Unqualified 0 typ')
|
||||
|
||||
PAlt p' q -> do
|
||||
g1 <- pattContext env g typ p'
|
||||
g2 <- pattContext env g typ q
|
||||
let pts = nub ([x | pt@(_,x,_) <- g1, notElem pt g2] ++ [x | pt@(_,x,_) <- g2, notElem pt g1])
|
||||
checkCond
|
||||
("incompatible bindings of" <+>
|
||||
fsep pts <+>
|
||||
"in pattern alterantives" <+> ppPatt Unqualified 0 p) (null pts)
|
||||
return g1 -- must be g1 == g2
|
||||
|
||||
noBind typ p' = do
|
||||
co <- pattContext env g typ p'
|
||||
if not (null co)
|
||||
then checkWarn ("no variable bound inside pattern" <+> ppPatt Unqualified 0 p)
|
||||
>> return []
|
||||
else return []
|
||||
|
||||
checkLookup :: Ident -> Context -> Check Type -- used for looking up Vr x type in context
|
||||
[] -> checkError ("unknown variable" <+> x)
|
||||
|
||||
|
||||
|
||||
-------------------------------
|
||||
Grammar/Lookup.hs
|
||||
|
||||
lookupIdent :: ErrorMonad m => Ident -> BinTree Ident b -> m b
|
||||
Bad _ -> raise ("unknown identifier" +++ showIdent c)
|
||||
|
||||
lookupResDefLoc
|
||||
_ -> raise $ render (c <+> "is not defined in resource" <+> m)
|
||||
|
||||
lookupResType :: ErrorMonad m => Grammar -> QIdent -> m Type
|
||||
_ -> raise $ render (c <+> "has no type defined in resource" <+> m)
|
||||
|
||||
lookupOverloadTypes :: ErrorMonad m => Grammar -> QIdent -> m [(Term,Type)]
|
||||
_ -> raise $ render (c <+> "has no types defined in resource" <+> m)
|
||||
|
||||
lookupOverload :: ErrorMonad m => Grammar -> QIdent -> m [([Type],(Type,Term))]
|
||||
_ -> raise $ render (c <+> "is not an overloaded operation")
|
||||
|
||||
|
||||
lookupParamValues :: ErrorMonad m => Grammar -> QIdent -> m [Term]
|
||||
case info of
|
||||
ResParam _ (Just pvs) -> return pvs
|
||||
_ -> raise $ render (ppQIdent Qualified c <+> "has no parameter values defined")
|
||||
|
||||
|
||||
allParamValues :: ErrorMonad m => Grammar -> Type -> m [Term]
|
||||
_ -> raise (render ("cannot find parameter values for" <+> ptyp))
|
||||
|
||||
|
||||
lookupFunType :: ErrorMonad m => Grammar -> ModuleName -> Ident -> m Type
|
||||
_ -> raise (render ("cannot find type of" <+> c))
|
||||
|
||||
lookupCatContext :: ErrorMonad m => Grammar -> ModuleName -> Ident -> m Context
|
||||
_ -> raise (render ("unknown category" <+> c))
|
||||
|
||||
|
||||
-------------------------
|
||||
PatternMatch.hs
|
||||
|
||||
matchPattern :: ErrorMonad m => [(Patt,rhs)] -> Term -> m (rhs, Substitution)
|
||||
if not (isInConstantForm term)
|
||||
then raise (render ("variables occur in" <+> pp term))
|
||||
|
||||
findMatch :: ErrorMonad m => [([Patt],rhs)] -> [Term] -> m (rhs, Substitution)
|
||||
[] -> raise (render ("no applicable case for" <+> hsep (punctuate ',' terms)))
|
||||
(patts,_):_ | length patts /= length terms ->
|
||||
raise (render ("wrong number of args for patterns :" <+> hsep patts <+>
|
||||
"cannot take" <+> hsep terms))
|
||||
|
||||
tryMatch :: (Patt, Term) -> Err [(Ident, Term)]
|
||||
(PNeg p',_) -> case tryMatch (p',t) of
|
||||
Bad _ -> return []
|
||||
_ -> raise (render ("no match with negative pattern" <+> p))
|
||||
|
||||
|
||||
---------------------------------------------
|
||||
Compile.Optimize.hs
|
||||
|
||||
mkLinDefault :: SourceGrammar -> Type -> Err Term
|
||||
_ -> Bad (render ("no parameter values given to type" <+> ppQIdent Qualified p))
|
||||
_ -> Bad (render ("linearization type field cannot be" <+> typ))
|
||||
|
||||
mkLinReference :: SourceGrammar -> Type -> Err Term
|
||||
[] -> Bad "no string"
|
||||
|
||||
|
||||
---------------------------------------------
|
||||
Compile.Compute.Concrete.hs
|
||||
|
||||
nfx env@(GE _ _ _ loc) t = do
|
||||
Left i -> fail ("variable #"++show i++" is out of scope")
|
||||
|
||||
var :: CompleteEnv -> Ident -> Err OpenValue
|
||||
var env x = maybe unbound pick' (elemIndex x (local env))
|
||||
where
|
||||
unbound = fail ("Unknown variable: "++showIdent x)
|
||||
pick' i = return $ \ vs -> maybe (err i vs) ok (pick i vs)
|
||||
err i vs = bug $ "Stack problem: "++showIdent x++": "
|
||||
++unwords (map showIdent (local env))
|
||||
++" => "++show (i,length vs)
|
||||
|
||||
resource env (m,c) =
|
||||
where e = fail $ "Not found: "++render m++"."++showIdent c
|
||||
|
||||
extR t vv =
|
||||
(VRecType rs1, VRecType rs2) ->
|
||||
case intersect (map fst rs1) (map fst rs2) of
|
||||
[] -> VRecType (rs1 ++ rs2)
|
||||
ls -> error $ "clash"<+>show ls
|
||||
(v1,v2) -> error $ "not records" $$ show v1 $$ show v2
|
||||
where
|
||||
error explain = ppbug $ "The term" <+> t
|
||||
<+> "is not reducible" $$ explain
|
||||
|
||||
glue env (v1,v2) = glu v1 v2
|
||||
ppL loc (hang "unsupported token gluing:" 4
|
||||
(Glue (vt v1) (vt v2)))
|
||||
|
||||
strsFromValue :: Value -> Err [Str]
|
||||
_ -> fail ("cannot get Str from value " ++ show t)
|
||||
|
||||
match loc cs v =
|
||||
case value2term loc [] v of
|
||||
Left i -> bad ("variable #"++show i++" is out of scope")
|
||||
Right t -> err bad return (matchPattern cs t)
|
||||
where
|
||||
bad = fail . ("In pattern matching: "++)
|
||||
|
||||
inlinePattMacro p =
|
||||
VPatt p' -> inlinePattMacro p'
|
||||
_ -> ppbug $ hang "Expected pattern macro:" 4
|
||||
|
||||
linPattVars p =
|
||||
if null dups
|
||||
then return pvs
|
||||
else fail.render $ hang "Pattern is not linear:" 4 (ppPatt Unqualified 0 p)
|
||||
|
||||
---------------------------------------------
|
||||
Compile.Compute.Abstract.hs
|
||||
|
||||
|
||||
---------------------------------------------
|
||||
PGF.Linearize.hs
|
||||
|
||||
bracketedLinearize :: PGF -> Language -> Tree -> [BracketedString]
|
||||
cnc = lookMap (error "no lang") lang (concretes pgf)
|
||||
|
||||
|
||||
---------------------------------------------
|
||||
PGF.TypeCheck.hs
|
||||
|
||||
ppTcError :: TcError -> Doc
|
||||
ppTcError (UnknownCat cat) = text "Category" <+> ppCId cat <+> text "is not in scope"
|
||||
ppTcError (UnknownFun fun) = text "Function" <+> ppCId fun <+> text "is not in scope"
|
||||
ppTcError (WrongCatArgs xs ty cat m n) = text "Category" <+> ppCId cat <+> text "should have" <+> int m <+> text "argument(s), but has been given" <+> int n $$
|
||||
text "In the type:" <+> ppType 0 xs ty
|
||||
ppTcError (TypeMismatch xs e ty1 ty2) = text "Couldn't match expected type" <+> ppType 0 xs ty1 $$
|
||||
text " against inferred type" <+> ppType 0 xs ty2 $$
|
||||
text "In the expression:" <+> ppExpr 0 xs e
|
||||
ppTcError (NotFunType xs e ty) = text "A function type is expected for the expression" <+> ppExpr 0 xs e <+> text "instead of type" <+> ppType 0 xs ty
|
||||
ppTcError (CannotInferType xs e) = text "Cannot infer the type of expression" <+> ppExpr 0 xs e
|
||||
ppTcError (UnresolvedMetaVars xs e ms) = text "Meta variable(s)" <+> fsep (List.map ppMeta ms) <+> text "should be resolved" $$
|
||||
text "in the expression:" <+> ppExpr 0 xs e
|
||||
ppTcError (UnexpectedImplArg xs e) = braces (ppExpr 0 xs e) <+> text "is implicit argument but not implicit argument is expected here"
|
||||
ppTcError (UnsolvableGoal xs metaid ty)= text "The goal:" <+> ppMeta metaid <+> colon <+> ppType 0 xs ty $$
|
||||
text "cannot be solved"
|
||||
|
||||
@@ -405,13 +405,13 @@ There is also ``make build``, ``make copy`` and ``make clean`` which do what you
|
||||
=== Advanced ===
|
||||
For advanced build options, call the Haskell build script directly:
|
||||
```
|
||||
$ runghc Make.hs ...
|
||||
$ runghc Setup.hs ...
|
||||
```
|
||||
For more details see the [README https://github.com/GrammaticalFramework/gf-rgl/blob/master/README.md].
|
||||
|
||||
=== Haskell-free ===
|
||||
If you do not have Haskell installed, you can use the simple build script ``Make.sh``
|
||||
(or ``Make.bat`` for Windows).
|
||||
If you do not have Haskell installed, you can use the simple build script ``Setup.sh``
|
||||
(or ``Setup.bat`` for Windows).
|
||||
|
||||
|
||||
== Creating binary distribution packages ==
|
||||
|
||||
4622
doc/gf-refman.html
4622
doc/gf-refman.html
File diff suppressed because it is too large
Load Diff
2770
doc/gf-refman.md
Normal file
2770
doc/gf-refman.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,69 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>GF Documentation</title>
|
||||
<link rel=stylesheet href="../css/style.css">
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<div class=center>
|
||||
<a href="../"><img src="Logos/gf0.png"></a>
|
||||
|
||||
|
||||
|
||||
|
||||
<h1>Grammatical Framework Documents</h1>
|
||||
</div>
|
||||
|
||||
|
||||
<b>Top-5 documents</b>:
|
||||
|
||||
<a href="gf-quickstart.html">Quick start instruction</a>.
|
||||
|
||||
|
||||
<a href="tutorial/gf-tutorial.html">Old Tutorial</a>, application-oriented.
|
||||
|
||||
<a href="gf-lrec-2010.pdf">New Tutorial</a>, linguistics-oriented.
|
||||
|
||||
<a href="gf-refman.html">ReferenceManual</a>.
|
||||
|
||||
<a href="../lib/resource/doc/synopsis.html">LibrarySynopsis</a>.
|
||||
|
||||
|
||||
|
||||
|
||||
<h2>Language and system documentation</h2>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<a href="gf-reference.html">GF Quick Reference</a>. Also available in
|
||||
<a href="gf-reference.pdf">pdf</a>. Covers all features of GF language
|
||||
in a summary format.
|
||||
|
||||
<li>
|
||||
<a href="gf-refman.html">GF Reference Manual</a>. A full-scale reference
|
||||
manual of the GF language.
|
||||
|
||||
<li>
|
||||
<a href="gf-shell-reference.html">GF Shell Reference</a>.
|
||||
Describes the commands available in the interactive GF shell. Also
|
||||
summarizes how to run GF as a batch compiler.
|
||||
|
||||
<li>
|
||||
<a href="gf-editor-modes.html">Editor modes for GF</a>.
|
||||
Editor modes for GF provides syntax highligting, automatic indentation and
|
||||
other features that makes editing GF grammar files easier.
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Publications</h2>
|
||||
|
||||
<a href="gf-bibliography.html">
|
||||
Bibliography</a>: more publications on GF, as well as background literature.
|
||||
|
||||
|
||||
</body></html>
|
||||
13
doc/index.md
Normal file
13
doc/index.md
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
title: Grammatical Framework Documentation
|
||||
---
|
||||
|
||||
Perhaps you're looking for one of the following:
|
||||
|
||||
- [Tutorial](tutorial/gf-tutorial.html). This is a hands-on introduction to grammar writing in GF.
|
||||
- [Reference Manual](gf-refman.html). A full-scale reference manual of the GF language.
|
||||
- [RGL Tutorial](../lib/doc/rgl-tutorial/index.html)
|
||||
- [RGL Synopsis](../lib/doc/synopsis/index.html). Documentation of the Resource Grammar Library, including the syntax API and lexical paradigms for each language.
|
||||
- [Shell Reference](gf-shell-reference.html). Describes the commands available in the interactive GF shell.
|
||||
Also summarizes how to run GF as a batch compiler.
|
||||
- [Developers Guide](gf-developers/html). Detailed information about building and developing GF.
|
||||
@@ -1,29 +1,26 @@
|
||||
<html>
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>C Runtime API</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
<style>
|
||||
body { background: #eee; padding-top: 200px; }
|
||||
|
||||
pre.python {background-color:#ffc; display: none}
|
||||
pre.haskell {background-color:#ffc; display: block}
|
||||
pre.java {background-color:#ffc; display: none}
|
||||
pre.csharp {background-color:#ffc; display: none}
|
||||
pre {
|
||||
background-color:#eee;
|
||||
margin-top: 1em;
|
||||
padding: 0.5em 1em;
|
||||
}
|
||||
pre.python {display: none}
|
||||
pre.haskell {display: block}
|
||||
pre.java {display: none}
|
||||
pre.csharp {display: none}
|
||||
span.python {display: none}
|
||||
span.haskell {display: inline}
|
||||
span.java {display: none}
|
||||
span.csharp {display: none}
|
||||
|
||||
.header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: #ddd;
|
||||
width: 100%;
|
||||
padding: 5pt;
|
||||
border-bottom: solid #bbb 2pt;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<script lang="javascript">
|
||||
function change_language(href) {
|
||||
var name = href.split("#")[1];
|
||||
@@ -50,14 +47,28 @@
|
||||
</script>
|
||||
</head>
|
||||
<body onload="change_language(window.location.href); window.addEventListener('hashchange', function(e){change_language(window.location.href);});">
|
||||
<span class="header">
|
||||
<h1>Using the <span class="python">Python</span> <span class="haskell">Haskell</span> <span class="java">Java</span> <span class="csharp">C#</span> binding to the C runtime</h1>
|
||||
|
||||
Choose a language: <a href="#haskell">Haskell</a> <a href="#python">Python</a> <a href="#java">Java</a> <a href="#csharp">C#</a>
|
||||
</span>
|
||||
<div class="container-fluid" style="max-width: 1200px">
|
||||
<div class="header sticky-top border-bottom py-3 bg-white">
|
||||
<a href=".." title="Home">
|
||||
<img src="../doc/Logos/gf1.svg" height="120px" class="float-md-right ml-3 mb-3 bg-white" alt="GF Logo">
|
||||
</a>
|
||||
<h1>
|
||||
Using the
|
||||
<span class="python">Python</span>
|
||||
<span class="haskell">Haskell</span>
|
||||
<span class="java">Java</span>
|
||||
<span class="csharp">C#</span>
|
||||
binding to the C runtime
|
||||
</h1>
|
||||
<h4 class="text-muted">Krasimir Angelov, July 2015 - August 2017</h4>
|
||||
Choose a language:
|
||||
<a href="#haskell" class="mx-1">Haskell</a>
|
||||
<a href="#python" class="mx-1">Python</a>
|
||||
<a href="#java" class="mx-1">Java</a>
|
||||
<a href="#csharp" class="mx-1">C#</a>
|
||||
</div>
|
||||
<main class="py-4">
|
||||
|
||||
<h4>Krasimir Angelov, July 2015 - August 2017</h4>
|
||||
|
||||
<h2>Loading the Grammar</h2>
|
||||
|
||||
Before you use the <span class="python">Python</span> binding you need to import the <span class="haskell">PGF2 module</span><span class="python">pgf module</span><span class="java">pgf package</span><span class="csharp">PGFSharp package</span>:
|
||||
@@ -127,7 +138,7 @@ Concr eng = gr.Languages["AppEng"];
|
||||
|
||||
<h2>Parsing</h2>
|
||||
|
||||
All language specific services are available as
|
||||
All language specific services are available as
|
||||
<span class="python">methods of the class <tt>pgf.Concr</tt></span><span class="haskell">functions that take as an argument an object of type <tt>Concr</tt></span><span class="java">methods of the class <tt>Concr</tt></span><span class="csharp">methods of the class <tt>Concr</tt></span>.
|
||||
For example to invoke the parser, you can call:
|
||||
<pre class="python">
|
||||
@@ -220,10 +231,10 @@ Console.WriteLine(ep.Item1);
|
||||
PhrUtt NoPConj (UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (DetNP (DetQuant this_Quant NumSg)) (UseComp (CompNP (DetCN (DetQuant IndefArt NumSg) (AdjCN (PositA small_A) (UseN theatre_N)))))))) NoVoc
|
||||
</pre>
|
||||
|
||||
<p>Note that depending on the grammar it is absolutely possible that for
|
||||
a single sentence you might get infinitely many trees.
|
||||
<p>Note that depending on the grammar it is absolutely possible that for
|
||||
a single sentence you might get infinitely many trees.
|
||||
In other cases the number of trees might be finite but still enormous.
|
||||
The parser is specifically designed to be lazy, which means that
|
||||
The parser is specifically designed to be lazy, which means that
|
||||
each tree is returned as soon as it is found before exhausting
|
||||
the full search space. For grammars with a patological number of
|
||||
trees it is advisable to pick only the top <tt>N</tt> trees
|
||||
@@ -246,16 +257,16 @@ parsing with a different start category can be done as follows:</p>
|
||||
</pre>
|
||||
</span>
|
||||
<span class="haskell">
|
||||
There is also the function <tt>parseWithHeuristics</tt> which
|
||||
takes two more paramaters which let you to have a better control
|
||||
There is also the function <tt>parseWithHeuristics</tt> which
|
||||
takes two more paramaters which let you to have a better control
|
||||
over the parser's behaviour:
|
||||
<pre class="haskell">
|
||||
Prelude PGF2> let res = parseWithHeuristics eng (startCat gr) heuristic_factor callbacks
|
||||
</pre>
|
||||
</span>
|
||||
<span class="java">
|
||||
There is also the method <tt>parseWithHeuristics</tt> which
|
||||
takes two more paramaters which let you to have a better control
|
||||
There is also the method <tt>parseWithHeuristics</tt> which
|
||||
takes two more paramaters which let you to have a better control
|
||||
over the parser's behaviour:
|
||||
<pre class="java">
|
||||
Iterable<ExprProb> iterable = eng.parseWithHeuristics(gr.startCat(), heuristic_factor, callbacks);
|
||||
@@ -281,7 +292,7 @@ to factor 0.0. When we increase the factor then parsing becomes faster
|
||||
but at the same time the sorting becomes imprecise. The worst
|
||||
factor is 1.0. In any case the parser always returns the same set of
|
||||
trees but in different order. Our experience is that even a factor
|
||||
of about 0.6-0.8 with the translation grammar still orders
|
||||
of about 0.6-0.8 with the translation grammar still orders
|
||||
the most probable tree on top of the list but further down the list,
|
||||
the trees become shuffled.
|
||||
</p>
|
||||
@@ -457,7 +468,7 @@ the object has the following public final variables:
|
||||
</span>
|
||||
</p>
|
||||
|
||||
The linearization works even if there are functions in the tree
|
||||
The linearization works even if there are functions in the tree
|
||||
that doesn't have linearization definitions. In that case you
|
||||
will just see the name of the function in the generated string.
|
||||
It is sometimes helpful to be able to see whether a function
|
||||
@@ -483,7 +494,7 @@ true
|
||||
|
||||
<p>
|
||||
An already constructed tree can be analyzed and transformed
|
||||
in the host application. For example you can deconstruct
|
||||
in the host application. For example you can deconstruct
|
||||
a tree into a function name and a list of arguments:
|
||||
<pre class="python">
|
||||
>>> e.unpack()
|
||||
@@ -523,8 +534,8 @@ literal. For example the result from:
|
||||
<span class="haskell">
|
||||
The result from <tt>unApp</tt> is <tt>Just</tt> if the expression
|
||||
is an application and <tt>Nothing</tt> in all other cases.
|
||||
Similarly, if the tree is a literal string then the return value
|
||||
from <tt>unStr</tt> will be <tt>Just</tt> with the actual literal.
|
||||
Similarly, if the tree is a literal string then the return value
|
||||
from <tt>unStr</tt> will be <tt>Just</tt> with the actual literal.
|
||||
For example the result from:
|
||||
</span>
|
||||
<pre class="haskell">
|
||||
@@ -534,8 +545,8 @@ Prelude PGF2> readExpr "\"literal\"" >>= unStr
|
||||
<span class="java">
|
||||
The result from <tt>unApp</tt> is not <tt>null</tt> if the expression
|
||||
is an application, and <tt>null</tt> in all other cases.
|
||||
Similarly, if the tree is a literal string then the return value
|
||||
from <tt>unStr</tt> will not be <tt>null</tt> with the actual literal.
|
||||
Similarly, if the tree is a literal string then the return value
|
||||
from <tt>unStr</tt> will not be <tt>null</tt> with the actual literal.
|
||||
For example the output from:
|
||||
</span>
|
||||
<pre class="java">
|
||||
@@ -545,15 +556,15 @@ System.out.println(elit.unStr());
|
||||
<span class="csharp">
|
||||
The result from <tt>UnApp</tt> is not <tt>null</tt> if the expression
|
||||
is an application, and <tt>null</tt> in all other cases.
|
||||
Similarly, if the tree is a literal string then the return value
|
||||
from <tt>UnStr</tt> will not be <tt>null</tt> with the actual literal.
|
||||
Similarly, if the tree is a literal string then the return value
|
||||
from <tt>UnStr</tt> will not be <tt>null</tt> with the actual literal.
|
||||
For example the output from:
|
||||
</span>
|
||||
<pre class="csharp">
|
||||
Expr elit = Expr.ReadExpr("\"literal\"");
|
||||
Console.WriteLine(elit.UnStr());
|
||||
</pre>
|
||||
is just the string "literal".
|
||||
is just the string "literal".
|
||||
<span class="python">Situations like this can be detected
|
||||
in Python by checking the type of the result from <tt>unpack</tt>.
|
||||
It is also possible to get an integer or a floating point number
|
||||
@@ -569,7 +580,7 @@ There are also the methods <tt>UnAbs</tt>, <tt>UnInt</tt>, <tt>UnFloat</tt> and
|
||||
</span>
|
||||
</p>
|
||||
|
||||
Constructing new trees is also easy. You can either use
|
||||
Constructing new trees is also easy. You can either use
|
||||
<tt>readExpr</tt> to read trees from strings, or you can
|
||||
construct new trees from existing pieces. This is possible by
|
||||
<span class="python">
|
||||
@@ -612,7 +623,7 @@ Console.WriteLine(e2);
|
||||
<p>If the host application needs to do a lot of expression manipulations,
|
||||
then it is helpful to use a higher-level API to the grammar,
|
||||
also known as "embedded grammars" in GF. The advantage is that
|
||||
you can construct and analyze expressions in a more compact way.</p>
|
||||
you can construct and analyze expressions in a more compact way.</p>
|
||||
|
||||
<span class="python">
|
||||
<p>In Python you first have to <tt>embed</tt> the grammar by calling:
|
||||
@@ -721,7 +732,7 @@ call the method <tt>default</tt>. The following is an example:
|
||||
def on_DetCN(self,quant,cn):
|
||||
print("Found DetCN")
|
||||
cn.visit(self)
|
||||
|
||||
|
||||
def on_AdjCN(self,adj,cn):
|
||||
print("Found AdjCN")
|
||||
cn.visit(self)
|
||||
@@ -1007,7 +1018,7 @@ Traceback (most recent call last):
|
||||
pgf.PGFError: The concrete syntax is not loaded
|
||||
</pre>
|
||||
|
||||
Before using the concrete syntax, you need to explicitly load it:
|
||||
Before using the concrete syntax, you need to explicitly load it:
|
||||
<pre class="python">
|
||||
>>> eng.load("AppEng.pgf_c")
|
||||
>>> print(eng.lookupMorpho("letter"))
|
||||
@@ -1060,7 +1071,7 @@ Traceback (most recent call last):
|
||||
pgf.PGFError: The concrete syntax is not loaded
|
||||
</pre>
|
||||
|
||||
Before using the concrete syntax, you need to explicitly load it:
|
||||
Before using the concrete syntax, you need to explicitly load it:
|
||||
<pre class="java">
|
||||
eng.load("AppEng.pgf_c")
|
||||
for (MorphoAnalysis an : eng.lookupMorpho("letter")) {
|
||||
@@ -1289,6 +1300,7 @@ graph {
|
||||
}
|
||||
</pre>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -618,32 +618,32 @@ and **semantic definitions**.
|
||||
|
||||
|
||||
|
||||
#NEW
|
||||
|
||||
==Slides==
|
||||
|
||||
You can chop this tutorial into a set of slides by the command
|
||||
```
|
||||
htmls gf-tutorial.html
|
||||
```
|
||||
where the program ``htmls`` is distributed with GF (see below), in
|
||||
|
||||
[``GF/src/tools/Htmls.hs`` http://grammaticalframework.org/src/tools/Htmls.hs]
|
||||
|
||||
The slides will appear as a set of files beginning with ``01-gf-tutorial.htmls``.
|
||||
|
||||
Internal links will not work in the slide format, except for those in the
|
||||
upper left corner of each slide, and the links behind the "Contents" link.
|
||||
% #NEW
|
||||
%
|
||||
% ==Slides==
|
||||
%
|
||||
% You can chop this tutorial into a set of slides by the command
|
||||
% ```
|
||||
% htmls gf-tutorial.html
|
||||
% ```
|
||||
% where the program ``htmls`` is distributed with GF (see below), in
|
||||
%
|
||||
% [``GF/src/tools/Htmls.hs`` http://grammaticalframework.org/src/tools/Htmls.hs]
|
||||
%
|
||||
% The slides will appear as a set of files beginning with ``01-gf-tutorial.htmls``.
|
||||
%
|
||||
% Internal links will not work in the slide format, except for those in the
|
||||
% upper left corner of each slide, and the links behind the "Contents" link.
|
||||
|
||||
|
||||
|
||||
#NEW
|
||||
|
||||
#Lchaptwo
|
||||
|
||||
=Lesson 1: Getting Started with GF=
|
||||
|
||||
|
||||
#Lchaptwo
|
||||
|
||||
Goals:
|
||||
- install and run GF
|
||||
- write the first GF grammar: a "Hello World" grammar in three languages
|
||||
@@ -1037,9 +1037,10 @@ Application programs, using techniques from #Rchapeight:
|
||||
|
||||
#NEW
|
||||
|
||||
#Lchapthree
|
||||
|
||||
=Lesson 2: Designing a grammar for complex phrases=
|
||||
|
||||
#Lchapthree
|
||||
|
||||
Goals:
|
||||
- build a larger grammar: phrases about food in English and Italian
|
||||
@@ -1797,9 +1798,10 @@ where
|
||||
|
||||
#NEW
|
||||
|
||||
#Lchapfour
|
||||
|
||||
=Lesson 3: Grammars with parameters=
|
||||
|
||||
#Lchapfour
|
||||
|
||||
Goals:
|
||||
- implement sophisticated linguistic structures:
|
||||
@@ -2772,9 +2774,10 @@ Thus
|
||||
|
||||
#NEW
|
||||
|
||||
#Lchapfive
|
||||
|
||||
=Lesson 4: Using the resource grammar library=
|
||||
|
||||
#Lchapfive
|
||||
|
||||
Goals:
|
||||
- navigate in the GF resource grammar library and use it in applications
|
||||
@@ -3614,9 +3617,10 @@ tenses and moods, e.g. the Romance languages.
|
||||
|
||||
#NEW
|
||||
|
||||
#Lchapsix
|
||||
|
||||
=Lesson 5: Refining semantics in abstract syntax=
|
||||
|
||||
#Lchapsix
|
||||
|
||||
Goals:
|
||||
- include semantic conditions in grammars, by using
|
||||
@@ -4177,11 +4181,11 @@ Type checking can be invoked with ``put_term -transform=solve``.
|
||||
|
||||
#NEW
|
||||
|
||||
#Lchapseven
|
||||
|
||||
==Lesson 6: Grammars of formal languages==
|
||||
|
||||
|
||||
#Lchapseven
|
||||
|
||||
Goals:
|
||||
- write grammars for formal languages (mathematical notation, programming languages)
|
||||
- interface between formal and natural langauges
|
||||
@@ -4516,9 +4520,10 @@ point literals as arguments.
|
||||
|
||||
#NEW
|
||||
|
||||
#Lchapeight
|
||||
|
||||
=Lesson 7: Embedded grammars=
|
||||
|
||||
#Lchapeight
|
||||
|
||||
Goals:
|
||||
- use grammars as parts of programs written in Haskell and JavaScript
|
||||
@@ -4958,12 +4963,12 @@ syntax name. This file contains the multilingual grammar as a JavaScript object.
|
||||
===Using the JavaScript grammar===
|
||||
|
||||
To perform parsing and linearization, the run-time library
|
||||
``gflib.js`` is used. It is included in ``GF/lib/javascript/``, together with
|
||||
``gflib.js`` is used. It is included in ``/src/runtime/javascript/``, together with
|
||||
some other JavaScript and HTML files; these files can be used
|
||||
as templates for building applications.
|
||||
|
||||
An example of usage is
|
||||
[``translator.html`` http://grammaticalframework.org:41296],
|
||||
[``translator.html`` ../../src/runtime/javascript/translator.html],
|
||||
which is in fact initialized with
|
||||
a pointer to the Food grammar, so that it provides translation between the English
|
||||
and Italian grammars:
|
||||
|
||||
@@ -3,22 +3,23 @@ title: Grammatical Framework Download and Installation
|
||||
...
|
||||
|
||||
**GF 3.10** was released on 2 December 2018.
|
||||
It is the first version of GF which _does not include the RGL_.
|
||||
|
||||
What's new? See the [release notes](release-3.10.html).
|
||||
|
||||
## Binary packages
|
||||
|
||||
These binary packages include both the GF core (compiler and runtime) as well as the pre-compiled RGL.
|
||||
|
||||
| Platform | Download | Features | How to install |
|
||||
|:----------------|:---------------------------------------------------|:---------------|:-----------------------------------|
|
||||
| macOS | [gf-3.10.pkg](gf-3.10.pkg) | GF, S, C, J, P | Double-click on the package icon |
|
||||
| Ubuntu (64-bit) | [gf\_3.10-1\_amd64.deb](gf_3.10-1_amd64.deb) | GF, S, C, J, P | `sudo dpkg -i gf_3.10-1_amd64.deb` |
|
||||
| Ubuntu (32-bit) | [gf\_3.10-2\_i386.deb](gf_3.10-2_i386.deb) | GF, S, C, J, P | `sudo dpkg -i gf_3.10-2_i386.deb` |
|
||||
| Ubuntu (64-bit) | [gf\_3.10-2\_amd64.deb](gf_3.10-2_amd64.deb) | GF, S, C, J, P | `sudo dpkg -i gf_3.10-2_amd64.deb` |
|
||||
| Windows | [gf-3.10-bin-windows.zip](gf-3.10-bin-windows.zip) | GF, S | `unzip gf-3.10-bin-windows.zip` |
|
||||
|
||||
<!--
|
||||
| macOS | [gf-3.10-bin-intel-mac.tar.gz](gf-3.10-bin-intel-mac.tar.gz) | GF,S,C,J,P | `sudo tar -C /usr/local -zxf gf-3.10-bin-intel-mac.tar.gz` |
|
||||
| Raspbian 9.1 | [gf\_3.10-1\_armhf.deb](gf_3.10-1_armhf.deb) | GF,S,C,J,P | `sudo dpkg -i gf_3.10-1_armhf.deb` |
|
||||
| Ubuntu (32-bit) | [gf\_3.10-1\_i386.deb](gf_3.10-1_i386.deb) | GF,S,C,J,P | `sudo dpkg -i gf_3.10-1_i386.deb` |
|
||||
-->
|
||||
|
||||
**Features**
|
||||
@@ -35,7 +36,10 @@ probably need to set the `PATH` and `GF_LIB_PATH` environment variables,
|
||||
see Inari's notes on [Installing GF on Windows](http://www.grammaticalframework.org/~inari/gf-windows.html#toc3).
|
||||
|
||||
The Ubuntu `.deb` packages should work on Ubuntu 16.04 and 18.04 and
|
||||
similar Linux distributions.
|
||||
similar Linux distributions. The `.deb` packages were updated
|
||||
to version 3.10-2 after the release of GF 3.10.
|
||||
(Because of a packaging bug the Resource Grammar Library was missing
|
||||
in the 3.10-1 packages.)
|
||||
|
||||
<!-- The Raspbian `.deb` package was created on a Raspberry Pi 3 and will
|
||||
probably work on other ARM-based systems running Debian 9 (stretch) or
|
||||
@@ -66,12 +70,10 @@ normal circumstances the procedure is fairly simple:
|
||||
3. On Linux: install some C libraries from your Linux distribution (see note below)
|
||||
4. `cabal install gf`
|
||||
|
||||
Note that this installs GF _without_ the RGL.
|
||||
This installs the GF executable and Haskell libraries, but **does not include the RGL**.
|
||||
|
||||
You can also download full source packages from GitHub at the following links:
|
||||
|
||||
- [GF releases](https://github.com/GrammaticalFramework/gf-core/releases)
|
||||
- [RGL releases](https://github.com/GrammaticalFramework/gf-rgl/releases)
|
||||
You can also download the source code release from [GitHub](https://github.com/GrammaticalFramework/gf-core/releases),
|
||||
and follow the instructions below under **Installing from the latest developer source code**.
|
||||
|
||||
### Notes
|
||||
|
||||
@@ -166,6 +168,7 @@ make
|
||||
```
|
||||
|
||||
in the RGL folder.
|
||||
This assumes that you already have GF installed.
|
||||
For more details about building the RGL, see the [RGL README](https://github.com/GrammaticalFramework/gf-rgl/blob/master/README.md).
|
||||
|
||||
## Older releases
|
||||
|
||||
@@ -9,8 +9,58 @@ See the [download page](index.html).
|
||||
|
||||
## What's new
|
||||
|
||||
- In this release, the GF "core" (compiler and runtimes) have been split from the RGL.
|
||||
In this release, the GF "core" (compiler and runtimes) and RGL have been split into separate repositories.
|
||||
The binary packages on the downloads page contain both GF and the RGL, but the sources are now separate:
|
||||
[gf-core](https://github.com/GrammaticalFramework/gf-core) and
|
||||
[gf-rgl](https://github.com/GrammaticalFramework/gf-rgl).
|
||||
|
||||
### Other
|
||||
Over 300 changes have been pushed to GF and over 600 changes have been made to the RGL
|
||||
since the release of GF 3.9 in August 2017.
|
||||
|
||||
- A lot of repository cleanup
|
||||
## General
|
||||
|
||||
- Travis integration:
|
||||
GF [](https://travis-ci.org/GrammaticalFramework/gf-core) and
|
||||
RGL [](https://travis-ci.org/GrammaticalFramework/gf-rgl)
|
||||
- A lot of bug fixes and repository cleanup, including things moved to new repositories:
|
||||
- [Phrasebook](https://github.com/GrammaticalFramework/gf-contrib/tree/master/phrasebook)
|
||||
- [Wide coverage translator](https://github.com/GrammaticalFramework/wide-coverage)
|
||||
- [Mobile apps](https://github.com/GrammaticalFramework/gf-offline-translator)
|
||||
- [gftest](https://github.com/GrammaticalFramework/gftest)
|
||||
- [gf-mode](https://github.com/GrammaticalFramework/gf-emacs-mode) for Emacs
|
||||
- [RGL browser](https://github.com/GrammaticalFramework/rgl-source-browser) (live [here](http://www.grammaticalframework.org/~john/rgl-browser/))
|
||||
- A fresh look for the GF website.
|
||||
|
||||
## GF compiler and run-time library
|
||||
|
||||
- Extensive improvements in the C runtime and bindings to it from Python, Java, Haskell, C#
|
||||
- A GF shell which uses the C runtime
|
||||
- Better error messages
|
||||
- GF now has a Stack configuration file
|
||||
- The compiler source code has been updated for compatibility with GHC 8.4.3.
|
||||
- `GF_LIB_PATH` can now be `path1:path2:path3`, not just `path1`
|
||||
- Add TypeScript type definitions for `gflib.js`
|
||||
- New compiler/shell options
|
||||
- added option `-output-format=java` for producing code for embedded grammars in Java
|
||||
- `rf -paragraphs`
|
||||
- `linearize -tabtreebank`
|
||||
- A new function called `completions` is added in the Haskell runtime and used in PGFService. This makes the extraction of completions more platform independent
|
||||
|
||||
## Resource Grammar Library
|
||||
|
||||
- [Bash build script](https://github.com/GrammaticalFramework/gf-rgl/blob/master/Setup.sh), for building the RGL without Haskell
|
||||
- [Windows build script](https://github.com/GrammaticalFramework/gf-rgl/blob/master/Setup.bat), for building the RGL without Haskell on a regular Windows command shell
|
||||
- New languages:
|
||||
- Basque
|
||||
- Portuguese
|
||||
- Big progress with Arabic, Turkish, Persian
|
||||
- Introduction of `Extend` module to combine the functions of `Extra` and `Extensions` in a more disciplined way
|
||||
- Various fixes for several languages.
|
||||
- Various fixes in the translation dictionaries.
|
||||
|
||||
## Apps and Cloud services
|
||||
|
||||
- Sort list of public grammars by age by default
|
||||
- Browser compatibility fixes
|
||||
- Allow public grammars to be deleted in more cases
|
||||
- Show grammar comments in the list of public grammars
|
||||
|
||||
18
gf.cabal
18
gf.cabal
@@ -1,5 +1,5 @@
|
||||
name: gf
|
||||
version: 3.10
|
||||
version: 3.10.3-git
|
||||
|
||||
cabal-version: >= 1.22
|
||||
build-type: Custom
|
||||
@@ -81,7 +81,8 @@ Library
|
||||
random,
|
||||
pretty,
|
||||
mtl,
|
||||
exceptions
|
||||
exceptions,
|
||||
ghc-prim
|
||||
hs-source-dirs: src/runtime/haskell
|
||||
|
||||
other-modules:
|
||||
@@ -97,7 +98,8 @@ Library
|
||||
--if impl(ghc>=7.8)
|
||||
-- ghc-options: +RTS -A20M -RTS
|
||||
ghc-prof-options: -fprof-auto
|
||||
extensions:
|
||||
if impl(ghc>=8.6)
|
||||
Default-extensions: NoMonadFailDesugaring
|
||||
|
||||
exposed-modules:
|
||||
PGF
|
||||
@@ -141,8 +143,8 @@ Library
|
||||
|
||||
---- GF compiler as a library:
|
||||
|
||||
build-depends: filepath, directory, time, time-compat,
|
||||
process, haskeline, parallel>=3
|
||||
build-depends: filepath, directory>=1.2, time,
|
||||
process, haskeline, parallel>=3, json
|
||||
|
||||
hs-source-dirs: src/compiler
|
||||
exposed-modules:
|
||||
@@ -150,6 +152,7 @@ Library
|
||||
GF.Support
|
||||
GF.Text.Pretty
|
||||
GF.Text.Lexing
|
||||
GF.Grammar.Canonical
|
||||
|
||||
other-modules:
|
||||
GF.Main GF.Compiler GF.Interactive
|
||||
@@ -188,7 +191,10 @@ Library
|
||||
GF.Compile.PGFtoJava
|
||||
GF.Haskell
|
||||
GF.Compile.ConcreteToHaskell
|
||||
GF.Compile.GrammarToCanonical
|
||||
GF.Grammar.CanonicalJSON
|
||||
GF.Compile.PGFtoJS
|
||||
GF.Compile.PGFtoJSON
|
||||
GF.Compile.PGFtoProlog
|
||||
GF.Compile.PGFtoPython
|
||||
GF.Compile.ReadFiles
|
||||
@@ -267,7 +273,7 @@ Library
|
||||
cpp-options: -DC_RUNTIME
|
||||
|
||||
if flag(server)
|
||||
build-depends: httpd-shed>=0.4.0.3, network>=2.3 && <2.7, json,
|
||||
build-depends: httpd-shed>=0.4.0.3, network>=2.3 && <2.7,
|
||||
cgi>=3001.2.2.0
|
||||
if flag(network-uri)
|
||||
build-depends: network-uri>=2.6, network>=2.6
|
||||
|
||||
41
index.html
41
index.html
@@ -26,15 +26,19 @@
|
||||
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<h3>Get started</h3>
|
||||
<ul>
|
||||
<ul class="mb-2">
|
||||
<li><a href="https://www.youtube.com/watch?v=x1LFbDQhbso">Google Tech Talk</a></li>
|
||||
<li>
|
||||
<a href="http://cloud.grammaticalframework.org/">
|
||||
GF Cloud
|
||||
<img src="http://www.grammaticalframework.org/src/www/P/gf-cloud.png" style="height:30px" class="ml-2">
|
||||
<img src="http://www.grammaticalframework.org/src/www/P/gf-cloud.png" style="height:30px" class="ml-2" alt="Cloud logo">
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="doc/tutorial/gf-tutorial.html">Tutorial</a></li>
|
||||
<li>
|
||||
<a href="doc/tutorial/gf-tutorial.html">Tutorial</a>
|
||||
/
|
||||
<a href="lib/doc/rgl-tutorial/index.html">RGL Tutorial</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<a href="download/index.html" class="btn btn-primary ml-3">
|
||||
@@ -46,7 +50,7 @@
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<h3>Learn more</h3>
|
||||
|
||||
<ul>
|
||||
<ul class="mb-2">
|
||||
<li><a href="gf-book">The GF Book</a></li>
|
||||
<li><a href="doc/gf-refman.html">Reference Manual</a></li>
|
||||
<li><a href="doc/gf-shell-reference.html">Shell Reference</a></li>
|
||||
@@ -61,7 +65,7 @@
|
||||
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<h3>Develop</h3>
|
||||
<ul>
|
||||
<ul class="mb-2">
|
||||
<li><a href="doc/gf-developers.html">Developers Guide</a></li>
|
||||
<!-- <li><a href="/~hallgren/gf-experiment/browse/">Browse Source Code</a></li> -->
|
||||
<li><a href="http://hackage.haskell.org/package/gf/docs/PGF.html">PGF library API (Haskell runtime)</a></li>
|
||||
@@ -75,7 +79,7 @@
|
||||
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<h3>Contribute</h3>
|
||||
<ul>
|
||||
<ul class="mb-2">
|
||||
<li><a href="http://groups.google.com/group/gf-dev">Mailing List</a></li>
|
||||
<li><a href="https://github.com/GrammaticalFramework/gf-core/issues">Issue Tracker</a></li>
|
||||
<li><a href="doc/gf-people.html">Authors</a></li>
|
||||
@@ -205,7 +209,10 @@ least one, it may help you to get a first idea of what GF is.
|
||||
|
||||
<p>
|
||||
We run the IRC channel <strong><code>#gf</code></strong> on the Freenode network, where you are welcome to look for help with small questions or just start a general discussion.
|
||||
IRC logs (in raw format) are available <a href="http://www.grammaticalframework.org/irc/">here</a>.
|
||||
You can <a href="https://webchat.freenode.net/?channels=gf">open a web chat</a>
|
||||
or <a href="http://www.grammaticalframework.org/irc/">browse the channel logs</a>.
|
||||
</p>
|
||||
<p>
|
||||
If you have a larger question which the community may benefit from, we recommend you ask it on the <a href="http://groups.google.com/group/gf-dev">mailing list</a>.
|
||||
</p>
|
||||
|
||||
@@ -222,7 +229,7 @@ least one, it may help you to get a first idea of what GF is.
|
||||
<dt class="col-sm-3 text-center text-nowrap">2018-12-02</dt>
|
||||
<dd class="col-sm-9">
|
||||
<strong>GF 3.10 released.</strong>
|
||||
<!-- <a href="download/release-3.10.html">Release notes</a> -->
|
||||
<a href="download/release-3.10.html">Release notes</a>
|
||||
</dd>
|
||||
<dt class="col-sm-3 text-center text-nowrap">2018-07-25</dt>
|
||||
<dd class="col-sm-9">
|
||||
@@ -353,13 +360,14 @@ least one, it may help you to get a first idea of what GF is.
|
||||
Swedish,
|
||||
Thai,
|
||||
Turkish (fragments),
|
||||
Urdu
|
||||
and
|
||||
Urdu.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Adding a language to the resource library takes 3 to 9
|
||||
months - contributions
|
||||
are welcome! You can start with the <a href="doc/gf-lrec-2010.pdf">resource grammarian's tutorial</a>.
|
||||
are welcome! You can start with the <a href="lib/doc/rgl-tutorial/index.html">resource grammarian's tutorial</a>.
|
||||
</p>
|
||||
|
||||
</div><!-- .col-6 -->
|
||||
@@ -368,11 +376,14 @@ least one, it may help you to get a first idea of what GF is.
|
||||
|
||||
</div><!-- .container -->
|
||||
|
||||
<footer class="bg-light mt-5 py-5">
|
||||
<div class="container mb-5">
|
||||
<div class="row">
|
||||
<div>
|
||||
<div>
|
||||
<footer class="bg-light mt-5 py-4">
|
||||
<div class="container mb-3">
|
||||
<div class="text-center text-muted">
|
||||
<img style="height:50px; filter: opacity(.5) grayscale(1);" class="mb-3" src="doc/Logos/gf0.svg" alt="GF Logo"><br>
|
||||
Grammatical Framework is free and open source,<br>
|
||||
with some support from <a href="https://www.digitalgrammars.com/">Digital Grammars AB</a>.
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
@@ -19,7 +19,9 @@ module GF(
|
||||
module GF.Grammar.Printer,
|
||||
module GF.Infra.Ident,
|
||||
-- ** Binary serialisation
|
||||
module GF.Grammar.Binary
|
||||
module GF.Grammar.Binary,
|
||||
-- * Canonical GF
|
||||
module GF.Compile.GrammarToCanonical
|
||||
) where
|
||||
import GF.Main
|
||||
import GF.Compiler
|
||||
@@ -36,3 +38,5 @@ import GF.Grammar.Macros
|
||||
import GF.Grammar.Printer
|
||||
import GF.Infra.Ident
|
||||
import GF.Grammar.Binary
|
||||
|
||||
import GF.Compile.GrammarToCanonical
|
||||
|
||||
@@ -147,11 +147,17 @@ checkCompleteGrammar opts cwd gr (am,abs) (cm,cnc) = checkInModule cwd cnc NoLoc
|
||||
return $ updateTree (c,CncFun (Just linty) d mn mf) js
|
||||
_ -> do checkWarn ("function" <+> c <+> "is not in abstract")
|
||||
return js
|
||||
CncCat _ _ _ _ _ -> case lookupOrigInfo gr (am,c) of
|
||||
Ok _ -> return $ updateTree i js
|
||||
_ -> do checkWarn ("category" <+> c <+> "is not in abstract")
|
||||
return js
|
||||
_ -> return $ updateTree i js
|
||||
CncCat {} ->
|
||||
case lookupOrigInfo gr (am,c) of
|
||||
Ok (_,AbsCat _) -> return $ updateTree i js
|
||||
{- -- This might be too pedantic:
|
||||
Ok (_,AbsFun {}) ->
|
||||
checkError ("lincat:"<+>c<+>"is a fun, not a cat")
|
||||
-}
|
||||
_ -> do checkWarn ("category" <+> c <+> "is not in abstract")
|
||||
return js
|
||||
|
||||
_ -> return $ updateTree i js
|
||||
|
||||
|
||||
-- | General Principle: only Just-values are checked.
|
||||
|
||||
@@ -1,365 +1,351 @@
|
||||
-- | Translate concrete syntax to Haskell
|
||||
module GF.Compile.ConcreteToHaskell(concretes2haskell,concrete2haskell) where
|
||||
import Data.List(sort,sortBy)
|
||||
import Data.Function(on)
|
||||
import Data.List(isPrefixOf,sort,sortOn)
|
||||
import qualified Data.Map as M
|
||||
import qualified Data.Set as S
|
||||
import GF.Data.ErrM
|
||||
import GF.Data.Utilities(mapSnd)
|
||||
import GF.Text.Pretty
|
||||
import GF.Grammar.Grammar
|
||||
import GF.Grammar.Lookup(lookupFunType,lookupOrigInfo,allOrigInfos)--,allParamValues
|
||||
import GF.Grammar.Macros(typeForm,collectOp,collectPattOp,mkAbs,mkApp)
|
||||
import GF.Grammar.Lockfield(isLockLabel)
|
||||
import GF.Grammar.Predef(cPredef,cInts)
|
||||
import GF.Compile.Compute.Predef(predef)
|
||||
import GF.Compile.Compute.Value(Predefined(..))
|
||||
import GF.Infra.Ident(Ident,identS,prefixIdent) --,moduleNameS
|
||||
--import GF.Grammar.Predef(cPredef,cInts)
|
||||
--import GF.Compile.Compute.Predef(predef)
|
||||
--import GF.Compile.Compute.Value(Predefined(..))
|
||||
import GF.Infra.Ident(Ident,identS,identW,prefixIdent)
|
||||
import GF.Infra.Option
|
||||
import GF.Compile.Compute.ConcreteNew(normalForm,resourceValues)
|
||||
import GF.Haskell
|
||||
import Debug.Trace
|
||||
import GF.Haskell as H
|
||||
import GF.Grammar.Canonical as C
|
||||
import GF.Compile.GrammarToCanonical
|
||||
import Debug.Trace(trace)
|
||||
|
||||
-- | Generate Haskell code for the all concrete syntaxes associated with
|
||||
-- the named abstract syntax in given the grammar.
|
||||
concretes2haskell opts absname gr =
|
||||
[(cncname,concrete2haskell opts gr cenv absname cnc cncmod)
|
||||
| let cenv = resourceValues opts gr,
|
||||
cnc<-allConcretes gr absname,
|
||||
let cncname = render cnc ++ ".hs" :: FilePath
|
||||
Ok cncmod = lookupModule gr cnc
|
||||
[(filename,render80 $ concrete2haskell opts abstr cncmod)
|
||||
| let Grammar abstr cncs = grammar2canonical opts absname gr,
|
||||
cncmod<-cncs,
|
||||
let ModId name = concName cncmod
|
||||
filename = name ++ ".hs" :: FilePath
|
||||
]
|
||||
|
||||
-- | Generate Haskell code for the given concrete module.
|
||||
-- The only options that make a difference are
|
||||
-- @-haskell=noprefix@ and @-haskell=variants@.
|
||||
concrete2haskell opts gr cenv absname cnc modinfo =
|
||||
renderStyle style{lineLength=80,ribbonsPerLine=1} $
|
||||
haskPreamble va absname cnc $$ vcat (
|
||||
nl:Comment "--- Parameter types ---":
|
||||
neededParamTypes S.empty (params defs) ++
|
||||
nl:Comment "--- Type signatures for linearization functions ---":
|
||||
map signature (S.toList allcats)++
|
||||
nl:Comment "--- Linearization functions for empty categories ---":
|
||||
emptydefs ++
|
||||
nl:Comment "--- Linearization types and linearization functions ---":
|
||||
map ppDef defs ++
|
||||
nl:Comment "--- Type classes for projection functions ---":
|
||||
map labelClass (S.toList labels) ++
|
||||
nl:Comment "--- Record types ---":
|
||||
concatMap recordType recs)
|
||||
concrete2haskell opts
|
||||
abstr@(Abstract _ _ cats funs)
|
||||
modinfo@(Concrete cnc absname _ ps lcs lns) =
|
||||
haskPreamble absname cnc $$
|
||||
vcat (
|
||||
nl:Comment "--- Parameter types ---":
|
||||
map paramDef ps ++
|
||||
nl:Comment "--- Type signatures for linearization functions ---":
|
||||
map signature cats ++
|
||||
nl:Comment "--- Linearization functions for empty categories ---":
|
||||
emptydefs ++
|
||||
nl:Comment "--- Linearization types ---":
|
||||
map lincatDef lcs ++
|
||||
nl:Comment "--- Linearization functions ---":
|
||||
lindefs ++
|
||||
nl:Comment "--- Type classes for projection functions ---":
|
||||
map labelClass (S.toList labels) ++
|
||||
nl:Comment "--- Record types ---":
|
||||
concatMap recordType recs)
|
||||
where
|
||||
nl = Comment ""
|
||||
recs = S.toList (S.difference (records (lcs,lns)) common_records)
|
||||
|
||||
labels = S.difference (S.unions (map S.fromList recs)) common_labels
|
||||
recs = S.toList (S.difference (records rhss) common_records)
|
||||
common_records = S.fromList [[label_s]]
|
||||
common_labels = S.fromList [label_s]
|
||||
label_s = ident2label (identS "s")
|
||||
label_s = LabelId "s"
|
||||
|
||||
rhss = map (either snd (snd.snd)) defs
|
||||
defs = sortBy (compare `on` either (const Nothing) (Just . fst)) .
|
||||
concatMap (toHaskell gId gr absname cenv) .
|
||||
M.toList $
|
||||
jments modinfo
|
||||
|
||||
-- signature c = "lin"<>c<+>"::"<+>"A."<>gId c<+>"->"<+>"Lin"<>c
|
||||
-- signature c = "--lin"<>c<+>":: (Applicative f,Monad f) =>"<+>"A."<>gId c<+>"->"<+>"f Lin"<>c
|
||||
signature c = TypeSig lf (Fun abs (pure lin))
|
||||
signature (CatDef c _) = TypeSig lf (Fun abs (pure lin))
|
||||
where
|
||||
abs = tcon0 (prefixIdent "A." (gId c))
|
||||
lin = tcon0 lc
|
||||
lf = prefixIdent "lin" c
|
||||
lc = prefixIdent "Lin" c
|
||||
lf = linfunName c
|
||||
lc = lincatName c
|
||||
|
||||
emptydefs = map emptydef (S.toList emptyCats)
|
||||
emptydef c = Eqn (prefixIdent "lin" c,[WildP]) (Const "undefined")
|
||||
emptydef c = Eqn (linfunName c,[WildP]) (Const "undefined")
|
||||
|
||||
emptyCats = allcats `S.difference` cats
|
||||
cats = S.fromList [c|Right (c,_)<-defs]
|
||||
allcats = S.fromList [c|((_,c),AbsCat (Just _))<-allOrigInfos gr absname]
|
||||
emptyCats = allcats `S.difference` linfuncats
|
||||
where
|
||||
--funcats = S.fromList [c | FunDef f (C.Type _ (TypeApp c _))<-funs]
|
||||
allcats = S.fromList [c | CatDef c _<-cats]
|
||||
|
||||
gId :: ToIdent i => i -> Ident
|
||||
gId = (if haskellOption opts HaskellNoPrefix then id else prefixIdent "G")
|
||||
. toIdent
|
||||
|
||||
params = S.toList . S.unions . map params1
|
||||
params1 (Left (_,rhs)) = paramTypes gr rhs
|
||||
params1 (Right (_,(_,rhs))) = tableTypes gr [rhs]
|
||||
|
||||
ppDef (Left (lhs,rhs)) = lhs (convType va gId rhs)
|
||||
ppDef (Right (_,(lhs,rhs))) = lhs (convert va gId gr rhs)
|
||||
|
||||
gId :: Ident -> Ident
|
||||
gId = if haskellOption opts HaskellNoPrefix then id else prefixIdent "G"
|
||||
va = haskellOption opts HaskellVariants
|
||||
pure = if va then ListT else id
|
||||
|
||||
neededParamTypes have [] = []
|
||||
neededParamTypes have (q:qs) =
|
||||
if q `S.member` have
|
||||
then neededParamTypes have qs
|
||||
else let ((got,need),def) = paramType va gId gr q
|
||||
in def++neededParamTypes (S.union got have) (S.toList need++qs)
|
||||
|
||||
haskPreamble :: Bool -> ModuleName -> ModuleName -> Doc
|
||||
haskPreamble va absname cncname =
|
||||
"{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, LambdaCase #-}" $$
|
||||
"module" <+> cncname <+> "where" $$
|
||||
"import Prelude hiding (Ordering(..))" $$
|
||||
"import Control.Applicative((<$>),(<*>))" $$
|
||||
"import PGF.Haskell" $$
|
||||
"import qualified" <+> absname <+> "as A" $$
|
||||
"" $$
|
||||
"--- Standard definitions ---" $$
|
||||
"linString (A.GString s) ="<+>pure "R_s [TK s]" $$
|
||||
"linInt (A.GInt i) ="<+>pure "R_s [TK (show i)]" $$
|
||||
"linFloat (A.GFloat x) ="<+>pure "R_s [TK (show x)]" $$
|
||||
"" $$
|
||||
"----------------------------------------------------" $$
|
||||
"-- Automatic translation from GF to Haskell follows" $$
|
||||
"----------------------------------------------------"
|
||||
where
|
||||
pure = if va then brackets else pp
|
||||
|
||||
toHaskell gId gr absname cenv (name,jment) =
|
||||
case jment of
|
||||
CncCat (Just (L loc typ)) _ _ pprn _ ->
|
||||
[Left (tsyn0 (prefixIdent "Lin" name),nf loc typ)]
|
||||
CncFun (Just r@(cat,ctx,lincat)) (Just (L loc def)) pprn _ ->
|
||||
-- trace (render (name<+>hcat[parens (x<>"::"<>t)|(_,x,t)<-ctx]<+>"::"<+>cat)) $
|
||||
[Right (cat,(Eqn (prefixIdent "lin" cat,lhs),coerce [] lincat rhs))]
|
||||
haskPreamble :: ModId -> ModId -> Doc
|
||||
haskPreamble absname cncname =
|
||||
"{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, LambdaCase #-}" $$
|
||||
"module" <+> cncname <+> "where" $$
|
||||
"import Prelude hiding (Ordering(..))" $$
|
||||
"import Control.Applicative((<$>),(<*>))" $$
|
||||
"import PGF.Haskell" $$
|
||||
"import qualified" <+> absname <+> "as A" $$
|
||||
"" $$
|
||||
"--- Standard definitions ---" $$
|
||||
"linString (A.GString s) ="<+>pure "R_s [TK s]" $$
|
||||
"linInt (A.GInt i) ="<+>pure "R_s [TK (show i)]" $$
|
||||
"linFloat (A.GFloat x) ="<+>pure "R_s [TK (show x)]" $$
|
||||
"" $$
|
||||
"----------------------------------------------------" $$
|
||||
"-- Automatic translation from GF to Haskell follows" $$
|
||||
"----------------------------------------------------"
|
||||
where
|
||||
Ok abstype = lookupFunType gr absname name
|
||||
(absctx,_abscat,_absargs) = typeForm abstype
|
||||
pure = if va then brackets else pp
|
||||
|
||||
e' = unAbs (length params) $
|
||||
nf loc (mkAbs params (mkApp def (map Vr args)))
|
||||
params = [(b,prefixIdent "g" x)|(b,x,_)<-ctx]
|
||||
args = map snd params
|
||||
abs_args = map (prefixIdent "abs_") args
|
||||
lhs = [ConP (aId name) (map VarP abs_args)]
|
||||
rhs = foldr letlin e' (zip args absctx)
|
||||
letlin (a,(_,_,at)) =
|
||||
Let (a,(Just (con ("Lin"++render at)),(App (con ("lin"++render at)) (con ("abs_"++render a)))))
|
||||
AnyInd _ m -> case lookupOrigInfo gr (m,name) of
|
||||
Ok (m,jment) -> toHaskell gId gr absname cenv (name,jment)
|
||||
_ -> []
|
||||
_ -> []
|
||||
where
|
||||
nf loc = normalForm cenv (L loc name)
|
||||
aId n = prefixIdent "A." (gId n)
|
||||
paramDef pd =
|
||||
case pd of
|
||||
ParamAliasDef p t -> H.Type (conap0 (gId p)) (convLinType t)
|
||||
ParamDef p pvs -> Data (conap0 (gId p)) (map paramCon pvs) derive
|
||||
where
|
||||
paramCon (Param c cs) = ConAp (gId c) (map (tcon0.gId) cs)
|
||||
derive = ["Eq","Ord","Show"]
|
||||
|
||||
unAbs 0 t = t
|
||||
unAbs n (Abs _ _ t) = unAbs (n-1) t
|
||||
unAbs _ t = t
|
||||
convLinType = ppT
|
||||
where
|
||||
ppT t =
|
||||
case t of
|
||||
FloatType -> tcon0 (identS "Float")
|
||||
IntType -> tcon0 (identS "Int")
|
||||
ParamType (ParamTypeId p) -> tcon0 (gId p)
|
||||
RecordType rs -> tcon (rcon' ls) (map ppT ts)
|
||||
where (ls,ts) = unzip $ sortOn fst [(l,t)|RecordRow l t<-rs]
|
||||
StrType -> tcon0 (identS "Str")
|
||||
TableType pt lt -> Fun (ppT pt) (ppT lt)
|
||||
-- TupleType lts ->
|
||||
|
||||
lincatDef (LincatDef c t) = tsyn0 (lincatName c) (convLinType t)
|
||||
|
||||
linfuncats = S.fromList linfuncatl
|
||||
(linfuncatl,lindefs) = unzip (linDefs lns)
|
||||
|
||||
linDefs = map eqn . sortOn fst . map linDef
|
||||
where eqn (cat,(f,(ps,rhs))) = (cat,Eqn (f,ps) rhs)
|
||||
|
||||
linDef (LinDef f xs rhs0) =
|
||||
(cat,(linfunName cat,(lhs,rhs)))
|
||||
where
|
||||
lhs = [ConP (aId f) (map VarP abs_args)]
|
||||
aId f = prefixIdent "A." (gId f)
|
||||
|
||||
[lincat] = [lincat | LincatDef c lincat<-lcs,c==cat]
|
||||
[C.Type absctx (TypeApp cat _)] = [t | FunDef f' t<-funs, f'==f]
|
||||
|
||||
abs_args = map abs_arg args
|
||||
abs_arg = prefixIdent "abs_"
|
||||
args = map (prefixIdent "g" . toIdent) xs
|
||||
|
||||
rhs = lets (zipWith letlin args absctx)
|
||||
(convert vs (coerce env lincat rhs0))
|
||||
where
|
||||
vs = [(VarValueId (Unqual x),a)|(VarId x,a)<-zip xs args]
|
||||
env= [(VarValueId (Unqual x),lc)|(VarId x,lc)<-zip xs (map arglincat absctx)]
|
||||
|
||||
letlin a (TypeBinding _ (C.Type _ (TypeApp acat _))) =
|
||||
(a,Ap (Var (linfunName acat)) (Var (abs_arg a)))
|
||||
|
||||
arglincat (TypeBinding _ (C.Type _ (TypeApp acat _))) = lincat
|
||||
where
|
||||
[lincat] = [lincat | LincatDef c lincat<-lcs,c==acat]
|
||||
|
||||
convert = convert' va
|
||||
|
||||
convert' va vs = ppT
|
||||
where
|
||||
ppT0 = convert' False vs
|
||||
ppTv vs' = convert' va vs'
|
||||
|
||||
pure = if va then single else id
|
||||
|
||||
ppT t =
|
||||
case t of
|
||||
TableValue ty cs -> pure (table cs)
|
||||
Selection t p -> select (ppT t) (ppT p)
|
||||
ConcatValue t1 t2 -> concat (ppT t1) (ppT t2)
|
||||
RecordValue r -> aps (rcon ls) (map ppT ts)
|
||||
where (ls,ts) = unzip $ sortOn fst [(l,t)|RecordRow l t<-r]
|
||||
PredefValue p -> single (Var (toIdent p)) -- hmm
|
||||
Projection t l -> ap (proj l) (ppT t)
|
||||
VariantValue [] -> empty
|
||||
VariantValue ts@(_:_) -> variants ts
|
||||
VarValue x -> maybe (Var (gId x)) (pure . Var) $ lookup x vs
|
||||
PreValue vs t' -> pure (alts t' vs)
|
||||
ParamConstant (Param c vs) -> aps (Var (pId c)) (map ppT vs)
|
||||
ErrorValue s -> ap (Const "error") (Const (show s)) -- !!
|
||||
LiteralValue l -> ppL l
|
||||
_ -> error ("convert "++show t)
|
||||
|
||||
ppL l =
|
||||
case l of
|
||||
FloatConstant x -> pure (lit x)
|
||||
IntConstant n -> pure (lit n)
|
||||
StrConstant s -> pure (token s)
|
||||
|
||||
pId p@(ParamId s) =
|
||||
if "to_R_" `isPrefixOf` unqual s then toIdent p else gId p -- !! a hack
|
||||
|
||||
table cs =
|
||||
if all (null.patVars) ps
|
||||
then lets ds (LambdaCase [(ppP p,t')|(p,t')<-zip ps ts'])
|
||||
else LambdaCase (map ppCase cs)
|
||||
where
|
||||
(ds,ts') = dedup ts
|
||||
(ps,ts) = unzip [(p,t)|TableRow p t<-cs]
|
||||
ppCase (TableRow p t) = (ppP p,ppTv (patVars p++vs) t)
|
||||
{-
|
||||
ppPredef n =
|
||||
case predef n of
|
||||
Ok BIND -> single (c "BIND")
|
||||
Ok SOFT_BIND -> single (c "SOFT_BIND")
|
||||
Ok SOFT_SPACE -> single (c "SOFT_SPACE")
|
||||
Ok CAPIT -> single (c "CAPIT")
|
||||
Ok ALL_CAPIT -> single (c "ALL_CAPIT")
|
||||
_ -> Var n
|
||||
-}
|
||||
ppP p =
|
||||
case p of
|
||||
ParamPattern (Param c ps) -> ConP (gId c) (map ppP ps)
|
||||
RecordPattern r -> ConP (rcon' ls) (map ppP ps)
|
||||
where (ls,ps) = unzip $ sortOn fst [(l,p)|RecordRow l p<-r]
|
||||
WildPattern -> WildP
|
||||
|
||||
token s = single (c "TK" `Ap` lit s)
|
||||
|
||||
alts t' vs = single (c "TP" `Ap` List (map alt vs) `Ap` ppT0 t')
|
||||
where
|
||||
alt (s,t) = Pair (List (pre s)) (ppT0 t)
|
||||
pre s = map lit s
|
||||
|
||||
c = Const
|
||||
lit s = c (show s) -- hmm
|
||||
concat = if va then concat' else plusplus
|
||||
where
|
||||
concat' (List [List ts1]) (List [List ts2]) = List [List (ts1++ts2)]
|
||||
concat' t1 t2 = Op t1 "+++" t2
|
||||
|
||||
pure' = single -- forcing the list monad
|
||||
|
||||
select = if va then select' else Ap
|
||||
select' (List [t]) (List [p]) = Op t "!" p
|
||||
select' (List [t]) p = Op t "!$" p
|
||||
select' t p = Op t "!*" p
|
||||
|
||||
ap = if va then ap' else Ap
|
||||
where
|
||||
ap' (List [f]) x = fmap f x
|
||||
ap' f x = Op f "<*>" x
|
||||
fmap f (List [x]) = pure' (Ap f x)
|
||||
fmap f x = Op f "<$>" x
|
||||
|
||||
-- join = if va then join' else id
|
||||
join' (List [x]) = x
|
||||
join' x = c "concat" `Ap` x
|
||||
|
||||
empty = if va then List [] else c "error" `Ap` c (show "empty variant")
|
||||
variants = if va then \ ts -> join' (List (map ppT ts))
|
||||
else \ (t:_) -> ppT t
|
||||
|
||||
aps f [] = f
|
||||
aps f (a:as) = aps (ap f a) as
|
||||
|
||||
dedup ts =
|
||||
if M.null dups
|
||||
then ([],map ppT ts)
|
||||
else ([(ev i,ppT t)|(i,t)<-defs],zipWith entry ts is)
|
||||
where
|
||||
entry t i = maybe (ppT t) (Var . ev) (M.lookup i dups)
|
||||
ev i = identS ("e'"++show i)
|
||||
|
||||
defs = [(i1,t)|(t,i1:_:_)<-ms]
|
||||
dups = M.fromList [(i2,i1)|(_,i1:is@(_:_))<-ms,i2<-i1:is]
|
||||
ms = M.toList m
|
||||
m = fmap sort (M.fromListWith (++) (zip ts [[i]|i<-is]))
|
||||
is = [0..]::[Int]
|
||||
|
||||
|
||||
con = Cn . identS
|
||||
--con = Cn . identS
|
||||
|
||||
tableTypes gr ts = S.unions (map tabtys ts)
|
||||
where
|
||||
tabtys t =
|
||||
case t of
|
||||
V t cc -> S.union (paramTypes gr t) (tableTypes gr cc)
|
||||
T (TTyped t) cs -> S.union (paramTypes gr t) (tableTypes gr (map snd cs))
|
||||
_ -> collectOp tabtys t
|
||||
class Records t where
|
||||
records :: t -> S.Set [LabelId]
|
||||
|
||||
paramTypes gr t =
|
||||
case t of
|
||||
RecType fs -> S.unions (map (paramTypes gr.snd) fs)
|
||||
Table t1 t2 -> S.union (paramTypes gr t1) (paramTypes gr t2)
|
||||
App tf ta -> S.union (paramTypes gr tf) (paramTypes gr ta)
|
||||
Sort _ -> S.empty
|
||||
EInt _ -> S.empty
|
||||
Q q -> lookup q
|
||||
QC q -> lookup q
|
||||
FV ts -> S.unions (map (paramTypes gr) ts)
|
||||
_ -> ignore
|
||||
where
|
||||
lookup q = case lookupOrigInfo gr q of
|
||||
Ok (_,ResOper _ (Just (L _ t))) ->
|
||||
S.insert q (paramTypes gr t)
|
||||
Ok (_,ResParam {}) -> S.singleton q
|
||||
_ -> ignore
|
||||
instance Records t => Records [t] where
|
||||
records = S.unions . map records
|
||||
|
||||
ignore = trace ("Ignore: "++show t) S.empty
|
||||
|
||||
|
||||
|
||||
records ts = S.unions (map recs ts)
|
||||
where
|
||||
recs t =
|
||||
case t of
|
||||
R r -> S.insert (labels r) (records (map (snd.snd) r))
|
||||
RecType r -> S.insert (labels r) (records (map snd r))
|
||||
_ -> collectOp recs t
|
||||
|
||||
labels = sort . filter (not . isLockLabel) . map fst
|
||||
instance (Records t1,Records t2) => Records (t1,t2) where
|
||||
records (t1,t2) = S.union (records t1) (records t2)
|
||||
|
||||
instance Records LincatDef where
|
||||
records (LincatDef _ lt) = records lt
|
||||
|
||||
instance Records LinDef where
|
||||
records (LinDef _ _ lv) = records lv
|
||||
|
||||
instance Records LinType where
|
||||
records t =
|
||||
case t of
|
||||
RecordType r -> rowRecords r
|
||||
TableType pt lt -> records (pt,lt)
|
||||
TupleType ts -> records ts
|
||||
_ -> S.empty
|
||||
|
||||
rowRecords r = S.insert (sort ls) (records ts)
|
||||
where (ls,ts) = unzip [(l,t)|RecordRow l t<-r]
|
||||
|
||||
instance Records LinValue where
|
||||
records v =
|
||||
case v of
|
||||
ConcatValue v1 v2 -> records (v1,v2)
|
||||
ParamConstant (Param c vs) -> records vs
|
||||
RecordValue r -> rowRecords r
|
||||
TableValue t r -> records (t,r)
|
||||
TupleValue vs -> records vs
|
||||
VariantValue vs -> records vs
|
||||
PreValue alts d -> records (map snd alts,d)
|
||||
Projection v l -> records v
|
||||
Selection v1 v2 -> records (v1,v2)
|
||||
_ -> S.empty
|
||||
|
||||
instance Records rhs => Records (TableRow rhs) where
|
||||
records (TableRow _ v) = records v
|
||||
|
||||
|
||||
-- | Record subtyping is converted into explicit coercions in Haskell
|
||||
coerce env ty t =
|
||||
case (ty,t) of
|
||||
(_,Let d t) -> Let d (coerce (extend env d) ty t)
|
||||
(_,FV ts) -> FV (map (coerce env ty) ts)
|
||||
(Table ti tv,V _ ts) -> V ti (map (coerce env tv) ts)
|
||||
(Table ti tv,T (TTyped _) cs) -> T (TTyped ti) (mapSnd (coerce env tv) cs)
|
||||
(RecType rt,R r) ->
|
||||
R [(l,(Just ft,coerce env ft f))|(l,(_,f))<-r,Just ft<-[lookup l rt]]
|
||||
(RecType rt,Vr x)->
|
||||
(_,VariantValue ts) -> VariantValue (map (coerce env ty) ts)
|
||||
(TableType ti tv,TableValue _ cs) ->
|
||||
TableValue ti [TableRow p (coerce env tv t)|TableRow p t<-cs]
|
||||
(RecordType rt,RecordValue r) ->
|
||||
RecordValue [RecordRow l (coerce env ft f) |
|
||||
RecordRow l f<-r,ft<-[ft|RecordRow l' ft<-rt,l'==l]]
|
||||
(RecordType rt,VarValue x)->
|
||||
case lookup x env of
|
||||
Just ty' | ty'/=ty -> -- better to compare to normal form of ty'
|
||||
--trace ("coerce "++render ty'++" to "++render ty) $
|
||||
App (to_rcon (map fst rt)) t
|
||||
_ -> trace ("no coerce to "++render ty) t
|
||||
--trace ("coerce "++render ty'++" to "++render ty) $
|
||||
app (to_rcon rt) [t]
|
||||
| otherwise -> t -- types match, no coercion needed
|
||||
_ -> trace (render ("missing type to coerce"<+>x<+>"to"<+>render ty
|
||||
$$ "in" <+> map fst env))
|
||||
t
|
||||
_ -> t
|
||||
where
|
||||
extend env (x,(Just ty,rhs)) = (x,ty):env
|
||||
extend env _ = env
|
||||
app f ts = ParamConstant (Param f ts) -- !! a hack
|
||||
to_rcon = ParamId . Unqual . to_rcon' . labels
|
||||
|
||||
convert va gId gr = convert' va gId [] gr
|
||||
patVars p = []
|
||||
|
||||
convert' va gId vs gr = ppT
|
||||
where
|
||||
ppT0 = convert' False gId vs gr
|
||||
ppTv vs' = convert' va gId vs' gr
|
||||
labels r = [l|RecordRow l _<-r]
|
||||
|
||||
ppT t =
|
||||
case t of
|
||||
-- Only for 'let' inserted on the top-level by this converter:
|
||||
Let (x,(_,xt)) t -> let1 x (ppT0 xt) (ppT t)
|
||||
-- Abs b x t -> ...
|
||||
V ty ts -> pure (c "table" `Ap` dedup ts)
|
||||
T (TTyped ty) cs -> pure (LambdaCase (map ppCase cs))
|
||||
S t p -> select (ppT t) (ppT p)
|
||||
C t1 t2 -> concat (ppT t1) (ppT t2)
|
||||
App f a -> ap (ppT f) (ppT a)
|
||||
R r -> aps (ppT (rcon (map fst r))) (fields r)
|
||||
P t l -> ap (ppT (proj l)) (ppT t)
|
||||
FV [] -> empty
|
||||
Vr x -> if x `elem` vs then pure (Var x) else Var x
|
||||
Cn x -> pure (Var x)
|
||||
Con c -> pure (Var (gId c))
|
||||
Sort k -> pure (Var k)
|
||||
EInt n -> pure (lit n)
|
||||
Q (m,n) -> if m==cPredef then pure (ppPredef n) else Var (qual m n)
|
||||
QC (m,n) -> pure (Var (gId (qual m n)))
|
||||
K s -> pure (token s)
|
||||
Empty -> pure (List [])
|
||||
FV ts@(_:_) -> variants ts
|
||||
Alts t' vs -> pure (alts t' vs)
|
||||
|
||||
ppCase (p,t) = (ppP p,ppTv (patVars p++vs) t)
|
||||
|
||||
ppPredef n =
|
||||
case predef n of
|
||||
Ok BIND -> single (c "BIND")
|
||||
Ok SOFT_BIND -> single (c "SOFT_BIND")
|
||||
Ok SOFT_SPACE -> single (c "SOFT_SPACE")
|
||||
Ok CAPIT -> single (c "CAPIT")
|
||||
Ok ALL_CAPIT -> single (c "ALL_CAPIT")
|
||||
_ -> Var n
|
||||
|
||||
ppP p =
|
||||
case p of
|
||||
PC c ps -> ConP (gId c) (map ppP ps)
|
||||
PP (_,c) ps -> ConP (gId c) (map ppP ps)
|
||||
PR r -> ConP (rcon' (map fst r)) (map (ppP.snd) (filter (not.isLockLabel.fst) r))
|
||||
PW -> WildP
|
||||
PV x -> VarP x
|
||||
PString s -> Lit (show s) -- !!
|
||||
PInt i -> Lit (show i)
|
||||
PFloat x -> Lit (show x)
|
||||
PT _ p -> ppP p
|
||||
PAs x p -> AsP x (ppP p)
|
||||
|
||||
token s = single (c "TK" `Ap` lit s)
|
||||
|
||||
alts t' vs = single (c "TP" `Ap` List (map alt vs) `Ap` ppT0 t')
|
||||
where
|
||||
alt (t,p) = Pair (List (pre p)) (ppT0 t)
|
||||
|
||||
pre (K s) = [lit s]
|
||||
pre (Strs ts) = concatMap pre ts
|
||||
pre (EPatt p) = pat p
|
||||
pre t = error $ "pre "++show t
|
||||
|
||||
pat (PString s) = [lit s]
|
||||
pat (PAlt p1 p2) = pat p1++pat p2
|
||||
pat p = error $ "pat "++show p
|
||||
|
||||
fields = map (ppT.snd.snd) . sort . filter (not.isLockLabel.fst)
|
||||
|
||||
c = Const
|
||||
lit s = c (show s) -- hmm
|
||||
concat = if va then concat' else plusplus
|
||||
where
|
||||
concat' (List [List ts1]) (List [List ts2]) = List [List (ts1++ts2)]
|
||||
concat' t1 t2 = Op t1 "+++" t2
|
||||
pure = if va then single else id
|
||||
pure' = single -- forcing the list monad
|
||||
|
||||
select = if va then select' else Ap
|
||||
select' (List [t]) (List [p]) = Op t "!" p
|
||||
select' (List [t]) p = Op t "!$" p
|
||||
select' t p = Op t "!*" p
|
||||
|
||||
ap = if va then ap' else Ap
|
||||
where
|
||||
ap' (List [f]) x = fmap f x
|
||||
ap' f x = Op f "<*>" x
|
||||
fmap f (List [x]) = pure' (Ap f x)
|
||||
fmap f x = Op f "<$>" x
|
||||
|
||||
-- join = if va then join' else id
|
||||
join' (List [x]) = x
|
||||
join' x = c "concat" `Ap` x
|
||||
|
||||
empty = if va then List [] else c "error" `Ap` c (show "empty variant")
|
||||
variants = if va then \ ts -> join' (List (map ppT ts))
|
||||
else \ (t:_) -> ppT t
|
||||
|
||||
aps f [] = f
|
||||
aps f (a:as) = aps (ap f a) as
|
||||
|
||||
dedup ts =
|
||||
if M.null dups
|
||||
then List (map ppT ts)
|
||||
else Lets [(ev i,ppT t)|(i,t)<-defs] (List (zipWith entry ts is))
|
||||
where
|
||||
entry t i = maybe (ppT t) (Var . ev) (M.lookup i dups)
|
||||
ev i = identS ("e'"++show i)
|
||||
|
||||
defs = [(i1,t)|(t,i1:_:_)<-ms]
|
||||
dups = M.fromList [(i2,i1)|(_,i1:is@(_:_))<-ms,i2<-i1:is]
|
||||
ms = M.toList m
|
||||
m = fmap sort (M.fromListWith (++) (zip ts [[i]|i<-is]))
|
||||
is = [0..]::[Int]
|
||||
|
||||
patVars p =
|
||||
case p of
|
||||
PV x -> [x]
|
||||
PAs x p -> x:patVars p
|
||||
_ -> collectPattOp patVars p
|
||||
|
||||
convType va gId = ppT
|
||||
where
|
||||
ppT t =
|
||||
case t of
|
||||
Table ti tv -> Fun (ppT ti) (if va then ListT (ppT tv) else ppT tv)
|
||||
RecType rt -> tcon (rcon' (map fst rt)) (fields rt)
|
||||
App tf ta -> TAp (ppT tf) (ppT ta)
|
||||
FV [] -> tcon0 (identS "({-empty variant-})")
|
||||
Sort k -> tcon0 k
|
||||
EInt n -> tcon0 (identS ("({-"++show n++"-})")) -- type level numeric literal
|
||||
FV (t:ts) -> ppT t -- !!
|
||||
QC (m,n) -> tcon0 (gId (qual m n))
|
||||
Q (m,n) -> tcon0 (gId (qual m n))
|
||||
_ -> error $ "Missing case in convType for: "++show t
|
||||
|
||||
fields = map (ppT.snd) . sort . filter (not.isLockLabel.fst)
|
||||
|
||||
proj = con . proj'
|
||||
proj' l = "proj_"++render l
|
||||
rcon = con . rcon_name
|
||||
proj = Var . identS . proj'
|
||||
proj' (LabelId l) = "proj_"++l
|
||||
rcon = Var . rcon'
|
||||
rcon' = identS . rcon_name
|
||||
rcon_name ls = "R"++concat (sort ['_':render l|l<-ls,not (isLockLabel l)])
|
||||
to_rcon = con . to_rcon'
|
||||
rcon_name ls = "R"++concat (sort ['_':l|LabelId l<-ls])
|
||||
|
||||
to_rcon' = ("to_"++) . rcon_name
|
||||
|
||||
recordType ls =
|
||||
@@ -400,31 +386,6 @@ labelClass l =
|
||||
r = identS "r"
|
||||
a = identS "a"
|
||||
|
||||
paramType va gId gr q@(_,n) =
|
||||
case lookupOrigInfo gr q of
|
||||
Ok (m,ResParam (Just (L _ ps)) _)
|
||||
{- - | m/=cPredef && m/=moduleNameS "Prelude"-} ->
|
||||
((S.singleton (m,n),argTypes ps),
|
||||
[Data (conap0 name) (map (param m) ps)["Eq","Ord","Show"],
|
||||
Instance [] (TId (identS "EnumAll") `TAp` TId name)
|
||||
[(lhs0 "enumAll",foldr1 plusplus (map (enumParam m) ps))]]
|
||||
)
|
||||
where name = gId (qual m n)
|
||||
Ok (m,ResOper _ (Just (L _ t)))
|
||||
| m==cPredef && n==cInts ->
|
||||
((S.singleton (m,n),S.empty),
|
||||
[Type (ConAp (gId (qual m n)) [identS "n"]) (TId (identS "Int"))])
|
||||
| otherwise ->
|
||||
((S.singleton (m,n),paramTypes gr t),
|
||||
[Type (conap0 (gId (qual m n))) (convType va gId t)])
|
||||
_ -> ((S.empty,S.empty),[])
|
||||
where
|
||||
param m (n,ctx) = ConAp (gId (qual m n)) [convType va gId t|(_,_,t)<-ctx]
|
||||
argTypes = S.unions . map argTypes1
|
||||
argTypes1 (n,ctx) = S.unions [paramTypes gr t|(_,_,t)<-ctx]
|
||||
|
||||
enumParam m (n,ctx) = enumCon (gId (qual m n)) (length ctx)
|
||||
|
||||
enumCon name arity =
|
||||
if arity==0
|
||||
then single (Var name)
|
||||
@@ -433,5 +394,23 @@ enumCon name arity =
|
||||
ap (List [f]) a = Op f "<$>" a
|
||||
ap f a = Op f "<*>" a
|
||||
|
||||
qual :: ModuleName -> Ident -> Ident
|
||||
qual m = prefixIdent (render m++"_")
|
||||
lincatName,linfunName :: CatId -> Ident
|
||||
lincatName c = prefixIdent "Lin" (toIdent c)
|
||||
linfunName c = prefixIdent "lin" (toIdent c)
|
||||
|
||||
class ToIdent i where toIdent :: i -> Ident
|
||||
|
||||
instance ToIdent ParamId where toIdent (ParamId q) = qIdentS q
|
||||
instance ToIdent PredefId where toIdent (PredefId s) = identS s
|
||||
instance ToIdent CatId where toIdent (CatId s) = identS s
|
||||
instance ToIdent C.FunId where toIdent (FunId s) = identS s
|
||||
instance ToIdent VarValueId where toIdent (VarValueId q) = qIdentS q
|
||||
|
||||
qIdentS = identS . unqual
|
||||
|
||||
unqual (Qual (ModId m) n) = m++"_"++n
|
||||
unqual (Unqual n) = n
|
||||
|
||||
instance ToIdent VarId where
|
||||
toIdent Anonymous = identW
|
||||
toIdent (VarId s) = identS s
|
||||
|
||||
@@ -3,9 +3,11 @@ module GF.Compile.Export where
|
||||
import PGF
|
||||
import PGF.Internal(ppPGF)
|
||||
import GF.Compile.PGFtoHaskell
|
||||
--import GF.Compile.PGFtoAbstract
|
||||
import GF.Compile.PGFtoJava
|
||||
import GF.Compile.PGFtoProlog
|
||||
import GF.Compile.PGFtoJS
|
||||
import GF.Compile.PGFtoJSON
|
||||
import GF.Compile.PGFtoPython
|
||||
import GF.Infra.Option
|
||||
--import GF.Speech.CFG
|
||||
@@ -34,7 +36,10 @@ exportPGF :: Options
|
||||
exportPGF opts fmt pgf =
|
||||
case fmt of
|
||||
FmtPGFPretty -> multi "txt" (render . ppPGF)
|
||||
FmtCanonicalGF -> [] -- canon "gf" (render80 . abstract2canonical)
|
||||
FmtCanonicalJson-> []
|
||||
FmtJavaScript -> multi "js" pgf2js
|
||||
FmtJSON -> multi "json" pgf2json
|
||||
FmtPython -> multi "py" pgf2python
|
||||
FmtHaskell -> multi "hs" (grammar2haskell opts name)
|
||||
FmtJava -> multi "java" (grammar2java opts name)
|
||||
@@ -57,9 +62,12 @@ exportPGF opts fmt pgf =
|
||||
multi :: String -> (PGF -> String) -> [(FilePath,String)]
|
||||
multi ext pr = [(name <.> ext, pr pgf)]
|
||||
|
||||
-- canon ext pr = [("canonical"</>name<.>ext,pr pgf)]
|
||||
|
||||
single :: String -> (PGF -> CId -> String) -> [(FilePath,String)]
|
||||
single ext pr = [(showCId cnc <.> ext, pr pgf cnc) | cnc <- languages pgf]
|
||||
|
||||
|
||||
-- | Get the name of the concrete syntax to generate output from.
|
||||
-- FIXME: there should be an option to change this.
|
||||
outputConcr :: PGF -> CId
|
||||
|
||||
388
src/compiler/GF/Compile/GrammarToCanonical.hs
Normal file
388
src/compiler/GF/Compile/GrammarToCanonical.hs
Normal file
@@ -0,0 +1,388 @@
|
||||
-- | Translate grammars to Canonical form
|
||||
-- (a common intermediate representation to simplify export to other formats)
|
||||
module GF.Compile.GrammarToCanonical(
|
||||
grammar2canonical,abstract2canonical,concretes2canonical,
|
||||
projection,selection
|
||||
) where
|
||||
import Data.List(nub,partition)
|
||||
import qualified Data.Map as M
|
||||
import qualified Data.Set as S
|
||||
import GF.Data.ErrM
|
||||
import GF.Text.Pretty
|
||||
import GF.Grammar.Grammar
|
||||
import GF.Grammar.Lookup(lookupOrigInfo,allOrigInfos,allParamValues)
|
||||
import GF.Grammar.Macros(typeForm,collectOp,collectPattOp,mkAbs,mkApp,term2patt)
|
||||
import GF.Grammar.Lockfield(isLockLabel)
|
||||
import GF.Grammar.Predef(cPredef,cInts)
|
||||
import GF.Compile.Compute.Predef(predef)
|
||||
import GF.Compile.Compute.Value(Predefined(..))
|
||||
import GF.Infra.Ident(ModuleName(..),Ident,prefixIdent,showIdent,isWildIdent)
|
||||
import GF.Infra.Option(optionsPGF)
|
||||
import PGF.Internal(Literal(..))
|
||||
import GF.Compile.Compute.ConcreteNew(normalForm,resourceValues)
|
||||
import GF.Grammar.Canonical as C
|
||||
import Debug.Trace
|
||||
|
||||
-- | Generate Canonical code for the named abstract syntax and all associated
|
||||
-- concrete syntaxes
|
||||
grammar2canonical opts absname gr =
|
||||
Grammar (abstract2canonical absname gr)
|
||||
(map snd (concretes2canonical opts absname gr))
|
||||
|
||||
-- | Generate Canonical code for the named abstract syntax
|
||||
abstract2canonical absname gr =
|
||||
Abstract (modId absname) (convFlags gr absname) cats funs
|
||||
where
|
||||
cats = [CatDef (gId c) (convCtx ctx) | ((_,c),AbsCat ctx) <- adefs]
|
||||
|
||||
funs = [FunDef (gId f) (convType ty) |
|
||||
((_,f),AbsFun (Just (L _ ty)) ma mdef _) <- adefs]
|
||||
|
||||
adefs = allOrigInfos gr absname
|
||||
|
||||
convCtx = maybe [] (map convHypo . unLoc)
|
||||
convHypo (bt,name,t) =
|
||||
case typeForm t of
|
||||
([],(_,cat),[]) -> gId cat -- !!
|
||||
|
||||
convType t =
|
||||
case typeForm t of
|
||||
(hyps,(_,cat),args) -> Type bs (TypeApp (gId cat) as)
|
||||
where
|
||||
bs = map convHypo' hyps
|
||||
as = map convType args
|
||||
|
||||
convHypo' (bt,name,t) = TypeBinding (gId name) (convType t)
|
||||
|
||||
|
||||
-- | Generate Canonical code for the all concrete syntaxes associated with
|
||||
-- the named abstract syntax in given the grammar.
|
||||
concretes2canonical opts absname gr =
|
||||
[(cncname,concrete2canonical gr cenv absname cnc cncmod)
|
||||
| let cenv = resourceValues opts gr,
|
||||
cnc<-allConcretes gr absname,
|
||||
let cncname = "canonical/"++render cnc ++ ".gf" :: FilePath
|
||||
Ok cncmod = lookupModule gr cnc
|
||||
]
|
||||
|
||||
-- | Generate Canonical GF for the given concrete module.
|
||||
concrete2canonical gr cenv absname cnc modinfo =
|
||||
Concrete (modId cnc) (modId absname) (convFlags gr cnc)
|
||||
(neededParamTypes S.empty (params defs))
|
||||
[lincat|(_,Left lincat)<-defs]
|
||||
[lin|(_,Right lin)<-defs]
|
||||
where
|
||||
defs = concatMap (toCanonical gr absname cenv) .
|
||||
M.toList $
|
||||
jments modinfo
|
||||
|
||||
params = S.toList . S.unions . map fst
|
||||
|
||||
neededParamTypes have [] = []
|
||||
neededParamTypes have (q:qs) =
|
||||
if q `S.member` have
|
||||
then neededParamTypes have qs
|
||||
else let ((got,need),def) = paramType gr q
|
||||
in def++neededParamTypes (S.union got have) (S.toList need++qs)
|
||||
|
||||
toCanonical gr absname cenv (name,jment) =
|
||||
case jment of
|
||||
CncCat (Just (L loc typ)) _ _ pprn _ ->
|
||||
[(pts,Left (LincatDef (gId name) (convType ntyp)))]
|
||||
where
|
||||
pts = paramTypes gr ntyp
|
||||
ntyp = nf loc typ
|
||||
CncFun (Just r@(cat,ctx,lincat)) (Just (L loc def)) pprn _ ->
|
||||
[(tts,Right (LinDef (gId name) (map gId args) (convert gr e')))]
|
||||
where
|
||||
tts = tableTypes gr [e']
|
||||
|
||||
e' = unAbs (length params) $
|
||||
nf loc (mkAbs params (mkApp def (map Vr args)))
|
||||
params = [(b,x)|(b,x,_)<-ctx]
|
||||
args = map snd params
|
||||
|
||||
AnyInd _ m -> case lookupOrigInfo gr (m,name) of
|
||||
Ok (m,jment) -> toCanonical gr absname cenv (name,jment)
|
||||
_ -> []
|
||||
_ -> []
|
||||
where
|
||||
nf loc = normalForm cenv (L loc name)
|
||||
-- aId n = prefixIdent "A." (gId n)
|
||||
|
||||
unAbs 0 t = t
|
||||
unAbs n (Abs _ _ t) = unAbs (n-1) t
|
||||
unAbs _ t = t
|
||||
|
||||
tableTypes gr ts = S.unions (map tabtys ts)
|
||||
where
|
||||
tabtys t =
|
||||
case t of
|
||||
V t cc -> S.union (paramTypes gr t) (tableTypes gr cc)
|
||||
T (TTyped t) cs -> S.union (paramTypes gr t) (tableTypes gr (map snd cs))
|
||||
_ -> collectOp tabtys t
|
||||
|
||||
paramTypes gr t =
|
||||
case t of
|
||||
RecType fs -> S.unions (map (paramTypes gr.snd) fs)
|
||||
Table t1 t2 -> S.union (paramTypes gr t1) (paramTypes gr t2)
|
||||
App tf ta -> S.union (paramTypes gr tf) (paramTypes gr ta)
|
||||
Sort _ -> S.empty
|
||||
EInt _ -> S.empty
|
||||
Q q -> lookup q
|
||||
QC q -> lookup q
|
||||
FV ts -> S.unions (map (paramTypes gr) ts)
|
||||
_ -> ignore
|
||||
where
|
||||
lookup q = case lookupOrigInfo gr q of
|
||||
Ok (_,ResOper _ (Just (L _ t))) ->
|
||||
S.insert q (paramTypes gr t)
|
||||
Ok (_,ResParam {}) -> S.singleton q
|
||||
_ -> ignore
|
||||
|
||||
ignore = trace ("Ignore: "++show t) S.empty
|
||||
|
||||
|
||||
convert gr = convert' gr []
|
||||
|
||||
convert' gr vs = ppT
|
||||
where
|
||||
ppT0 = convert' gr vs
|
||||
ppTv vs' = convert' gr vs'
|
||||
|
||||
ppT t =
|
||||
case t of
|
||||
-- Abs b x t -> ...
|
||||
-- V ty ts -> VTableValue (convType ty) (map ppT ts)
|
||||
V ty ts -> TableValue (convType ty) [TableRow (ppP p) (ppT t)|(p,t)<-zip ps ts]
|
||||
where
|
||||
Ok pts = allParamValues gr ty
|
||||
Ok ps = mapM term2patt pts
|
||||
T (TTyped ty) cs -> TableValue (convType ty) (map ppCase cs)
|
||||
S t p -> selection (ppT t) (ppT p)
|
||||
C t1 t2 -> concatValue (ppT t1) (ppT t2)
|
||||
App f a -> ap (ppT f) (ppT a)
|
||||
R r -> RecordValue (fields r)
|
||||
P t l -> projection (ppT t) (lblId l)
|
||||
Vr x -> VarValue (gId x)
|
||||
Cn x -> VarValue (gId x) -- hmm
|
||||
Con c -> ParamConstant (Param (gId c) [])
|
||||
Sort k -> VarValue (gId k)
|
||||
EInt n -> LiteralValue (IntConstant n)
|
||||
Q (m,n) -> if m==cPredef then ppPredef n else VarValue ((gQId m n))
|
||||
QC (m,n) -> ParamConstant (Param ((gQId m n)) [])
|
||||
K s -> LiteralValue (StrConstant s)
|
||||
Empty -> LiteralValue (StrConstant "")
|
||||
FV ts -> VariantValue (map ppT ts)
|
||||
Alts t' vs -> alts vs (ppT t')
|
||||
_ -> error $ "convert' "++show t
|
||||
|
||||
ppCase (p,t) = TableRow (ppP p) (ppTv (patVars p++vs) t)
|
||||
|
||||
ppPredef n =
|
||||
case predef n of
|
||||
Ok BIND -> p "BIND"
|
||||
Ok SOFT_BIND -> p "SOFT_BIND"
|
||||
Ok SOFT_SPACE -> p "SOFT_SPACE"
|
||||
Ok CAPIT -> p "CAPIT"
|
||||
Ok ALL_CAPIT -> p "ALL_CAPIT"
|
||||
_ -> VarValue (gQId cPredef n) -- hmm
|
||||
where
|
||||
p = PredefValue . PredefId
|
||||
|
||||
ppP p =
|
||||
case p of
|
||||
PC c ps -> ParamPattern (Param (gId c) (map ppP ps))
|
||||
PP (m,c) ps -> ParamPattern (Param ((gQId m c)) (map ppP ps))
|
||||
PR r -> RecordPattern (fields r) {-
|
||||
PW -> WildPattern
|
||||
PV x -> VarP x
|
||||
PString s -> Lit (show s) -- !!
|
||||
PInt i -> Lit (show i)
|
||||
PFloat x -> Lit (show x)
|
||||
PT _ p -> ppP p
|
||||
PAs x p -> AsP x (ppP p) -}
|
||||
where
|
||||
fields = map field . filter (not.isLockLabel.fst)
|
||||
field (l,p) = RecordRow (lblId l) (ppP p)
|
||||
|
||||
-- patToParam p = case ppP p of ParamPattern pv -> pv
|
||||
|
||||
-- token s = single (c "TK" `Ap` lit s)
|
||||
|
||||
alts vs = PreValue (map alt vs)
|
||||
where
|
||||
alt (t,p) = (pre p,ppT0 t)
|
||||
|
||||
pre (K s) = [s]
|
||||
pre (Strs ts) = concatMap pre ts
|
||||
pre (EPatt p) = pat p
|
||||
pre t = error $ "pre "++show t
|
||||
|
||||
pat (PString s) = [s]
|
||||
pat (PAlt p1 p2) = pat p1++pat p2
|
||||
pat (PSeq p1 p2) = [s1++s2 | s1<-pat p1, s2<-pat p2]
|
||||
pat p = error $ "pat "++show p
|
||||
|
||||
fields = map field . filter (not.isLockLabel.fst)
|
||||
field (l,(_,t)) = RecordRow (lblId l) (ppT t)
|
||||
--c = Const
|
||||
--c = VarValue . VarValueId
|
||||
--lit s = c (show s) -- hmm
|
||||
|
||||
ap f a = case f of
|
||||
ParamConstant (Param p ps) ->
|
||||
ParamConstant (Param p (ps++[a]))
|
||||
_ -> error $ "convert' ap: "++render (ppA f <+> ppA a)
|
||||
|
||||
concatValue v1 v2 =
|
||||
case (v1,v2) of
|
||||
(LiteralValue (StrConstant ""),_) -> v2
|
||||
(_,LiteralValue (StrConstant "")) -> v1
|
||||
_ -> ConcatValue v1 v2
|
||||
|
||||
-- | Smart constructor for projections
|
||||
projection r l = maybe (Projection r l) id (proj r l)
|
||||
|
||||
proj r l =
|
||||
case r of
|
||||
RecordValue r -> case [v|RecordRow l' v<-r,l'==l] of
|
||||
[v] -> Just v
|
||||
_ -> Nothing
|
||||
_ -> Nothing
|
||||
|
||||
-- | Smart constructor for selections
|
||||
selection t v =
|
||||
-- Note: impossible cases can become possible after grammar transformation
|
||||
case t of
|
||||
TableValue tt r ->
|
||||
case nub [rv|TableRow _ rv<-keep] of
|
||||
[rv] -> rv
|
||||
_ -> Selection (TableValue tt r') v
|
||||
where
|
||||
-- Don't introduce wildcard patterns, true to the canonical format,
|
||||
-- annotate (or eliminate) rhs in impossible rows
|
||||
r' = map trunc r
|
||||
trunc r@(TableRow p e) = if mightMatchRow v r
|
||||
then r
|
||||
else TableRow p (impossible e)
|
||||
{-
|
||||
-- Creates smaller tables, but introduces wildcard patterns
|
||||
r' = if null discard
|
||||
then r
|
||||
else keep++[TableRow WildPattern impossible]
|
||||
-}
|
||||
(keep,discard) = partition (mightMatchRow v) r
|
||||
_ -> Selection t v
|
||||
|
||||
impossible = CommentedValue "impossible"
|
||||
|
||||
mightMatchRow v (TableRow p _) =
|
||||
case p of
|
||||
WildPattern -> True
|
||||
_ -> mightMatch v p
|
||||
|
||||
mightMatch v p =
|
||||
case v of
|
||||
ConcatValue _ _ -> False
|
||||
ParamConstant (Param c1 pvs) ->
|
||||
case p of
|
||||
ParamPattern (Param c2 pps) -> c1==c2 && length pvs==length pps &&
|
||||
and [mightMatch v p|(v,p)<-zip pvs pps]
|
||||
_ -> False
|
||||
RecordValue rv ->
|
||||
case p of
|
||||
RecordPattern rp ->
|
||||
and [maybe False (flip mightMatch p) (proj v l) | RecordRow l p<-rp]
|
||||
_ -> False
|
||||
_ -> True
|
||||
|
||||
patVars p =
|
||||
case p of
|
||||
PV x -> [x]
|
||||
PAs x p -> x:patVars p
|
||||
_ -> collectPattOp patVars p
|
||||
|
||||
convType = ppT
|
||||
where
|
||||
ppT t =
|
||||
case t of
|
||||
Table ti tv -> TableType (ppT ti) (ppT tv)
|
||||
RecType rt -> RecordType (convFields rt)
|
||||
-- App tf ta -> TAp (ppT tf) (ppT ta)
|
||||
-- FV [] -> tcon0 (identS "({-empty variant-})")
|
||||
Sort k -> convSort k
|
||||
-- EInt n -> tcon0 (identS ("({-"++show n++"-})")) -- type level numeric literal
|
||||
FV (t:ts) -> ppT t -- !!
|
||||
QC (m,n) -> ParamType (ParamTypeId ((gQId m n)))
|
||||
Q (m,n) -> ParamType (ParamTypeId ((gQId m n)))
|
||||
_ -> error $ "Missing case in convType for: "++show t
|
||||
|
||||
convFields = map convField . filter (not.isLockLabel.fst)
|
||||
convField (l,r) = RecordRow (lblId l) (ppT r)
|
||||
|
||||
convSort k = case showIdent k of
|
||||
"Float" -> FloatType
|
||||
"Int" -> IntType
|
||||
"Str" -> StrType
|
||||
_ -> error ("convSort "++show k)
|
||||
|
||||
toParamType t = case convType t of
|
||||
ParamType pt -> pt
|
||||
_ -> error ("toParamType "++show t)
|
||||
|
||||
toParamId t = case toParamType t of
|
||||
ParamTypeId p -> p
|
||||
|
||||
paramType gr q@(_,n) =
|
||||
case lookupOrigInfo gr q of
|
||||
Ok (m,ResParam (Just (L _ ps)) _)
|
||||
{- - | m/=cPredef && m/=moduleNameS "Prelude"-} ->
|
||||
((S.singleton (m,n),argTypes ps),
|
||||
[ParamDef name (map (param m) ps)]
|
||||
)
|
||||
where name = (gQId m n)
|
||||
Ok (m,ResOper _ (Just (L _ t)))
|
||||
| m==cPredef && n==cInts ->
|
||||
((S.empty,S.empty),[]) {-
|
||||
((S.singleton (m,n),S.empty),
|
||||
[Type (ConAp ((gQId m n)) [identS "n"]) (TId (identS "Int"))])-}
|
||||
| otherwise ->
|
||||
((S.singleton (m,n),paramTypes gr t),
|
||||
[ParamAliasDef ((gQId m n)) (convType t)])
|
||||
_ -> ((S.empty,S.empty),[])
|
||||
where
|
||||
param m (n,ctx) = Param ((gQId m n)) [toParamId t|(_,_,t)<-ctx]
|
||||
argTypes = S.unions . map argTypes1
|
||||
argTypes1 (n,ctx) = S.unions [paramTypes gr t|(_,_,t)<-ctx]
|
||||
|
||||
lblId = LabelId . render -- hmm
|
||||
modId (MN m) = ModId (showIdent m)
|
||||
|
||||
class FromIdent i where gId :: Ident -> i
|
||||
|
||||
instance FromIdent VarId where
|
||||
gId i = if isWildIdent i then Anonymous else VarId (showIdent i)
|
||||
|
||||
instance FromIdent C.FunId where gId = C.FunId . showIdent
|
||||
instance FromIdent CatId where gId = CatId . showIdent
|
||||
instance FromIdent ParamId where gId = ParamId . unqual
|
||||
instance FromIdent VarValueId where gId = VarValueId . unqual
|
||||
|
||||
class FromIdent i => QualIdent i where gQId :: ModuleName -> Ident -> i
|
||||
|
||||
instance QualIdent ParamId where gQId m n = ParamId (qual m n)
|
||||
instance QualIdent VarValueId where gQId m n = VarValueId (qual m n)
|
||||
|
||||
qual m n = Qual (modId m) (showIdent n)
|
||||
unqual n = Unqual (showIdent n)
|
||||
|
||||
convFlags gr mn =
|
||||
Flags [(n,convLit v) |
|
||||
(n,v)<-err (const []) (optionsPGF.mflags) (lookupModule gr mn)]
|
||||
where
|
||||
convLit l =
|
||||
case l of
|
||||
LStr s -> Str s
|
||||
LInt i -> C.Int i
|
||||
LFlt d -> Flt d
|
||||
@@ -1,4 +1,4 @@
|
||||
{-# LANGUAGE BangPatterns, FlexibleContexts #-}
|
||||
{-# LANGUAGE BangPatterns, FlexibleContexts, MagicHash #-}
|
||||
module GF.Compile.GrammarToPGF (mkCanon2pgf) where
|
||||
|
||||
--import GF.Compile.Export
|
||||
@@ -30,6 +30,10 @@ import qualified Data.Map as Map
|
||||
import qualified Data.IntMap as IntMap
|
||||
import Data.Array.IArray
|
||||
|
||||
import Data.Char
|
||||
import GHC.Prim
|
||||
import GHC.Base(getTag)
|
||||
|
||||
mkCanon2pgf :: Options -> SourceGrammar -> ModuleName -> IOE D.PGF
|
||||
mkCanon2pgf opts gr am = do
|
||||
(an,abs) <- mkAbstr am
|
||||
@@ -59,7 +63,9 @@ mkCanon2pgf opts gr am = do
|
||||
[(0,i2i f) | ((m,f),AbsFun (Just (L _ ty)) _ _ (Just True)) <- adefs, snd (GM.valCat ty) == cat]
|
||||
|
||||
mkConcr cm = do
|
||||
let cflags = err (const noOptions) mflags (lookupModule gr cm)
|
||||
let cflags = err (const noOptions) mflags (lookupModule gr cm)
|
||||
ciCmp | flag optCaseSensitive cflags = compare
|
||||
| otherwise = compareCaseInsensitve
|
||||
|
||||
(ex_seqs,cdefs) <- addMissingPMCFGs
|
||||
Map.empty
|
||||
@@ -68,15 +74,15 @@ mkCanon2pgf opts gr am = do
|
||||
|
||||
let flags = Map.fromList [(mkCId f,x) | (f,x) <- optionsPGF cflags]
|
||||
|
||||
seqs = (mkSetArray . Set.fromList . concat) $
|
||||
seqs = (mkArray . sortNubBy ciCmp . concat) $
|
||||
(Map.keys ex_seqs : [maybe [] elems (mseqs mi) | (m,mi) <- allExtends gr cm])
|
||||
|
||||
ex_seqs_arr = mkMapArray ex_seqs :: Array SeqId Sequence
|
||||
|
||||
!(!fid_cnt1,!cnccats) = genCncCats gr am cm cdefs
|
||||
!(!fid_cnt2,!productions,!lindefs,!linrefs,!cncfuns)
|
||||
= genCncFuns gr am cm ex_seqs_arr seqs cdefs fid_cnt1 cnccats
|
||||
|
||||
= genCncFuns gr am cm ex_seqs_arr ciCmp seqs cdefs fid_cnt1 cnccats
|
||||
|
||||
printnames = genPrintNames cdefs
|
||||
return (mi2i cm, D.Concr flags
|
||||
printnames
|
||||
@@ -186,6 +192,7 @@ genCncFuns :: Grammar
|
||||
-> ModuleName
|
||||
-> ModuleName
|
||||
-> Array SeqId Sequence
|
||||
-> (Sequence -> Sequence -> Ordering)
|
||||
-> Array SeqId Sequence
|
||||
-> [(QIdent, Info)]
|
||||
-> FId
|
||||
@@ -195,7 +202,7 @@ genCncFuns :: Grammar
|
||||
IntMap.IntMap [FunId],
|
||||
IntMap.IntMap [FunId],
|
||||
Array FunId D.CncFun)
|
||||
genCncFuns gr am cm ex_seqs seqs cdefs fid_cnt cnccats =
|
||||
genCncFuns gr am cm ex_seqs ciCmp seqs cdefs fid_cnt cnccats =
|
||||
let (fid_cnt1,funs_cnt1,funs1,lindefs,linrefs) = mkCncCats cdefs fid_cnt 0 [] IntMap.empty IntMap.empty
|
||||
(fid_cnt2,funs_cnt2,funs2,prods) = mkCncFuns cdefs fid_cnt1 funs_cnt1 funs1 lindefs Map.empty IntMap.empty
|
||||
in (fid_cnt2,prods,lindefs,linrefs,array (0,funs_cnt2-1) funs2)
|
||||
@@ -282,9 +289,9 @@ genCncFuns gr am cm ex_seqs seqs cdefs fid_cnt cnccats =
|
||||
in (offs+funid0,C.CncFun (i2i id) (amap (newIndex mseqs) lins0)):funs
|
||||
where
|
||||
newIndex mseqs i = binSearch (mseqs ! i) seqs (bounds seqs)
|
||||
|
||||
|
||||
binSearch v arr (i,j)
|
||||
| i <= j = case compare v (arr ! k) of
|
||||
| i <= j = case ciCmp v (arr ! k) of
|
||||
LT -> binSearch v arr (i,k-1)
|
||||
EQ -> k
|
||||
GT -> binSearch v arr (k+1,j)
|
||||
@@ -303,6 +310,121 @@ genPrintNames cdefs =
|
||||
flatten (Alts x _) = flatten x
|
||||
flatten (C x y) = flatten x +++ flatten y
|
||||
|
||||
--mkArray lst = listArray (0,length lst-1) lst
|
||||
mkArray lst = listArray (0,length lst-1) lst
|
||||
mkMapArray map = array (0,Map.size map-1) [(v,k) | (k,v) <- Map.toList map]
|
||||
mkSetArray set = listArray (0,Set.size set-1) [v | v <- Set.toList set]
|
||||
|
||||
-- The following is a version of Data.List.sortBy which together
|
||||
-- with the sorting also eliminates duplicate values
|
||||
sortNubBy cmp = mergeAll . sequences
|
||||
where
|
||||
sequences (a:b:xs) =
|
||||
case cmp a b of
|
||||
GT -> descending b [a] xs
|
||||
EQ -> sequences (b:xs)
|
||||
LT -> ascending b (a:) xs
|
||||
sequences xs = [xs]
|
||||
|
||||
descending a as [] = [a:as]
|
||||
descending a as (b:bs) =
|
||||
case cmp a b of
|
||||
GT -> descending b (a:as) bs
|
||||
EQ -> descending a as bs
|
||||
LT -> (a:as) : sequences (b:bs)
|
||||
|
||||
ascending a as [] = let !x = as [a]
|
||||
in [x]
|
||||
ascending a as (b:bs) =
|
||||
case cmp a b of
|
||||
GT -> let !x = as [a]
|
||||
in x : sequences (b:bs)
|
||||
EQ -> ascending a as bs
|
||||
LT -> ascending b (\ys -> as (a:ys)) bs
|
||||
|
||||
mergeAll [x] = x
|
||||
mergeAll xs = mergeAll (mergePairs xs)
|
||||
|
||||
mergePairs (a:b:xs) = let !x = merge a b
|
||||
in x : mergePairs xs
|
||||
mergePairs xs = xs
|
||||
|
||||
merge as@(a:as') bs@(b:bs') =
|
||||
case cmp a b of
|
||||
GT -> b:merge as bs'
|
||||
EQ -> a:merge as' bs'
|
||||
LT -> a:merge as' bs
|
||||
merge [] bs = bs
|
||||
merge as [] = as
|
||||
|
||||
-- The following function does case-insensitive comparison of sequences.
|
||||
-- This is used to allow case-insensitive parsing, while
|
||||
-- the linearizer still has access to the original cases.
|
||||
compareCaseInsensitve s1 s2 =
|
||||
compareSeq (elems s1) (elems s2)
|
||||
where
|
||||
compareSeq [] [] = EQ
|
||||
compareSeq [] _ = LT
|
||||
compareSeq _ [] = GT
|
||||
compareSeq (x:xs) (y:ys) =
|
||||
case compareSym x y of
|
||||
EQ -> compareSeq xs ys
|
||||
x -> x
|
||||
|
||||
compareSym s1 s2 =
|
||||
case s1 of
|
||||
D.SymCat d1 r1
|
||||
-> case s2 of
|
||||
D.SymCat d2 r2
|
||||
-> case compare d1 d2 of
|
||||
EQ -> r1 `compare` r2
|
||||
x -> x
|
||||
_ -> LT
|
||||
D.SymLit d1 r1
|
||||
-> case s2 of
|
||||
D.SymCat {} -> GT
|
||||
D.SymLit d2 r2
|
||||
-> case compare d1 d2 of
|
||||
EQ -> r1 `compare` r2
|
||||
x -> x
|
||||
_ -> LT
|
||||
D.SymVar d1 r1
|
||||
-> if tagToEnum# (getTag s2 ># 2#)
|
||||
then LT
|
||||
else case s2 of
|
||||
D.SymVar d2 r2
|
||||
-> case compare d1 d2 of
|
||||
EQ -> r1 `compare` r2
|
||||
x -> x
|
||||
_ -> GT
|
||||
D.SymKS t1
|
||||
-> if tagToEnum# (getTag s2 ># 3#)
|
||||
then LT
|
||||
else case s2 of
|
||||
D.SymKS t2 -> t1 `compareToken` t2
|
||||
_ -> GT
|
||||
D.SymKP a1 b1
|
||||
-> if tagToEnum# (getTag s2 ># 4#)
|
||||
then LT
|
||||
else case s2 of
|
||||
D.SymKP a2 b2
|
||||
-> case compare a1 a2 of
|
||||
EQ -> b1 `compare` b2
|
||||
x -> x
|
||||
_ -> GT
|
||||
_ -> let t1 = getTag s1
|
||||
t2 = getTag s2
|
||||
in if tagToEnum# (t1 <# t2)
|
||||
then LT
|
||||
else if tagToEnum# (t1 ==# t2)
|
||||
then EQ
|
||||
else GT
|
||||
|
||||
compareToken [] [] = EQ
|
||||
compareToken [] _ = LT
|
||||
compareToken _ [] = GT
|
||||
compareToken (x:xs) (y:ys)
|
||||
| x == y = compareToken xs ys
|
||||
| otherwise = case compare (toLower x) (toLower y) of
|
||||
EQ -> case compareToken xs ys of
|
||||
EQ -> compare x y
|
||||
x -> x
|
||||
x -> x
|
||||
|
||||
156
src/compiler/GF/Compile/PGFtoJSON.hs
Normal file
156
src/compiler/GF/Compile/PGFtoJSON.hs
Normal file
@@ -0,0 +1,156 @@
|
||||
module GF.Compile.PGFtoJSON (pgf2json) where
|
||||
|
||||
import PGF (showCId)
|
||||
import qualified PGF.Internal as M
|
||||
import PGF.Internal (
|
||||
Abstr,
|
||||
CId,
|
||||
CncCat(..),
|
||||
CncFun(..),
|
||||
Concr,
|
||||
DotPos,
|
||||
Equation(..),
|
||||
Literal(..),
|
||||
PArg(..),
|
||||
PGF,
|
||||
Production(..),
|
||||
Symbol(..),
|
||||
Type,
|
||||
absname,
|
||||
abstract,
|
||||
cflags,
|
||||
cnccats,
|
||||
cncfuns,
|
||||
concretes,
|
||||
funs,
|
||||
productions,
|
||||
sequences,
|
||||
totalCats
|
||||
)
|
||||
|
||||
import qualified Text.JSON as JSON
|
||||
import Text.JSON (JSValue(..))
|
||||
|
||||
import qualified Data.Array.IArray as Array
|
||||
import Data.Map (Map)
|
||||
import qualified Data.Set as Set
|
||||
import qualified Data.Map as Map
|
||||
import qualified Data.IntMap as IntMap
|
||||
|
||||
pgf2json :: PGF -> String
|
||||
pgf2json pgf =
|
||||
JSON.encode $ JSON.makeObj
|
||||
[ ("abstract", json_abstract)
|
||||
, ("concretes", json_concretes)
|
||||
]
|
||||
where
|
||||
n = showCId $ absname pgf
|
||||
as = abstract pgf
|
||||
cs = Map.assocs (concretes pgf)
|
||||
start = showCId $ M.lookStartCat pgf
|
||||
json_abstract = abstract2json n start as
|
||||
json_concretes = JSON.makeObj $ map concrete2json cs
|
||||
|
||||
abstract2json :: String -> String -> Abstr -> JSValue
|
||||
abstract2json name start ds =
|
||||
JSON.makeObj
|
||||
[ ("name", mkJSStr name)
|
||||
, ("startcat", mkJSStr start)
|
||||
, ("funs", JSON.makeObj $ map absdef2json (Map.assocs (funs ds)))
|
||||
]
|
||||
|
||||
absdef2json :: (CId,(Type,Int,Maybe ([Equation],[[M.Instr]]),Double)) -> (String,JSValue)
|
||||
absdef2json (f,(typ,_,_,_)) = (showCId f,sig)
|
||||
where
|
||||
(args,cat) = M.catSkeleton typ
|
||||
sig = JSON.makeObj
|
||||
[ ("args", JSArray $ map (mkJSStr.showCId) args)
|
||||
, ("cat", mkJSStr $ showCId cat)
|
||||
]
|
||||
|
||||
lit2json :: Literal -> JSValue
|
||||
lit2json (LStr s) = mkJSStr s
|
||||
lit2json (LInt n) = mkJSInt n
|
||||
lit2json (LFlt d) = JSRational True (toRational d)
|
||||
|
||||
concrete2json :: (CId,Concr) -> (String,JSValue)
|
||||
concrete2json (c,cnc) = (showCId c,obj)
|
||||
where
|
||||
obj = JSON.makeObj
|
||||
[ ("flags", JSON.makeObj [ (showCId k, lit2json v) | (k,v) <- Map.toList (cflags cnc) ])
|
||||
, ("productions", JSON.makeObj [ (show cat, JSArray (map frule2json (Set.toList set))) | (cat,set) <- IntMap.toList (productions cnc)])
|
||||
, ("functions", JSArray (map ffun2json (Array.elems (cncfuns cnc))))
|
||||
, ("sequences", JSArray (map seq2json (Array.elems (sequences cnc))))
|
||||
, ("categories", JSON.makeObj $ map cats2json (Map.assocs (cnccats cnc)))
|
||||
, ("totalfids", mkJSInt (totalCats cnc))
|
||||
]
|
||||
|
||||
cats2json :: (CId, CncCat) -> (String,JSValue)
|
||||
cats2json (c,CncCat start end _) = (showCId c, ixs)
|
||||
where
|
||||
ixs = JSON.makeObj
|
||||
[ ("start", mkJSInt start)
|
||||
, ("end", mkJSInt end)
|
||||
]
|
||||
|
||||
frule2json :: Production -> JSValue
|
||||
frule2json (PApply fid args) =
|
||||
JSON.makeObj
|
||||
[ ("type", mkJSStr "Apply")
|
||||
, ("fid", mkJSInt fid)
|
||||
, ("args", JSArray (map farg2json args))
|
||||
]
|
||||
frule2json (PCoerce arg) =
|
||||
JSON.makeObj
|
||||
[ ("type", mkJSStr "Coerce")
|
||||
, ("arg", mkJSInt arg)
|
||||
]
|
||||
|
||||
farg2json :: PArg -> JSValue
|
||||
farg2json (PArg hypos fid) =
|
||||
JSON.makeObj
|
||||
[ ("type", mkJSStr "PArg")
|
||||
, ("hypos", JSArray $ map (mkJSInt . snd) hypos)
|
||||
, ("fid", mkJSInt fid)
|
||||
]
|
||||
|
||||
ffun2json :: CncFun -> JSValue
|
||||
ffun2json (CncFun f lins) =
|
||||
JSON.makeObj
|
||||
[ ("name", mkJSStr $ showCId f)
|
||||
, ("lins", JSArray (map mkJSInt (Array.elems lins)))
|
||||
]
|
||||
|
||||
seq2json :: Array.Array DotPos Symbol -> JSValue
|
||||
seq2json seq = JSArray [sym2json s | s <- Array.elems seq]
|
||||
|
||||
sym2json :: Symbol -> JSValue
|
||||
sym2json (SymCat n l) = new "SymCat" [mkJSInt n, mkJSInt l]
|
||||
sym2json (SymLit n l) = new "SymLit" [mkJSInt n, mkJSInt l]
|
||||
sym2json (SymVar n l) = new "SymVar" [mkJSInt n, mkJSInt l]
|
||||
sym2json (SymKS t) = new "SymKS" [mkJSStr t]
|
||||
sym2json (SymKP ts alts) = new "SymKP" [JSArray (map sym2json ts), JSArray (map alt2json alts)]
|
||||
sym2json SymBIND = new "SymKS" [mkJSStr "&+"]
|
||||
sym2json SymSOFT_BIND = new "SymKS" [mkJSStr "&+"]
|
||||
sym2json SymSOFT_SPACE = new "SymKS" [mkJSStr "&+"]
|
||||
sym2json SymCAPIT = new "SymKS" [mkJSStr "&|"]
|
||||
sym2json SymALL_CAPIT = new "SymKS" [mkJSStr "&|"]
|
||||
sym2json SymNE = new "SymNE" []
|
||||
|
||||
alt2json :: ([Symbol],[String]) -> JSValue
|
||||
alt2json (ps,ts) = new "Alt" [JSArray (map sym2json ps), JSArray (map mkJSStr ts)]
|
||||
|
||||
new :: String -> [JSValue] -> JSValue
|
||||
new f xs =
|
||||
JSON.makeObj
|
||||
[ ("type", mkJSStr f)
|
||||
, ("args", JSArray xs)
|
||||
]
|
||||
|
||||
-- | Make JSON value from string
|
||||
mkJSStr :: String -> JSValue
|
||||
mkJSStr = JSString . JSON.toJSString
|
||||
|
||||
-- | Make JSON value from integer
|
||||
mkJSInt :: Integral a => a -> JSValue
|
||||
mkJSInt = JSRational False . toRational
|
||||
@@ -360,12 +360,13 @@ getOverload gr g mt ot = case appForm ot of
|
||||
nest 2 (showTypes pre)
|
||||
return (mkApp fun tts, val)
|
||||
([],[]) -> do
|
||||
checkError $ "no overload instance of" <+> ppTerm Unqualified 0 f $$
|
||||
"for" $$
|
||||
checkError $ "no overload instance of" <+> ppTerm Qualified 0 f $$
|
||||
maybe empty (\x -> "with value type" <+> ppType x) mt $$
|
||||
"for argument list" $$
|
||||
nest 2 stysError $$
|
||||
"among" $$
|
||||
nest 2 (vcat stypsError) $$
|
||||
maybe empty (\x -> "with value type" <+> ppType x) mt
|
||||
"among alternatives" $$
|
||||
nest 2 (vcat stypsError)
|
||||
|
||||
|
||||
(vfs1,vfs2) -> case (noProds vfs1,noProds vfs2) of
|
||||
([(val,fun)],_) -> do
|
||||
|
||||
232
src/compiler/GF/Compile/pgf.schema.json
Normal file
232
src/compiler/GF/Compile/pgf.schema.json
Normal file
@@ -0,0 +1,232 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "http://grammaticalframework.org/pgf.schema.json",
|
||||
"type": "object",
|
||||
"title": "PGF JSON Schema",
|
||||
"required": [
|
||||
"abstract",
|
||||
"concretes"
|
||||
],
|
||||
"properties": {
|
||||
"abstract": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"startcat",
|
||||
"funs"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"startcat": {
|
||||
"type": "string"
|
||||
},
|
||||
"funs": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"args",
|
||||
"cat"
|
||||
],
|
||||
"properties": {
|
||||
"args": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"cat": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"concretes": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"required": [
|
||||
"flags",
|
||||
"productions",
|
||||
"functions",
|
||||
"sequences",
|
||||
"categories",
|
||||
"totalfids"
|
||||
],
|
||||
"properties": {
|
||||
"flags": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": ["string", "number"]
|
||||
}
|
||||
},
|
||||
"productions": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/apply"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/coerce"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"functions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"title": "CncFun",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"lins": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sequences": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/sym"
|
||||
}
|
||||
}
|
||||
},
|
||||
"categories": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"title": "CncCat",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"start",
|
||||
"end"
|
||||
],
|
||||
"properties": {
|
||||
"start": {
|
||||
"type": "integer"
|
||||
},
|
||||
"end": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"totalfids": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"apply": {
|
||||
"required": [
|
||||
"type",
|
||||
"fid",
|
||||
"args"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["Apply"]
|
||||
},
|
||||
"fid": {
|
||||
"type": "integer"
|
||||
},
|
||||
"args": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/parg"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"coerce": {
|
||||
"required": [
|
||||
"type",
|
||||
"arg"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["Coerce"]
|
||||
},
|
||||
"arg": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parg": {
|
||||
"required": [
|
||||
"type",
|
||||
"hypos",
|
||||
"fid"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["PArg"]
|
||||
},
|
||||
"hypos": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"fid": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sym": {
|
||||
"title": "Sym",
|
||||
"required": [
|
||||
"type",
|
||||
"args"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"SymCat",
|
||||
"SymLit",
|
||||
"SymVar",
|
||||
"SymKS",
|
||||
"SymKP",
|
||||
"SymNE"
|
||||
]
|
||||
},
|
||||
"args": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "integer"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/sym"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import GF.Compile as S(batchCompile,link,srcAbsName)
|
||||
import GF.CompileInParallel as P(parallelBatchCompile)
|
||||
import GF.Compile.Export
|
||||
import GF.Compile.ConcreteToHaskell(concretes2haskell)
|
||||
import GF.Compile.GrammarToCanonical--(concretes2canonical)
|
||||
import GF.Compile.CFGtoPGF
|
||||
import GF.Compile.GetGrammar
|
||||
import GF.Grammar.BNFC
|
||||
@@ -17,12 +18,13 @@ import GF.Infra.UseIO
|
||||
import GF.Infra.Option
|
||||
import GF.Data.ErrM
|
||||
import GF.System.Directory
|
||||
import GF.Text.Pretty(render)
|
||||
import GF.Text.Pretty(render,render80)
|
||||
|
||||
import Data.Maybe
|
||||
import qualified Data.Map as Map
|
||||
import qualified Data.Set as Set
|
||||
import qualified Data.ByteString.Lazy as BSL
|
||||
import GF.Grammar.CanonicalJSON (encodeJSON)
|
||||
import System.FilePath
|
||||
import Control.Monad(when,unless,forM_)
|
||||
|
||||
@@ -47,7 +49,7 @@ mainGFC opts fs = do
|
||||
compileSourceFiles :: Options -> [FilePath] -> IOE ()
|
||||
compileSourceFiles opts fs =
|
||||
do output <- batchCompile opts fs
|
||||
cncs2haskell output
|
||||
exportCanonical output
|
||||
unless (flag optStopAfterPhase opts == Compile) $
|
||||
linkGrammars opts output
|
||||
where
|
||||
@@ -55,15 +57,35 @@ compileSourceFiles opts fs =
|
||||
batchCompile' opts fs = do (t,cnc_gr) <- S.batchCompile opts fs
|
||||
return (t,[cnc_gr])
|
||||
|
||||
cncs2haskell output =
|
||||
when (FmtHaskell `elem` flag optOutputFormats opts &&
|
||||
haskellOption opts HaskellConcrete) $
|
||||
mapM_ cnc2haskell (snd output)
|
||||
exportCanonical (_time, canonical) =
|
||||
do when (FmtHaskell `elem` ofmts && haskellOption opts HaskellConcrete) $
|
||||
mapM_ cnc2haskell canonical
|
||||
when (FmtCanonicalGF `elem` ofmts) $
|
||||
do createDirectoryIfMissing False "canonical"
|
||||
mapM_ abs2canonical canonical
|
||||
mapM_ cnc2canonical canonical
|
||||
when (FmtCanonicalJson `elem` ofmts) $ mapM_ grammar2json canonical
|
||||
where
|
||||
ofmts = flag optOutputFormats opts
|
||||
|
||||
cnc2haskell (cnc,gr) =
|
||||
mapM_ writeHs $ concretes2haskell opts (srcAbsName gr cnc) gr
|
||||
do mapM_ writeExport $ concretes2haskell opts (srcAbsName gr cnc) gr
|
||||
|
||||
writeHs (path,s) = writing opts path $ writeUTF8File path s
|
||||
abs2canonical (cnc,gr) =
|
||||
writeExport ("canonical/"++render absname++".gf",render80 canAbs)
|
||||
where
|
||||
absname = srcAbsName gr cnc
|
||||
canAbs = abstract2canonical absname gr
|
||||
|
||||
cnc2canonical (cnc,gr) =
|
||||
mapM_ (writeExport.fmap render80) $
|
||||
concretes2canonical opts (srcAbsName gr cnc) gr
|
||||
|
||||
grammar2json (cnc,gr) = encodeJSON (render absname ++ ".json") gr_canon
|
||||
where absname = srcAbsName gr cnc
|
||||
gr_canon = grammar2canonical opts absname gr
|
||||
|
||||
writeExport (path,s) = writing opts path $ writeUTF8File path s
|
||||
|
||||
|
||||
-- | Create a @.pgf@ file (and possibly files in other formats, if specified
|
||||
@@ -80,7 +102,9 @@ linkGrammars opts (t_src,~cnc_grs@(~(cnc,gr):_)) =
|
||||
if t_pgf >= Just t_src
|
||||
then putIfVerb opts $ pgfFile ++ " is up-to-date."
|
||||
else do pgfs <- mapM (link opts) cnc_grs
|
||||
let pgf = foldl1 unionPGF pgfs
|
||||
let pgf0 = foldl1 unionPGF pgfs
|
||||
probs <- maybe (return . defaultProbabilities) readProbabilitiesFromFile (flag optProbsFile opts) pgf0
|
||||
let pgf = setProbabilities probs pgf0
|
||||
writePGF opts pgf
|
||||
writeOutputs opts pgf
|
||||
|
||||
@@ -115,7 +139,9 @@ unionPGFFiles opts fs =
|
||||
doIt =
|
||||
do pgfs <- mapM readPGFVerbose fs
|
||||
let pgf0 = foldl1 unionPGF pgfs
|
||||
pgf = if flag optOptimizePGF opts then optimizePGF pgf0 else pgf0
|
||||
pgf1 = if flag optOptimizePGF opts then optimizePGF pgf0 else pgf0
|
||||
probs <- liftIO (maybe (return . defaultProbabilities) readProbabilitiesFromFile (flag optProbsFile opts) pgf1)
|
||||
let pgf = setProbabilities probs pgf1
|
||||
pgfFile = outputPath opts (grammarName opts pgf <.> "pgf")
|
||||
if pgfFile `elem` fs
|
||||
then putStrLnE $ "Refusing to overwrite " ++ pgfFile
|
||||
|
||||
313
src/compiler/GF/Grammar/Canonical.hs
Normal file
313
src/compiler/GF/Grammar/Canonical.hs
Normal file
@@ -0,0 +1,313 @@
|
||||
-- |
|
||||
-- Module : GF.Grammar.Canonical
|
||||
-- Stability : provisional
|
||||
--
|
||||
-- Abstract syntax for canonical GF grammars, i.e. what's left after
|
||||
-- high-level constructions such as functors and opers have been eliminated
|
||||
-- by partial evaluation. This is intended as a common intermediate
|
||||
-- representation to simplify export to other formats.
|
||||
|
||||
{-# LANGUAGE DeriveTraversable #-}
|
||||
module GF.Grammar.Canonical where
|
||||
import Prelude hiding ((<>))
|
||||
import GF.Text.Pretty
|
||||
|
||||
-- | A Complete grammar
|
||||
data Grammar = Grammar Abstract [Concrete] deriving Show
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- ** Abstract Syntax
|
||||
|
||||
-- | Abstract Syntax
|
||||
data Abstract = Abstract ModId Flags [CatDef] [FunDef] deriving Show
|
||||
abstrName (Abstract mn _ _ _) = mn
|
||||
|
||||
data CatDef = CatDef CatId [CatId] deriving Show
|
||||
data FunDef = FunDef FunId Type deriving Show
|
||||
data Type = Type [TypeBinding] TypeApp deriving Show
|
||||
data TypeApp = TypeApp CatId [Type] deriving Show
|
||||
|
||||
data TypeBinding = TypeBinding VarId Type deriving Show
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- ** Concreate syntax
|
||||
|
||||
-- | Concrete Syntax
|
||||
data Concrete = Concrete ModId ModId Flags [ParamDef] [LincatDef] [LinDef]
|
||||
deriving Show
|
||||
concName (Concrete cnc _ _ _ _ _) = cnc
|
||||
|
||||
data ParamDef = ParamDef ParamId [ParamValueDef]
|
||||
| ParamAliasDef ParamId LinType
|
||||
deriving Show
|
||||
data LincatDef = LincatDef CatId LinType deriving Show
|
||||
data LinDef = LinDef FunId [VarId] LinValue deriving Show
|
||||
|
||||
-- | Linearization type, RHS of @lincat@
|
||||
data LinType = FloatType
|
||||
| IntType
|
||||
| ParamType ParamType
|
||||
| RecordType [RecordRowType]
|
||||
| StrType
|
||||
| TableType LinType LinType
|
||||
| TupleType [LinType]
|
||||
deriving (Eq,Ord,Show)
|
||||
|
||||
newtype ParamType = ParamTypeId ParamId deriving (Eq,Ord,Show)
|
||||
|
||||
-- | Linearization value, RHS of @lin@
|
||||
data LinValue = ConcatValue LinValue LinValue
|
||||
| LiteralValue LinLiteral
|
||||
| ErrorValue String
|
||||
| ParamConstant ParamValue
|
||||
| PredefValue PredefId
|
||||
| RecordValue [RecordRowValue]
|
||||
| TableValue LinType [TableRowValue]
|
||||
--- | VTableValue LinType [LinValue]
|
||||
| TupleValue [LinValue]
|
||||
| VariantValue [LinValue]
|
||||
| VarValue VarValueId
|
||||
| PreValue [([String], LinValue)] LinValue
|
||||
| Projection LinValue LabelId
|
||||
| Selection LinValue LinValue
|
||||
| CommentedValue String LinValue
|
||||
deriving (Eq,Ord,Show)
|
||||
|
||||
data LinLiteral = FloatConstant Float
|
||||
| IntConstant Int
|
||||
| StrConstant String
|
||||
deriving (Eq,Ord,Show)
|
||||
|
||||
data LinPattern = ParamPattern ParamPattern
|
||||
| RecordPattern [RecordRow LinPattern]
|
||||
| TuplePattern [LinPattern]
|
||||
| WildPattern
|
||||
deriving (Eq,Ord,Show)
|
||||
|
||||
type ParamValue = Param LinValue
|
||||
type ParamPattern = Param LinPattern
|
||||
type ParamValueDef = Param ParamId
|
||||
|
||||
data Param arg = Param ParamId [arg]
|
||||
deriving (Eq,Ord,Show,Functor,Foldable,Traversable)
|
||||
|
||||
type RecordRowType = RecordRow LinType
|
||||
type RecordRowValue = RecordRow LinValue
|
||||
type TableRowValue = TableRow LinValue
|
||||
|
||||
data RecordRow rhs = RecordRow LabelId rhs
|
||||
deriving (Eq,Ord,Show,Functor,Foldable,Traversable)
|
||||
data TableRow rhs = TableRow LinPattern rhs
|
||||
deriving (Eq,Ord,Show,Functor,Foldable,Traversable)
|
||||
|
||||
-- *** Identifiers in Concrete Syntax
|
||||
|
||||
newtype PredefId = PredefId Id deriving (Eq,Ord,Show)
|
||||
newtype LabelId = LabelId Id deriving (Eq,Ord,Show)
|
||||
data VarValueId = VarValueId QualId deriving (Eq,Ord,Show)
|
||||
|
||||
-- | Name of param type or param value
|
||||
newtype ParamId = ParamId QualId deriving (Eq,Ord,Show)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- ** Used in both Abstract and Concrete Syntax
|
||||
|
||||
newtype ModId = ModId Id deriving (Eq,Ord,Show)
|
||||
|
||||
newtype CatId = CatId Id deriving (Eq,Ord,Show)
|
||||
newtype FunId = FunId Id deriving (Eq,Show)
|
||||
|
||||
data VarId = Anonymous | VarId Id deriving Show
|
||||
|
||||
newtype Flags = Flags [(FlagName,FlagValue)] deriving Show
|
||||
type FlagName = Id
|
||||
data FlagValue = Str String | Int Int | Flt Double deriving Show
|
||||
|
||||
|
||||
-- *** Identifiers
|
||||
|
||||
type Id = String
|
||||
data QualId = Qual ModId Id | Unqual Id deriving (Eq,Ord,Show)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- ** Pretty printing
|
||||
|
||||
instance Pretty Grammar where
|
||||
pp (Grammar abs cncs) = abs $+$ vcat cncs
|
||||
|
||||
instance Pretty Abstract where
|
||||
pp (Abstract m flags cats funs) =
|
||||
"abstract" <+> m <+> "=" <+> "{" $$
|
||||
flags $$
|
||||
"cat" <+> fsep cats $$
|
||||
"fun" <+> vcat funs $$
|
||||
"}"
|
||||
|
||||
instance Pretty CatDef where
|
||||
pp (CatDef c cs) = hsep (c:cs)<>";"
|
||||
|
||||
instance Pretty FunDef where
|
||||
pp (FunDef f ty) = f <+> ":" <+> ty <>";"
|
||||
|
||||
instance Pretty Type where
|
||||
pp (Type bs ty) = sep (punctuate " ->" (map pp bs ++ [pp ty]))
|
||||
|
||||
instance PPA Type where
|
||||
ppA (Type [] (TypeApp c [])) = pp c
|
||||
ppA t = parens t
|
||||
|
||||
instance Pretty TypeBinding where
|
||||
pp (TypeBinding Anonymous (Type [] tapp)) = pp tapp
|
||||
pp (TypeBinding Anonymous ty) = parens ty
|
||||
pp (TypeBinding (VarId x) ty) = parens (x<+>":"<+>ty)
|
||||
|
||||
instance Pretty TypeApp where
|
||||
pp (TypeApp c targs) = c<+>hsep (map ppA targs)
|
||||
|
||||
instance Pretty VarId where
|
||||
pp Anonymous = pp "_"
|
||||
pp (VarId x) = pp x
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
instance Pretty Concrete where
|
||||
pp (Concrete cncid absid flags params lincats lins) =
|
||||
"concrete" <+> cncid <+> "of" <+> absid <+> "=" <+> "{" $$
|
||||
vcat params $$
|
||||
section "lincat" lincats $$
|
||||
section "lin" lins $$
|
||||
"}"
|
||||
where
|
||||
section name [] = empty
|
||||
section name ds = name <+> vcat (map (<> ";") ds)
|
||||
|
||||
instance Pretty ParamDef where
|
||||
pp (ParamDef p pvs) = hang ("param"<+> p <+> "=") 4 (punctuate " |" pvs)<>";"
|
||||
pp (ParamAliasDef p t) = hang ("oper"<+> p <+> "=") 4 t<>";"
|
||||
|
||||
instance PPA arg => Pretty (Param arg) where
|
||||
pp (Param p ps) = pp p<+>sep (map ppA ps)
|
||||
|
||||
instance PPA arg => PPA (Param arg) where
|
||||
ppA (Param p []) = pp p
|
||||
ppA pv = parens pv
|
||||
|
||||
instance Pretty LincatDef where
|
||||
pp (LincatDef c lt) = hang (c <+> "=") 4 lt
|
||||
|
||||
instance Pretty LinType where
|
||||
pp lt = case lt of
|
||||
FloatType -> pp "Float"
|
||||
IntType -> pp "Int"
|
||||
ParamType pt -> pp pt
|
||||
RecordType rs -> block rs
|
||||
StrType -> pp "Str"
|
||||
TableType pt lt -> sep [pt <+> "=>",pp lt]
|
||||
TupleType lts -> "<"<>punctuate "," lts<>">"
|
||||
|
||||
instance RhsSeparator LinType where rhsSep _ = pp ":"
|
||||
|
||||
instance Pretty ParamType where
|
||||
pp (ParamTypeId p) = pp p
|
||||
|
||||
instance Pretty LinDef where
|
||||
pp (LinDef f xs lv) = hang (f<+>hsep xs<+>"=") 4 lv
|
||||
|
||||
instance Pretty LinValue where
|
||||
pp lv = case lv of
|
||||
ConcatValue v1 v2 -> sep [v1 <+> "++",pp v2]
|
||||
ErrorValue s -> "Predef.error"<+>doubleQuotes s
|
||||
ParamConstant pv -> pp pv
|
||||
Projection lv l -> ppA lv<>"."<>l
|
||||
Selection tv pv -> ppA tv<>"!"<>ppA pv
|
||||
VariantValue vs -> "variants"<+>block vs
|
||||
CommentedValue s v -> "{-" <+> s <+> "-}" $$ v
|
||||
_ -> ppA lv
|
||||
|
||||
instance PPA LinValue where
|
||||
ppA lv = case lv of
|
||||
LiteralValue l -> ppA l
|
||||
ParamConstant pv -> ppA pv
|
||||
PredefValue p -> ppA p
|
||||
RecordValue [] -> pp "<>"
|
||||
RecordValue rvs -> block rvs
|
||||
PreValue alts def ->
|
||||
"pre"<+>block (map alt alts++["_"<+>"=>"<+>def])
|
||||
where
|
||||
alt (ss,lv) = hang (hcat (punctuate "|" (map doubleQuotes ss)))
|
||||
2 ("=>"<+>lv)
|
||||
TableValue _ tvs -> "table"<+>block tvs
|
||||
-- VTableValue t ts -> "table"<+>t<+>brackets (semiSep ts)
|
||||
TupleValue lvs -> "<"<>punctuate "," lvs<>">"
|
||||
VarValue v -> pp v
|
||||
_ -> parens lv
|
||||
|
||||
instance Pretty LinLiteral where pp = ppA
|
||||
|
||||
instance PPA LinLiteral where
|
||||
ppA l = case l of
|
||||
FloatConstant f -> pp f
|
||||
IntConstant n -> pp n
|
||||
StrConstant s -> doubleQuotes s -- hmm
|
||||
|
||||
instance RhsSeparator LinValue where rhsSep _ = pp "="
|
||||
|
||||
instance Pretty LinPattern where
|
||||
pp p =
|
||||
case p of
|
||||
ParamPattern pv -> pp pv
|
||||
_ -> ppA p
|
||||
|
||||
instance PPA LinPattern where
|
||||
ppA p =
|
||||
case p of
|
||||
ParamPattern pv -> ppA pv
|
||||
RecordPattern r -> block r
|
||||
TuplePattern ps -> "<"<>punctuate "," ps<>">"
|
||||
WildPattern -> pp "_"
|
||||
_ -> parens p
|
||||
|
||||
instance RhsSeparator LinPattern where rhsSep _ = pp "="
|
||||
|
||||
instance RhsSeparator rhs => Pretty (RecordRow rhs) where
|
||||
pp (RecordRow l v) = hang (l<+>rhsSep v) 2 v
|
||||
|
||||
instance Pretty rhs => Pretty (TableRow rhs) where
|
||||
pp (TableRow l v) = hang (l<+>"=>") 2 v
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
instance Pretty ModId where pp (ModId s) = pp s
|
||||
instance Pretty CatId where pp (CatId s) = pp s
|
||||
instance Pretty FunId where pp (FunId s) = pp s
|
||||
instance Pretty LabelId where pp (LabelId s) = pp s
|
||||
instance Pretty PredefId where pp = ppA
|
||||
instance PPA PredefId where ppA (PredefId s) = "Predef."<>s
|
||||
instance Pretty ParamId where pp = ppA
|
||||
instance PPA ParamId where ppA (ParamId s) = pp s
|
||||
instance Pretty VarValueId where pp (VarValueId s) = pp s
|
||||
|
||||
instance Pretty QualId where pp = ppA
|
||||
|
||||
instance PPA QualId where
|
||||
ppA (Qual m n) = m<>"_"<>n -- hmm
|
||||
ppA (Unqual n) = pp n
|
||||
|
||||
instance Pretty Flags where
|
||||
pp (Flags []) = empty
|
||||
pp (Flags flags) = "flags" <+> vcat (map ppFlag flags)
|
||||
where
|
||||
ppFlag (name,value) = name <+> "=" <+> value <>";"
|
||||
|
||||
instance Pretty FlagValue where
|
||||
pp (Str s) = pp s
|
||||
pp (Int i) = pp i
|
||||
pp (Flt d) = pp d
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- | Pretty print atomically (i.e. wrap it in parentheses if necessary)
|
||||
class Pretty a => PPA a where ppA :: a -> Doc
|
||||
|
||||
class Pretty rhs => RhsSeparator rhs where rhsSep :: rhs -> Doc
|
||||
|
||||
semiSep xs = punctuate ";" xs
|
||||
block xs = braces (semiSep xs)
|
||||
289
src/compiler/GF/Grammar/CanonicalJSON.hs
Normal file
289
src/compiler/GF/Grammar/CanonicalJSON.hs
Normal file
@@ -0,0 +1,289 @@
|
||||
module GF.Grammar.CanonicalJSON (
|
||||
encodeJSON
|
||||
) where
|
||||
|
||||
import Text.JSON
|
||||
import Control.Applicative ((<|>))
|
||||
import Data.Ratio (denominator, numerator)
|
||||
import GF.Grammar.Canonical
|
||||
|
||||
|
||||
encodeJSON :: FilePath -> Grammar -> IO ()
|
||||
encodeJSON fpath g = writeFile fpath (encode g)
|
||||
|
||||
|
||||
-- in general we encode grammars using JSON objects/records,
|
||||
-- except for newtypes/coercions/direct values
|
||||
|
||||
-- the top-level definitions use normal record labels,
|
||||
-- but recursive types/values/ids use labels staring with a "."
|
||||
|
||||
instance JSON Grammar where
|
||||
showJSON (Grammar abs cncs) = makeObj [("abstract", showJSON abs), ("concretes", showJSON cncs)]
|
||||
|
||||
readJSON o = Grammar <$> o!"abstract" <*> o!"concretes"
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- ** Abstract Syntax
|
||||
|
||||
instance JSON Abstract where
|
||||
showJSON (Abstract absid flags cats funs)
|
||||
= makeObj [("abs", showJSON absid),
|
||||
("flags", showJSON flags),
|
||||
("cats", showJSON cats),
|
||||
("funs", showJSON funs)]
|
||||
|
||||
readJSON o = Abstract
|
||||
<$> o!"abs"
|
||||
<*>(o!"flags" <|> return (Flags []))
|
||||
<*> o!"cats"
|
||||
<*> o!"funs"
|
||||
|
||||
instance JSON CatDef where
|
||||
-- non-dependent categories are encoded as simple strings:
|
||||
showJSON (CatDef c []) = showJSON c
|
||||
showJSON (CatDef c cs) = makeObj [("cat", showJSON c), ("args", showJSON cs)]
|
||||
|
||||
readJSON o = CatDef <$> readJSON o <*> return []
|
||||
<|> CatDef <$> o!"cat" <*> o!"args"
|
||||
|
||||
instance JSON FunDef where
|
||||
showJSON (FunDef f ty) = makeObj [("fun", showJSON f), ("type", showJSON ty)]
|
||||
|
||||
readJSON o = FunDef <$> o!"fun" <*> o!"type"
|
||||
|
||||
instance JSON Type where
|
||||
showJSON (Type bs ty) = makeObj [(".args", showJSON bs), (".result", showJSON ty)]
|
||||
|
||||
readJSON o = Type <$> o!".args" <*> o!".result"
|
||||
|
||||
instance JSON TypeApp where
|
||||
-- non-dependent categories are encoded as simple strings:
|
||||
showJSON (TypeApp c []) = showJSON c
|
||||
showJSON (TypeApp c args) = makeObj [(".cat", showJSON c), (".args", showJSON args)]
|
||||
|
||||
readJSON o = TypeApp <$> readJSON o <*> return []
|
||||
<|> TypeApp <$> o!".cat" <*> o!".args"
|
||||
|
||||
instance JSON TypeBinding where
|
||||
-- non-dependent categories are encoded as simple strings:
|
||||
showJSON (TypeBinding Anonymous (Type [] (TypeApp c []))) = showJSON c
|
||||
showJSON (TypeBinding x ty) = makeObj [(".var", showJSON x), (".type", showJSON ty)]
|
||||
|
||||
readJSON o = do c <- readJSON o
|
||||
return (TypeBinding Anonymous (Type [] (TypeApp c [])))
|
||||
<|> TypeBinding <$> o!".var" <*> o!".type"
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- ** Concrete syntax
|
||||
|
||||
instance JSON Concrete where
|
||||
showJSON (Concrete cncid absid flags params lincats lins)
|
||||
= makeObj [("cnc", showJSON cncid),
|
||||
("abs", showJSON absid),
|
||||
("flags", showJSON flags),
|
||||
("params", showJSON params),
|
||||
("lincats", showJSON lincats),
|
||||
("lins", showJSON lins)]
|
||||
|
||||
readJSON o = Concrete
|
||||
<$> o!"cnc"
|
||||
<*> o!"abs"
|
||||
<*>(o!"flags" <|> return (Flags []))
|
||||
<*> o!"params"
|
||||
<*> o!"lincats"
|
||||
<*> o!"lins"
|
||||
|
||||
instance JSON ParamDef where
|
||||
showJSON (ParamDef p pvs) = makeObj [("param", showJSON p), ("values", showJSON pvs)]
|
||||
showJSON (ParamAliasDef p t) = makeObj [("param", showJSON p), ("alias", showJSON t)]
|
||||
|
||||
readJSON o = ParamDef <$> o!"param" <*> o!"values"
|
||||
<|> ParamAliasDef <$> o!"param" <*> o!"alias"
|
||||
|
||||
instance JSON LincatDef where
|
||||
showJSON (LincatDef c lt) = makeObj [("cat", showJSON c), ("lintype", showJSON lt)]
|
||||
|
||||
readJSON o = LincatDef <$> o!"cat" <*> o!"lintype"
|
||||
|
||||
instance JSON LinDef where
|
||||
showJSON (LinDef f xs lv) = makeObj [("fun", showJSON f), ("args", showJSON xs), ("lin", showJSON lv)]
|
||||
|
||||
readJSON o = LinDef <$> o!"fun" <*> o!"args" <*> o!"lin"
|
||||
|
||||
instance JSON LinType where
|
||||
-- the basic types (Str, Float, Int) are encoded as strings:
|
||||
showJSON (StrType) = showJSON "Str"
|
||||
showJSON (FloatType) = showJSON "Float"
|
||||
showJSON (IntType) = showJSON "Int"
|
||||
-- parameters are also encoded as strings:
|
||||
showJSON (ParamType pt) = showJSON pt
|
||||
-- tables/tuples are encoded as JSON objects:
|
||||
showJSON (TableType pt lt) = makeObj [(".tblarg", showJSON pt), (".tblval", showJSON lt)]
|
||||
showJSON (TupleType lts) = makeObj [(".tuple", showJSON lts)]
|
||||
-- records are encoded as records:
|
||||
showJSON (RecordType rows) = showJSON rows
|
||||
|
||||
readJSON o = do "Str" <- readJSON o; return StrType
|
||||
<|> do "Float" <- readJSON o; return FloatType
|
||||
<|> do "Int" <- readJSON o; return IntType
|
||||
<|> do ptype <- readJSON o; return (ParamType ptype)
|
||||
<|> TableType <$> o!".tblarg" <*> o!".tblval"
|
||||
<|> TupleType <$> o!".tuple"
|
||||
<|> RecordType <$> readJSON o
|
||||
|
||||
instance JSON LinValue where
|
||||
showJSON (LiteralValue l ) = showJSON l
|
||||
-- most values are encoded as JSON objects:
|
||||
showJSON (ParamConstant pv) = makeObj [(".param", showJSON pv)]
|
||||
showJSON (PredefValue p ) = makeObj [(".predef", showJSON p)]
|
||||
showJSON (TableValue t tvs) = makeObj [(".tblarg", showJSON t), (".tblrows", showJSON tvs)]
|
||||
showJSON (TupleValue lvs) = makeObj [(".tuple", showJSON lvs)]
|
||||
showJSON (VarValue v ) = makeObj [(".var", showJSON v)]
|
||||
showJSON (ErrorValue s ) = makeObj [(".error", showJSON s)]
|
||||
showJSON (Projection lv l ) = makeObj [(".project", showJSON lv), (".label", showJSON l)]
|
||||
showJSON (Selection tv pv) = makeObj [(".select", showJSON tv), (".key", showJSON pv)]
|
||||
showJSON (VariantValue vs) = makeObj [(".variants", showJSON vs)]
|
||||
showJSON (PreValue pre def) = makeObj [(".pre", showJSON pre),(".default", showJSON def)]
|
||||
-- records are encoded directly as JSON records:
|
||||
showJSON (RecordValue rows) = showJSON rows
|
||||
-- concatenation is encoded as a JSON array:
|
||||
showJSON v@(ConcatValue _ _) = showJSON (flatten v [])
|
||||
where flatten (ConcatValue v v') = flatten v . flatten v'
|
||||
flatten v = (v :)
|
||||
|
||||
readJSON o = LiteralValue <$> readJSON o
|
||||
<|> ParamConstant <$> o!".param"
|
||||
<|> PredefValue <$> o!".predef"
|
||||
<|> TableValue <$> o!".tblarg" <*> o!".tblrows"
|
||||
<|> TupleValue <$> o!".tuple"
|
||||
<|> VarValue <$> o!".var"
|
||||
<|> ErrorValue <$> o!".error"
|
||||
<|> Projection <$> o!".project" <*> o!".label"
|
||||
<|> Selection <$> o!".select" <*> o!".key"
|
||||
<|> VariantValue <$> o!".variants"
|
||||
<|> PreValue <$> o!".pre" <*> o!".default"
|
||||
<|> RecordValue <$> readJSON o
|
||||
<|> do vs <- readJSON o :: Result [LinValue]
|
||||
return (foldr1 ConcatValue vs)
|
||||
|
||||
instance JSON LinLiteral where
|
||||
-- basic values (Str, Float, Int) are encoded as JSON strings/numbers:
|
||||
showJSON (StrConstant s) = showJSON s
|
||||
showJSON (FloatConstant f) = showJSON f
|
||||
showJSON (IntConstant n) = showJSON n
|
||||
|
||||
readJSON = readBasicJSON StrConstant IntConstant FloatConstant
|
||||
|
||||
instance JSON LinPattern where
|
||||
-- wildcards and patterns without arguments are encoded as strings:
|
||||
showJSON (WildPattern) = showJSON "_"
|
||||
showJSON (ParamPattern (Param p [])) = showJSON p
|
||||
-- complex patterns are encoded as JSON objects:
|
||||
showJSON (ParamPattern pv) = showJSON pv
|
||||
-- and records as records:
|
||||
showJSON (RecordPattern r) = showJSON r
|
||||
|
||||
readJSON o = do "_" <- readJSON o; return WildPattern
|
||||
<|> do p <- readJSON o; return (ParamPattern (Param p []))
|
||||
<|> ParamPattern <$> readJSON o
|
||||
<|> RecordPattern <$> readJSON o
|
||||
|
||||
instance JSON arg => JSON (Param arg) where
|
||||
-- parameters without arguments are encoded as strings:
|
||||
showJSON (Param p []) = showJSON p
|
||||
showJSON (Param p args) = makeObj [(".paramid", showJSON p), (".args", showJSON args)]
|
||||
|
||||
readJSON o = Param <$> readJSON o <*> return []
|
||||
<|> Param <$> o!".paramid" <*> o!".args"
|
||||
|
||||
instance JSON a => JSON (RecordRow a) where
|
||||
-- record rows and lists of record rows are both encoded as JSON records (i.e., objects)
|
||||
showJSON row = showJSONs [row]
|
||||
showJSONs rows = makeObj (map toRow rows)
|
||||
where toRow (RecordRow (LabelId lbl) val) = (lbl, showJSON val)
|
||||
|
||||
readJSON obj = head <$> readJSONs obj
|
||||
readJSONs obj = mapM fromRow (assocsJSObject obj)
|
||||
where fromRow (lbl, jsvalue) = do value <- readJSON jsvalue
|
||||
return (RecordRow (LabelId lbl) value)
|
||||
|
||||
instance JSON rhs => JSON (TableRow rhs) where
|
||||
showJSON (TableRow l v) = makeObj [(".pattern", showJSON l), (".value", showJSON v)]
|
||||
|
||||
readJSON o = TableRow <$> o!".pattern" <*> o!".value"
|
||||
|
||||
|
||||
-- *** Identifiers in Concrete Syntax
|
||||
|
||||
instance JSON PredefId where showJSON (PredefId s) = showJSON s ; readJSON = fmap PredefId . readJSON
|
||||
instance JSON LabelId where showJSON (LabelId s) = showJSON s ; readJSON = fmap LabelId . readJSON
|
||||
instance JSON VarValueId where showJSON (VarValueId s) = showJSON s ; readJSON = fmap VarValueId . readJSON
|
||||
instance JSON ParamId where showJSON (ParamId s) = showJSON s ; readJSON = fmap ParamId . readJSON
|
||||
instance JSON ParamType where showJSON (ParamTypeId s) = showJSON s ; readJSON = fmap ParamTypeId . readJSON
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- ** Used in both Abstract and Concrete Syntax
|
||||
|
||||
instance JSON ModId where showJSON (ModId s) = showJSON s ; readJSON = fmap ModId . readJSON
|
||||
instance JSON CatId where showJSON (CatId s) = showJSON s ; readJSON = fmap CatId . readJSON
|
||||
instance JSON FunId where showJSON (FunId s) = showJSON s ; readJSON = fmap FunId . readJSON
|
||||
|
||||
instance JSON VarId where
|
||||
-- the anonymous variable is the underscore:
|
||||
showJSON Anonymous = showJSON "_"
|
||||
showJSON (VarId x) = showJSON x
|
||||
|
||||
readJSON o = do "_" <- readJSON o; return Anonymous
|
||||
<|> VarId <$> readJSON o
|
||||
|
||||
instance JSON QualId where
|
||||
showJSON (Qual (ModId m) n) = showJSON (m++"."++n)
|
||||
showJSON (Unqual n) = showJSON n
|
||||
|
||||
readJSON o = do qualid <- readJSON o
|
||||
let (mod, id) = span (/= '.') qualid
|
||||
return $ if null mod then Unqual id else Qual (ModId mod) id
|
||||
|
||||
instance JSON Flags where
|
||||
-- flags are encoded directly as JSON records (i.e., objects):
|
||||
showJSON (Flags fs) = makeObj [(f, showJSON v) | (f, v) <- fs]
|
||||
|
||||
readJSON obj = Flags <$> mapM fromRow (assocsJSObject obj)
|
||||
where fromRow (lbl, jsvalue) = do value <- readJSON jsvalue
|
||||
return (lbl, value)
|
||||
|
||||
instance JSON FlagValue where
|
||||
-- flag values are encoded as basic JSON types:
|
||||
showJSON (Str s) = showJSON s
|
||||
showJSON (Int i) = showJSON i
|
||||
showJSON (Flt f) = showJSON f
|
||||
|
||||
readJSON = readBasicJSON Str Int Flt
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- ** Convenience functions
|
||||
|
||||
(!) :: JSON a => JSValue -> String -> Result a
|
||||
obj ! key = maybe (fail $ "CanonicalJSON.(!): Could not find key: " ++ show key)
|
||||
readJSON
|
||||
(lookup key (assocsJSObject obj))
|
||||
|
||||
assocsJSObject :: JSValue -> [(String, JSValue)]
|
||||
assocsJSObject (JSObject o) = fromJSObject o
|
||||
assocsJSObject (JSArray _) = fail $ "CanonicalJSON.assocsJSObject: Expected a JSON object, found an Array"
|
||||
assocsJSObject jsvalue = fail $ "CanonicalJSON.assocsJSObject: Expected a JSON object, found " ++ show jsvalue
|
||||
|
||||
|
||||
readBasicJSON :: (JSON int, Integral int, JSON flt, RealFloat flt) =>
|
||||
(String -> v) -> (int -> v) -> (flt -> v) -> JSValue -> Result v
|
||||
readBasicJSON str int flt o
|
||||
= str <$> readJSON o
|
||||
<|> int_or_flt <$> readJSON o
|
||||
where int_or_flt f | f == fromIntegral n = int n
|
||||
| otherwise = flt f
|
||||
where n = round f
|
||||
@@ -209,7 +209,7 @@ ppTerm q d (S x y) = case x of
|
||||
ppTerm q d (ExtR x y) = prec d 3 (ppTerm q 3 x <+> "**" <+> ppTerm q 4 y)
|
||||
ppTerm q d (App x y) = prec d 4 (ppTerm q 4 x <+> ppTerm q 5 y)
|
||||
ppTerm q d (V e es) = hang "table" 2 (sep [ppTerm q 6 e,brackets (fsep (punctuate ';' (map (ppTerm q 0) es)))])
|
||||
ppTerm q d (FV es) = "variants" <+> braces (fsep (punctuate ';' (map (ppTerm q 0) es)))
|
||||
ppTerm q d (FV es) = prec d 4 ("variants" <+> braces (fsep (punctuate ';' (map (ppTerm q 0) es))))
|
||||
ppTerm q d (AdHocOverload es) = "overload" <+> braces (fsep (punctuate ';' (map (ppTerm q 0) es)))
|
||||
ppTerm q d (Alts e xs) = prec d 4 ("pre" <+> braces (ppTerm q 0 e <> ';' <+> fsep (punctuate ';' (map (ppAltern q) xs))))
|
||||
ppTerm q d (Strs es) = "strs" <+> braces (fsep (punctuate ';' (map (ppTerm q 0) es)))
|
||||
|
||||
@@ -40,6 +40,9 @@ tvar = TId
|
||||
tcon0 = TId
|
||||
tcon c = foldl TAp (TId c)
|
||||
|
||||
lets [] e = e
|
||||
lets ds e = Lets ds e
|
||||
|
||||
let1 x xe e = Lets [(x,xe)] e
|
||||
single x = List [x]
|
||||
|
||||
@@ -113,7 +116,8 @@ instance Pretty Exp where
|
||||
Op e1 op e2 -> hang (ppB e1<+>op) 2 (ppB e2)
|
||||
Lets bs e -> sep ["let"<+>vcat [hang (x<+>"=") 2 xe|(x,xe)<-bs],
|
||||
"in" <+>e]
|
||||
LambdaCase alts -> hang "\\case" 4 (vcat [p<+>"->"<+>e|(p,e)<-alts])
|
||||
LambdaCase alts ->
|
||||
hang "\\case" 2 (vcat [hang (p<+>"->") 2 e|(p,e)<-alts])
|
||||
_ -> ppB e
|
||||
|
||||
ppB e = case flatAp e of f:as -> hang (ppA f) 2 (sep (map ppA as))
|
||||
|
||||
@@ -87,7 +87,10 @@ data Phase = Preproc | Convert | Compile | Link
|
||||
deriving (Show,Eq,Ord)
|
||||
|
||||
data OutputFormat = FmtPGFPretty
|
||||
| FmtCanonicalGF
|
||||
| FmtCanonicalJson
|
||||
| FmtJavaScript
|
||||
| FmtJSON
|
||||
| FmtPython
|
||||
| FmtHaskell
|
||||
| FmtJava
|
||||
@@ -325,7 +328,8 @@ optDescr =
|
||||
Option [] ["gfo-dir"] (ReqArg gfoDir "DIR") "Directory to put .gfo files in (default = '.').",
|
||||
Option ['f'] ["output-format"] (ReqArg outFmt "FMT")
|
||||
(unlines ["Output format. FMT can be one of:",
|
||||
"Multiple concrete: pgf (default), js, pgf_pretty, prolog, python, ...", -- gar,
|
||||
"Canonical GF grammar: canonical_gf, canonical_json, (and haskell with option --haskell=concrete)",
|
||||
"Multiple concrete: pgf (default), json, js, pgf_pretty, prolog, python, ...", -- gar,
|
||||
"Single concrete only: bnf, ebnf, fa, gsl, jsgf, regexp, slf, srgs_xml, srgs_abnf, vxml, ....", -- cf, lbnf,
|
||||
"Abstract only: haskell, ..."]), -- prolog_abs,
|
||||
Option [] ["sisr"] (ReqArg sisrFmt "FMT")
|
||||
@@ -468,7 +472,10 @@ outputFormats = map fst outputFormatsExpl
|
||||
outputFormatsExpl :: [((String,OutputFormat),String)]
|
||||
outputFormatsExpl =
|
||||
[(("pgf_pretty", FmtPGFPretty),"human-readable pgf"),
|
||||
(("canonical_gf", FmtCanonicalGF),"Canonical GF source files"),
|
||||
(("canonical_json", FmtCanonicalJson),"Canonical JSON source files"),
|
||||
(("js", FmtJavaScript),"JavaScript (whole grammar)"),
|
||||
(("json", FmtJSON),"JSON (whole grammar)"),
|
||||
(("python", FmtPython),"Python (whole grammar)"),
|
||||
(("haskell", FmtHaskell),"Haskell (abstract syntax)"),
|
||||
(("java", FmtJava),"Java (abstract syntax)"),
|
||||
|
||||
@@ -8,13 +8,13 @@ import System.Directory as D
|
||||
doesDirectoryExist,doesFileExist,getModificationTime,
|
||||
getCurrentDirectory,getDirectoryContents,getPermissions,
|
||||
removeFile,renameFile)
|
||||
import Data.Time.Compat
|
||||
--import Data.Time.Compat
|
||||
|
||||
canonicalizePath path = liftIO $ D.canonicalizePath path
|
||||
createDirectoryIfMissing b = liftIO . D.createDirectoryIfMissing b
|
||||
doesDirectoryExist path = liftIO $ D.doesDirectoryExist path
|
||||
doesFileExist path = liftIO $ D.doesFileExist path
|
||||
getModificationTime path = liftIO $ fmap toUTCTime (D.getModificationTime path)
|
||||
getModificationTime path = liftIO $ {-fmap toUTCTime-} (D.getModificationTime path)
|
||||
getDirectoryContents path = liftIO $ D.getDirectoryContents path
|
||||
|
||||
getCurrentDirectory :: MonadIO io => io FilePath
|
||||
|
||||
@@ -20,6 +20,7 @@ instance Pretty a => Pretty [a] where
|
||||
ppList = fsep . map pp -- hmm
|
||||
|
||||
render x = PP.render (pp x)
|
||||
render80 x = renderStyle style{lineLength=80,ribbonsPerLine=1} x
|
||||
renderStyle s x = PP.renderStyle s (pp x)
|
||||
|
||||
infixl 5 $$,$+$
|
||||
|
||||
@@ -68,6 +68,7 @@ libpgf_la_SOURCES = \
|
||||
pgf/data.h \
|
||||
pgf/expr.c \
|
||||
pgf/expr.h \
|
||||
pgf/scanner.c \
|
||||
pgf/parser.c \
|
||||
pgf/lookup.c \
|
||||
pgf/jit.c \
|
||||
|
||||
@@ -74,6 +74,8 @@
|
||||
|
||||
#ifdef GU_ALIGNOF
|
||||
# define gu_alignof GU_ALIGNOF
|
||||
#elif defined(_MSC_VER)
|
||||
# define gu_alignof __alignof
|
||||
#else
|
||||
# define gu_alignof(t_) \
|
||||
((size_t)(offsetof(struct { char c_; t_ e_; }, e_)))
|
||||
@@ -87,7 +89,7 @@
|
||||
|
||||
#define GU_COMMA ,
|
||||
|
||||
#define GU_ARRAY_LEN(t,a) (sizeof((const t[])a) / sizeof(t))
|
||||
#define GU_ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||
#define GU_ID(...) __VA_ARGS__
|
||||
|
||||
@@ -193,9 +195,13 @@ typedef union {
|
||||
void (*fp)();
|
||||
} GuMaxAlign;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <malloc.h>
|
||||
#define gu_alloca(N) alloca(N)
|
||||
#else
|
||||
#define gu_alloca(N) \
|
||||
(((union { GuMaxAlign align_; uint8_t buf_[N]; }){{0}}).buf_)
|
||||
|
||||
#endif
|
||||
|
||||
// For Doxygen
|
||||
#define GU_PRIVATE /** @private */
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -108,6 +112,39 @@ gu_mem_buf_alloc(size_t min_size, size_t* real_size_out)
|
||||
return gu_mem_buf_realloc(NULL, min_size, real_size_out);
|
||||
}
|
||||
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
#include <windows.h>
|
||||
|
||||
static int
|
||||
getpagesize()
|
||||
{
|
||||
SYSTEM_INFO system_info;
|
||||
GetSystemInfo(&system_info);
|
||||
return system_info.dwPageSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
GU_API void*
|
||||
gu_mem_page_alloc(size_t min_size, size_t* real_size_out)
|
||||
{
|
||||
size_t page_size = getpagesize();
|
||||
size_t size = ((min_size + page_size - 1) / page_size) * page_size;
|
||||
void *page = NULL;
|
||||
|
||||
#if defined(ANDROID)
|
||||
if ((page = memalign(page_size, size)) == NULL) {
|
||||
#elif defined(__MINGW32__) || defined(_MSC_VER)
|
||||
if ((page = malloc(size)) == NULL) {
|
||||
#else
|
||||
if (posix_memalign(&page, page_size, size) != 0) {
|
||||
#endif
|
||||
gu_fatal("Memory allocation failed");
|
||||
}
|
||||
|
||||
*real_size_out = size;
|
||||
return page;
|
||||
}
|
||||
|
||||
GU_API void
|
||||
gu_mem_buf_free(void* buf)
|
||||
{
|
||||
@@ -132,6 +169,7 @@ struct GuFinalizerNode {
|
||||
enum GuPoolType {
|
||||
GU_POOL_HEAP,
|
||||
GU_POOL_LOCAL,
|
||||
GU_POOL_PAGE,
|
||||
GU_POOL_MMAP
|
||||
};
|
||||
|
||||
@@ -180,6 +218,16 @@ gu_new_pool(void)
|
||||
return pool;
|
||||
}
|
||||
|
||||
GU_API GuPool*
|
||||
gu_new_page_pool(void)
|
||||
{
|
||||
size_t sz = GU_FLEX_SIZE(GuPool, init_buf, gu_mem_pool_initial_size);
|
||||
uint8_t* buf = gu_mem_page_alloc(sz, &sz);
|
||||
GuPool* pool = gu_init_pool(buf, sz);
|
||||
pool->type = GU_POOL_PAGE;
|
||||
return pool;
|
||||
}
|
||||
|
||||
GU_API GuPool*
|
||||
gu_mmap_pool(char* fpath, void* addr, size_t size, void**pptr)
|
||||
{
|
||||
@@ -238,7 +286,10 @@ gu_pool_expand(GuPool* pool, size_t req)
|
||||
gu_mem_chunk_max_size));
|
||||
gu_assert(real_req >= sizeof(GuMemChunk));
|
||||
size_t size = 0;
|
||||
GuMemChunk* chunk = gu_mem_buf_alloc(real_req, &size);
|
||||
GuMemChunk* chunk =
|
||||
(pool->type == GU_POOL_PAGE)
|
||||
? gu_mem_page_alloc(real_req, &size)
|
||||
: gu_mem_buf_alloc(real_req, &size);
|
||||
chunk->next = pool->chunks;
|
||||
pool->chunks = chunk;
|
||||
pool->curr_buf = (uint8_t*) chunk;
|
||||
@@ -309,6 +360,7 @@ gu_malloc_prefixed(GuPool* pool, size_t pre_align, size_t pre_size,
|
||||
size_t full_size = gu_mem_advance(offsetof(GuMemChunk, data),
|
||||
pre_align, pre_size, align, size);
|
||||
if (full_size > gu_mem_max_shared_alloc &&
|
||||
pool->type != GU_POOL_PAGE &&
|
||||
pool->type != GU_POOL_MMAP) {
|
||||
GuMemChunk* chunk = gu_mem_alloc(full_size);
|
||||
chunk->next = pool->chunks;
|
||||
|
||||
@@ -55,6 +55,11 @@ gu_local_pool_(uint8_t* init_buf, size_t sz);
|
||||
* should not be used in the bodies of recursive functions.
|
||||
*/
|
||||
|
||||
/// Create a pool where each chunk is corresponds to one or
|
||||
/// more pages.
|
||||
GU_API_DECL GuPool*
|
||||
gu_new_page_pool(void);
|
||||
|
||||
/// Create a pool stored in a memory mapped file.
|
||||
GU_API_DECL GuPool*
|
||||
gu_mmap_pool(char* fpath, void* addr, size_t size, void**pptr);
|
||||
@@ -198,6 +203,9 @@ gu_mem_buf_realloc(
|
||||
size_t min_size,
|
||||
size_t* real_size_out);
|
||||
|
||||
/// Allocate enough memory pages to contain min_size bytes.
|
||||
GU_API_DECL void*
|
||||
gu_mem_page_alloc(size_t min_size, size_t* real_size_out);
|
||||
|
||||
/// Free a memory buffer.
|
||||
GU_API_DECL void
|
||||
|
||||
@@ -100,6 +100,11 @@ gu_seq_free(GuSeq* seq)
|
||||
gu_mem_buf_free(seq);
|
||||
}
|
||||
|
||||
static void
|
||||
gu_dummy_finalizer(GuFinalizer* self)
|
||||
{
|
||||
}
|
||||
|
||||
GU_API void
|
||||
gu_buf_require(GuBuf* buf, size_t req_len)
|
||||
{
|
||||
@@ -109,7 +114,9 @@ gu_buf_require(GuBuf* buf, size_t req_len)
|
||||
|
||||
size_t req_size = sizeof(GuSeq) + buf->elem_size * req_len;
|
||||
size_t real_size;
|
||||
|
||||
|
||||
gu_require(buf->fin.fn != gu_dummy_finalizer);
|
||||
|
||||
if (buf->seq == NULL || buf->seq == gu_empty_seq()) {
|
||||
buf->seq = gu_mem_buf_alloc(req_size, &real_size);
|
||||
buf->seq->len = 0;
|
||||
@@ -164,6 +171,24 @@ gu_buf_freeze(GuBuf* buf, GuPool* pool)
|
||||
return seq;
|
||||
}
|
||||
|
||||
GU_API void
|
||||
gu_buf_evacuate(GuBuf* buf, GuPool* pool)
|
||||
{
|
||||
if (buf->seq != gu_empty_seq()) {
|
||||
size_t len = gu_buf_length(buf);
|
||||
|
||||
GuSeq* seq = gu_make_seq(buf->elem_size, len, pool);
|
||||
void* bufdata = gu_buf_data(buf);
|
||||
void* seqdata = gu_seq_data(seq);
|
||||
memcpy(seqdata, bufdata, buf->elem_size * len);
|
||||
gu_mem_buf_free(buf->seq);
|
||||
|
||||
buf->seq = seq;
|
||||
buf->fin.fn = gu_dummy_finalizer;
|
||||
buf->avail_len = len;
|
||||
}
|
||||
}
|
||||
|
||||
GU_API void*
|
||||
gu_buf_insert(GuBuf* buf, size_t index)
|
||||
{
|
||||
@@ -335,13 +360,8 @@ GU_API void
|
||||
gu_buf_heap_pop(GuBuf *buf, GuOrder *order, void* data_out)
|
||||
{
|
||||
const void* last = gu_buf_trim(buf); // raises an error if empty
|
||||
|
||||
if (gu_buf_length(buf) > 0) {
|
||||
memcpy(data_out, buf->seq->data, buf->elem_size);
|
||||
gu_heap_siftup(buf, order, last, 0);
|
||||
} else {
|
||||
memcpy(data_out, last, buf->elem_size);
|
||||
}
|
||||
memcpy(data_out, buf->seq->data, buf->elem_size);
|
||||
gu_heap_siftup(buf, order, last, 0);
|
||||
}
|
||||
|
||||
GU_API void
|
||||
|
||||
@@ -182,6 +182,9 @@ gu_buf_heapify(GuBuf *buf, GuOrder *order);
|
||||
|
||||
GU_API_DECL GuSeq*
|
||||
gu_buf_freeze(GuBuf* buf, GuPool* pool);
|
||||
|
||||
GU_API_DECL void
|
||||
gu_buf_evacuate(GuBuf* buf, GuPool* pool);
|
||||
#endif // GU_SEQ_H_
|
||||
|
||||
#ifdef GU_STRING_H_
|
||||
|
||||
@@ -197,16 +197,16 @@ pgf_literal_hash(GuHash h, PgfLiteral lit);
|
||||
PGF_API_DECL GuHash
|
||||
pgf_expr_hash(GuHash h, PgfExpr e);
|
||||
|
||||
PGF_API size_t
|
||||
PGF_API_DECL size_t
|
||||
pgf_expr_size(PgfExpr expr);
|
||||
|
||||
PGF_API GuSeq*
|
||||
PGF_API_DECL GuSeq*
|
||||
pgf_expr_functions(PgfExpr expr, GuPool* pool);
|
||||
|
||||
PGF_API PgfExpr
|
||||
PGF_API_DECL PgfExpr
|
||||
pgf_expr_substitute(PgfExpr expr, GuSeq* meta_values, GuPool* pool);
|
||||
|
||||
PGF_API PgfType*
|
||||
PGF_API_DECL PgfType*
|
||||
pgf_type_substitute(PgfType* type, GuSeq* meta_values, GuPool* pool);
|
||||
|
||||
typedef struct PgfPrintContext PgfPrintContext;
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
#include <pgf/reasoner.h>
|
||||
#include <pgf/reader.h>
|
||||
#include "lightning.h"
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
//#define PGF_JIT_DEBUG
|
||||
|
||||
@@ -43,18 +40,6 @@ typedef struct {
|
||||
#define JIT_VSTATE JIT_V1
|
||||
#define JIT_VCLOS JIT_V2
|
||||
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
#include <windows.h>
|
||||
|
||||
static int
|
||||
getpagesize()
|
||||
{
|
||||
SYSTEM_INFO system_info;
|
||||
GetSystemInfo(&system_info);
|
||||
return system_info.dwPageSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
pgf_jit_finalize_page(GuFinalizer* self)
|
||||
@@ -65,19 +50,8 @@ pgf_jit_finalize_page(GuFinalizer* self)
|
||||
static void
|
||||
pgf_jit_alloc_page(PgfReader* rdr)
|
||||
{
|
||||
void *page;
|
||||
|
||||
size_t page_size = getpagesize();
|
||||
|
||||
#if defined(ANDROID)
|
||||
if ((page = memalign(page_size, page_size)) == NULL) {
|
||||
#elif defined(__MINGW32__) || defined(_MSC_VER)
|
||||
if ((page = malloc(page_size)) == NULL) {
|
||||
#else
|
||||
if (posix_memalign(&page, page_size, page_size) != 0) {
|
||||
#endif
|
||||
gu_fatal("Memory allocation failed");
|
||||
}
|
||||
size_t page_size;
|
||||
void *page = gu_mem_page_alloc(sizeof(GuFinalizer), &page_size);
|
||||
|
||||
GuFinalizer* fin = page;
|
||||
fin->fn = pgf_jit_finalize_page;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -167,6 +167,22 @@ PGF_API_DECL void
|
||||
pgf_lookup_morpho(PgfConcr *concr, GuString sentence,
|
||||
PgfMorphoCallback* callback, GuExn* err);
|
||||
|
||||
typedef struct {
|
||||
size_t pos;
|
||||
GuString ptr;
|
||||
} PgfCohortSpot;
|
||||
|
||||
typedef struct {
|
||||
PgfCohortSpot start;
|
||||
PgfCohortSpot end;
|
||||
GuBuf* buf;
|
||||
} PgfCohortRange;
|
||||
|
||||
PGF_API_DECL GuEnum*
|
||||
pgf_lookup_cohorts(PgfConcr *concr, GuString sentence,
|
||||
PgfMorphoCallback* callback,
|
||||
GuPool* pool, GuExn* err);
|
||||
|
||||
typedef struct PgfFullFormEntry PgfFullFormEntry;
|
||||
|
||||
PGF_API_DECL GuEnum*
|
||||
|
||||
@@ -94,6 +94,74 @@ pgf_print_fid(int fid, GuOut* out, GuExn* err)
|
||||
gu_printf(out, err, "C%d", fid);
|
||||
}
|
||||
|
||||
PGF_INTERNAL void
|
||||
pgf_print_production_args(PgfPArgs* args,
|
||||
GuOut* out, GuExn* err)
|
||||
{
|
||||
size_t n_args = gu_seq_length(args);
|
||||
for (size_t j = 0; j < n_args; j++) {
|
||||
if (j > 0)
|
||||
gu_putc(',',out,err);
|
||||
|
||||
PgfPArg arg = gu_seq_get(args, PgfPArg, j);
|
||||
|
||||
if (arg.hypos != NULL &&
|
||||
gu_seq_length(arg.hypos) > 0) {
|
||||
size_t n_hypos = gu_seq_length(arg.hypos);
|
||||
for (size_t k = 0; k < n_hypos; k++) {
|
||||
PgfCCat *hypo = gu_seq_get(arg.hypos, PgfCCat*, k);
|
||||
pgf_print_fid(hypo->fid, out, err);
|
||||
gu_putc(' ',out,err);
|
||||
}
|
||||
gu_puts("-> ",out,err);
|
||||
}
|
||||
|
||||
pgf_print_fid(arg.ccat->fid, out, err);
|
||||
}
|
||||
}
|
||||
|
||||
PGF_INTERNAL void
|
||||
pgf_print_production(int fid, PgfProduction prod,
|
||||
GuOut *out, GuExn* err)
|
||||
{
|
||||
pgf_print_fid(fid, out, err);
|
||||
gu_puts(" -> ", out, err);
|
||||
|
||||
GuVariantInfo i = gu_variant_open(prod);
|
||||
switch (i.tag) {
|
||||
case PGF_PRODUCTION_APPLY: {
|
||||
PgfProductionApply* papp = i.data;
|
||||
gu_printf(out,err,"F%d(",papp->fun->funid);
|
||||
if (papp->fun->ep != NULL) {
|
||||
pgf_print_expr(papp->fun->ep->expr, NULL, 0, out, err);
|
||||
} else {
|
||||
PgfPArg* parg = gu_seq_index(papp->args, PgfPArg, 0);
|
||||
gu_printf(out,err,"linref %s", parg->ccat->cnccat->abscat->name);
|
||||
}
|
||||
gu_printf(out,err,")[");
|
||||
pgf_print_production_args(papp->args,out,err);
|
||||
gu_printf(out,err,"]\n");
|
||||
break;
|
||||
}
|
||||
case PGF_PRODUCTION_COERCE: {
|
||||
PgfProductionCoerce* pcoerce = i.data;
|
||||
gu_puts("_[",out,err);
|
||||
pgf_print_fid(pcoerce->coerce->fid, out, err);
|
||||
gu_puts("]\n",out,err);
|
||||
break;
|
||||
}
|
||||
case PGF_PRODUCTION_EXTERN: {
|
||||
PgfProductionExtern* pext = i.data;
|
||||
gu_printf(out,err,"<extern>(");
|
||||
pgf_print_expr(pext->ep->expr, NULL, 0, out, err);
|
||||
gu_printf(out,err,")[]\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
gu_impossible();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pgf_print_productions(GuMapItor* fn, const void* key, void* value,
|
||||
GuExn* err)
|
||||
@@ -107,48 +175,7 @@ pgf_print_productions(GuMapItor* fn, const void* key, void* value,
|
||||
size_t n_prods = gu_seq_length(ccat->prods);
|
||||
for (size_t i = 0; i < n_prods; i++) {
|
||||
PgfProduction prod = gu_seq_get(ccat->prods, PgfProduction, i);
|
||||
|
||||
gu_puts(" ", out, err);
|
||||
pgf_print_fid(fid, out, err);
|
||||
gu_puts(" -> ", out, err);
|
||||
|
||||
GuVariantInfo i = gu_variant_open(prod);
|
||||
switch (i.tag) {
|
||||
case PGF_PRODUCTION_APPLY: {
|
||||
PgfProductionApply* papp = i.data;
|
||||
gu_printf(out,err,"F%d[",papp->fun->funid);
|
||||
size_t n_args = gu_seq_length(papp->args);
|
||||
for (size_t j = 0; j < n_args; j++) {
|
||||
if (j > 0)
|
||||
gu_putc(',',out,err);
|
||||
|
||||
PgfPArg arg = gu_seq_get(papp->args, PgfPArg, j);
|
||||
|
||||
if (arg.hypos != NULL) {
|
||||
size_t n_hypos = gu_seq_length(arg.hypos);
|
||||
for (size_t k = 0; k < n_hypos; k++) {
|
||||
if (k > 0)
|
||||
gu_putc(' ',out,err);
|
||||
PgfCCat *hypo = gu_seq_get(arg.hypos, PgfCCat*, k);
|
||||
pgf_print_fid(hypo->fid, out, err);
|
||||
}
|
||||
}
|
||||
|
||||
pgf_print_fid(arg.ccat->fid, out, err);
|
||||
}
|
||||
gu_printf(out,err,"]\n");
|
||||
break;
|
||||
}
|
||||
case PGF_PRODUCTION_COERCE: {
|
||||
PgfProductionCoerce* pcoerce = i.data;
|
||||
gu_puts("_[", out, err);
|
||||
pgf_print_fid(pcoerce->coerce->fid, out, err);
|
||||
gu_puts("]\n", out, err);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
gu_impossible();
|
||||
}
|
||||
pgf_print_production(fid, prod, out, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,16 +328,20 @@ pgf_read_patt(PgfReader* rdr)
|
||||
uint8_t tag = pgf_read_tag(rdr);
|
||||
switch (tag) {
|
||||
case PGF_PATT_APP: {
|
||||
PgfCId ctor = pgf_read_cid(rdr, rdr->opool);
|
||||
gu_return_on_exn(rdr->err, gu_null_variant);
|
||||
|
||||
size_t n_args = pgf_read_len(rdr);
|
||||
gu_return_on_exn(rdr->err, gu_null_variant);
|
||||
|
||||
PgfPattApp *papp =
|
||||
gu_new_variant(PGF_PATT_APP,
|
||||
PgfPattApp,
|
||||
&patt, rdr->opool);
|
||||
papp->ctor = pgf_read_cid(rdr, rdr->opool);
|
||||
gu_return_on_exn(rdr->err, gu_null_variant);
|
||||
|
||||
papp->n_args = pgf_read_len(rdr);
|
||||
gu_return_on_exn(rdr->err, gu_null_variant);
|
||||
|
||||
gu_new_flex_variant(PGF_PATT_APP,
|
||||
PgfPattApp,
|
||||
args, n_args,
|
||||
&patt, rdr->opool);
|
||||
papp->ctor = ctor;
|
||||
papp->n_args = n_args;
|
||||
|
||||
for (size_t i = 0; i < papp->n_args; i++) {
|
||||
papp->args[i] = pgf_read_patt(rdr);
|
||||
gu_return_on_exn(rdr->err, gu_null_variant);
|
||||
|
||||
516
src/runtime/c/pgf/scanner.c
Normal file
516
src/runtime/c/pgf/scanner.c
Normal file
@@ -0,0 +1,516 @@
|
||||
#include <pgf/data.h>
|
||||
#include <pgf/expr.h>
|
||||
#include <pgf/linearizer.h>
|
||||
#include <gu/utf8.h>
|
||||
|
||||
PGF_INTERNAL int
|
||||
cmp_string(PgfCohortSpot* spot, GuString tok,
|
||||
bool case_sensitive)
|
||||
{
|
||||
for (;;) {
|
||||
GuUCS c2 = gu_utf8_decode((const uint8_t**) &tok);
|
||||
if (c2 == 0)
|
||||
return 0;
|
||||
|
||||
const uint8_t* p = (uint8_t*) spot->ptr;
|
||||
GuUCS c1 = gu_utf8_decode(&p);
|
||||
if (c1 == 0)
|
||||
return -1;
|
||||
|
||||
if (!case_sensitive) {
|
||||
c1 = gu_ucs_to_lower(c1);
|
||||
c2 = gu_ucs_to_lower(c2);
|
||||
}
|
||||
|
||||
if (c1 != c2)
|
||||
return (c1-c2);
|
||||
|
||||
spot->ptr = (GuString) p;
|
||||
spot->pos++;
|
||||
}
|
||||
}
|
||||
|
||||
PGF_INTERNAL bool
|
||||
skip_space(GuString* psent, size_t* ppos)
|
||||
{
|
||||
const uint8_t* p = (uint8_t*) *psent;
|
||||
if (!gu_ucs_is_space(gu_utf8_decode(&p)))
|
||||
return false;
|
||||
|
||||
*psent = (GuString) p;
|
||||
(*ppos)++;
|
||||
return true;
|
||||
}
|
||||
|
||||
PGF_INTERNAL int
|
||||
pgf_symbols_cmp(PgfCohortSpot* spot,
|
||||
PgfSymbols* syms, size_t* sym_idx,
|
||||
bool case_sensitive)
|
||||
{
|
||||
size_t n_syms = gu_seq_length(syms);
|
||||
while (*sym_idx < n_syms) {
|
||||
PgfSymbol sym = gu_seq_get(syms, PgfSymbol, *sym_idx);
|
||||
|
||||
if (*sym_idx > 0) {
|
||||
if (!skip_space(&spot->ptr,&spot->pos)) {
|
||||
if (*spot->ptr == 0)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (*spot->ptr != 0) {
|
||||
if (!skip_space(&spot->ptr,&spot->pos))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GuVariantInfo inf = gu_variant_open(sym);
|
||||
switch (inf.tag) {
|
||||
case PGF_SYMBOL_CAT:
|
||||
case PGF_SYMBOL_LIT:
|
||||
case PGF_SYMBOL_VAR: {
|
||||
if (*spot->ptr == 0)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
case PGF_SYMBOL_KS: {
|
||||
PgfSymbolKS* pks = inf.data;
|
||||
if (*spot->ptr == 0)
|
||||
return -1;
|
||||
|
||||
int cmp = cmp_string(spot,pks->token, case_sensitive);
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
break;
|
||||
}
|
||||
case PGF_SYMBOL_KP:
|
||||
case PGF_SYMBOL_BIND:
|
||||
case PGF_SYMBOL_NE:
|
||||
case PGF_SYMBOL_SOFT_BIND:
|
||||
case PGF_SYMBOL_SOFT_SPACE:
|
||||
case PGF_SYMBOL_CAPIT:
|
||||
case PGF_SYMBOL_ALL_CAPIT: {
|
||||
return -1;
|
||||
}
|
||||
default:
|
||||
gu_impossible();
|
||||
}
|
||||
|
||||
(*sym_idx)++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pgf_morpho_iter(PgfProductionIdx* idx,
|
||||
PgfMorphoCallback* callback,
|
||||
GuExn* err)
|
||||
{
|
||||
size_t n_entries = gu_buf_length(idx);
|
||||
for (size_t i = 0; i < n_entries; i++) {
|
||||
PgfProductionIdxEntry* entry =
|
||||
gu_buf_index(idx, PgfProductionIdxEntry, i);
|
||||
|
||||
PgfCId lemma = entry->papp->fun->absfun->name;
|
||||
GuString analysis = entry->ccat->cnccat->labels[entry->lin_idx];
|
||||
|
||||
prob_t prob = entry->ccat->cnccat->abscat->prob +
|
||||
entry->papp->fun->absfun->ep.prob;
|
||||
callback->callback(callback,
|
||||
lemma, analysis, prob, err);
|
||||
if (!gu_ok(err))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GuOrder order;
|
||||
bool case_sensitive;
|
||||
} PgfSequenceOrder;
|
||||
|
||||
PGF_INTERNAL bool
|
||||
pgf_is_case_sensitive(PgfConcr* concr)
|
||||
{
|
||||
PgfFlag* flag =
|
||||
gu_seq_binsearch(concr->cflags, pgf_flag_order, PgfFlag, "case_sensitive");
|
||||
if (flag != NULL) {
|
||||
GuVariantInfo inf = gu_variant_open(flag->value);
|
||||
if (inf.tag == PGF_LITERAL_STR) {
|
||||
PgfLiteralStr* lstr = inf.data;
|
||||
if (strcmp(lstr->val, "off") == 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
pgf_sequence_cmp_fn(GuOrder* order, const void* p1, const void* p2)
|
||||
{
|
||||
PgfSequenceOrder* self = gu_container(order, PgfSequenceOrder, order);
|
||||
|
||||
PgfCohortSpot spot = {0, (GuString) p1};
|
||||
|
||||
const PgfSequence* sp2 = p2;
|
||||
|
||||
size_t sym_idx = 0;
|
||||
int res = pgf_symbols_cmp(&spot, sp2->syms, &sym_idx, self->case_sensitive);
|
||||
if (res == 0 && (*spot.ptr != 0 || sym_idx != gu_seq_length(sp2->syms))) {
|
||||
res = 1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
PGF_API void
|
||||
pgf_lookup_morpho(PgfConcr *concr, GuString sentence,
|
||||
PgfMorphoCallback* callback, GuExn* err)
|
||||
{
|
||||
if (concr->sequences == NULL) {
|
||||
GuExnData* err_data = gu_raise(err, PgfExn);
|
||||
if (err_data) {
|
||||
err_data->data = "The concrete syntax is not loaded";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
size_t index = 0;
|
||||
PgfSequenceOrder order = { { pgf_sequence_cmp_fn },
|
||||
pgf_is_case_sensitive(concr) };
|
||||
if (gu_seq_binsearch_index(concr->sequences, &order.order,
|
||||
PgfSequence, (void*) sentence,
|
||||
&index)) {
|
||||
PgfSequence* seq = NULL;
|
||||
|
||||
/* If the match is case-insensitive then there might be more
|
||||
* matches around the current index. We must check the neighbour
|
||||
* sequences for matching as well.
|
||||
*/
|
||||
|
||||
if (!order.case_sensitive) {
|
||||
size_t i = index;
|
||||
while (i > 0) {
|
||||
seq = gu_seq_index(concr->sequences, PgfSequence, i-1);
|
||||
|
||||
size_t sym_idx = 0;
|
||||
PgfCohortSpot spot = {0, sentence};
|
||||
if (pgf_symbols_cmp(&spot, seq->syms, &sym_idx, order.case_sensitive) != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (seq->idx != NULL)
|
||||
pgf_morpho_iter(seq->idx, callback, err);
|
||||
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
seq = gu_seq_index(concr->sequences, PgfSequence, index);
|
||||
if (seq->idx != NULL)
|
||||
pgf_morpho_iter(seq->idx, callback, err);
|
||||
|
||||
if (!order.case_sensitive) {
|
||||
size_t i = index+1;
|
||||
while (i < gu_seq_length(concr->sequences)) {
|
||||
seq = gu_seq_index(concr->sequences, PgfSequence, i);
|
||||
|
||||
size_t sym_idx = 0;
|
||||
PgfCohortSpot spot = {0, sentence};
|
||||
if (pgf_symbols_cmp(&spot, seq->syms, &sym_idx, order.case_sensitive) != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (seq->idx != NULL)
|
||||
pgf_morpho_iter(seq->idx, callback, err);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GuEnum en;
|
||||
PgfConcr* concr;
|
||||
GuString sentence;
|
||||
GuString current;
|
||||
size_t len;
|
||||
PgfMorphoCallback* callback;
|
||||
GuExn* err;
|
||||
bool case_sensitive;
|
||||
GuBuf* spots;
|
||||
GuBuf* found;
|
||||
} PgfCohortsState;
|
||||
|
||||
static int
|
||||
cmp_cohort_spot(GuOrder* self, const void* a, const void* b)
|
||||
{
|
||||
PgfCohortSpot *s1 = (PgfCohortSpot *) a;
|
||||
PgfCohortSpot *s2 = (PgfCohortSpot *) b;
|
||||
|
||||
return (s1->ptr-s2->ptr);
|
||||
}
|
||||
|
||||
static GuOrder
|
||||
pgf_cohort_spot_order[1] = {{ cmp_cohort_spot }};
|
||||
|
||||
static void
|
||||
pgf_lookup_cohorts_helper(PgfCohortsState *state, PgfCohortSpot* spot,
|
||||
int i, int j, ptrdiff_t min, ptrdiff_t max)
|
||||
{
|
||||
// This is a variation of a binary search algorithm which
|
||||
// can retrieve all prefixes of a string with minimal
|
||||
// comparisons, i.e. there is no need to lookup every
|
||||
// prefix separately.
|
||||
|
||||
while (i <= j) {
|
||||
int k = (i+j) / 2;
|
||||
PgfSequence* seq = gu_seq_index(state->concr->sequences, PgfSequence, k);
|
||||
|
||||
PgfCohortSpot current = *spot;
|
||||
|
||||
size_t sym_idx = 0;
|
||||
int cmp = pgf_symbols_cmp(¤t, seq->syms, &sym_idx, state->case_sensitive);
|
||||
if (cmp < 0) {
|
||||
j = k-1;
|
||||
} else if (cmp > 0) {
|
||||
ptrdiff_t len = current.ptr - spot->ptr;
|
||||
|
||||
if (min <= len)
|
||||
pgf_lookup_cohorts_helper(state, spot, i, k-1, min, len);
|
||||
|
||||
if (len+1 <= max)
|
||||
pgf_lookup_cohorts_helper(state, spot, k+1, j, len+1, max);
|
||||
|
||||
break;
|
||||
} else {
|
||||
ptrdiff_t len = current.ptr - spot->ptr;
|
||||
|
||||
if (min <= len)
|
||||
pgf_lookup_cohorts_helper(state, spot, i, k-1, min, len);
|
||||
|
||||
if (seq->idx != NULL && gu_buf_length(seq->idx) > 0) {
|
||||
PgfCohortRange* range = gu_buf_insert(state->found, 0);
|
||||
range->start = *spot;
|
||||
range->end = current;
|
||||
range->buf = seq->idx;
|
||||
}
|
||||
|
||||
while (*current.ptr != 0) {
|
||||
if (!skip_space(¤t.ptr, ¤t.pos))
|
||||
break;
|
||||
}
|
||||
|
||||
gu_buf_heap_push(state->spots, pgf_cohort_spot_order, ¤t);
|
||||
|
||||
if (len <= max)
|
||||
pgf_lookup_cohorts_helper(state, spot, k+1, j, len, max);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pgf_lookup_cohorts_enum_next(GuEnum* self, void* to, GuPool* pool)
|
||||
{
|
||||
PgfCohortsState* state = gu_container(self, PgfCohortsState, en);
|
||||
|
||||
while (gu_buf_length(state->found) == 0 &&
|
||||
gu_buf_length(state->spots) > 0) {
|
||||
PgfCohortSpot spot;
|
||||
gu_buf_heap_pop(state->spots, pgf_cohort_spot_order, &spot);
|
||||
|
||||
if (spot.ptr == state->current)
|
||||
continue;
|
||||
|
||||
if (*spot.ptr == 0)
|
||||
break;
|
||||
|
||||
pgf_lookup_cohorts_helper
|
||||
(state, &spot,
|
||||
0, gu_seq_length(state->concr->sequences)-1,
|
||||
1, (state->sentence+state->len)-spot.ptr);
|
||||
|
||||
if (gu_buf_length(state->found) == 0) {
|
||||
// skip one character and try again
|
||||
gu_utf8_decode((const uint8_t**) &spot.ptr);
|
||||
spot.pos++;
|
||||
gu_buf_heap_push(state->spots, pgf_cohort_spot_order, &spot);
|
||||
}
|
||||
}
|
||||
|
||||
PgfCohortRange* pRes = (PgfCohortRange*)to;
|
||||
|
||||
if (gu_buf_length(state->found) == 0) {
|
||||
pRes->start.pos = 0;
|
||||
pRes->start.ptr = NULL;
|
||||
pRes->end.pos = 0;
|
||||
pRes->end.ptr = NULL;
|
||||
pRes->buf = NULL;
|
||||
state->current = NULL;
|
||||
return;
|
||||
} else do {
|
||||
*pRes = gu_buf_pop(state->found, PgfCohortRange);
|
||||
state->current = pRes->start.ptr;
|
||||
pgf_morpho_iter(pRes->buf, state->callback, state->err);
|
||||
} while (gu_buf_length(state->found) > 0 &&
|
||||
gu_buf_index_last(state->found, PgfCohortRange)->end.ptr == pRes->end.ptr);
|
||||
|
||||
}
|
||||
|
||||
PGF_API GuEnum*
|
||||
pgf_lookup_cohorts(PgfConcr *concr, GuString sentence,
|
||||
PgfMorphoCallback* callback,
|
||||
GuPool* pool, GuExn* err)
|
||||
{
|
||||
if (concr->sequences == NULL) {
|
||||
GuExnData* err_data = gu_raise(err, PgfExn);
|
||||
if (err_data) {
|
||||
err_data->data = "The concrete syntax is not loaded";
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
PgfCohortsState* state = gu_new(PgfCohortsState, pool);
|
||||
state->en.next = pgf_lookup_cohorts_enum_next;
|
||||
state->concr = concr;
|
||||
state->sentence= sentence;
|
||||
state->len = strlen(sentence);
|
||||
state->callback= callback;
|
||||
state->err = err;
|
||||
state->case_sensitive = pgf_is_case_sensitive(concr);
|
||||
state->spots = gu_new_buf(PgfCohortSpot, pool);
|
||||
state->found = gu_new_buf(PgfCohortRange, pool);
|
||||
|
||||
PgfCohortSpot spot = {0,sentence};
|
||||
while (*spot.ptr != 0) {
|
||||
if (!skip_space(&spot.ptr, &spot.pos))
|
||||
break;
|
||||
}
|
||||
|
||||
gu_buf_heap_push(state->spots, pgf_cohort_spot_order, &spot);
|
||||
|
||||
return &state->en;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GuEnum en;
|
||||
PgfSequences* sequences;
|
||||
GuString prefix;
|
||||
size_t seq_idx;
|
||||
bool case_sensitive;
|
||||
} PgfFullFormState;
|
||||
|
||||
struct PgfFullFormEntry {
|
||||
GuString tokens;
|
||||
PgfProductionIdx* idx;
|
||||
};
|
||||
|
||||
static void
|
||||
gu_fullform_enum_next(GuEnum* self, void* to, GuPool* pool)
|
||||
{
|
||||
PgfFullFormState* st = gu_container(self, PgfFullFormState, en);
|
||||
PgfFullFormEntry* entry = NULL;
|
||||
|
||||
if (st->sequences != NULL) {
|
||||
size_t n_seqs = gu_seq_length(st->sequences);
|
||||
while (st->seq_idx < n_seqs) {
|
||||
PgfSequence* seq = gu_seq_index(st->sequences, PgfSequence, st->seq_idx);
|
||||
GuString tokens = pgf_get_tokens(seq->syms, 0, pool);
|
||||
|
||||
PgfCohortSpot spot = {0, st->prefix};
|
||||
if (cmp_string(&spot, tokens, st->case_sensitive) > 0 || *spot.ptr != 0) {
|
||||
st->seq_idx = n_seqs;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*tokens != 0 && seq->idx != NULL) {
|
||||
entry = gu_new(PgfFullFormEntry, pool);
|
||||
entry->tokens = tokens;
|
||||
entry->idx = seq->idx;
|
||||
|
||||
st->seq_idx++;
|
||||
break;
|
||||
}
|
||||
|
||||
st->seq_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
*((PgfFullFormEntry**) to) = entry;
|
||||
}
|
||||
|
||||
PGF_API GuEnum*
|
||||
pgf_fullform_lexicon(PgfConcr *concr, GuPool* pool)
|
||||
{
|
||||
PgfFullFormState* st = gu_new(PgfFullFormState, pool);
|
||||
st->en.next = gu_fullform_enum_next;
|
||||
st->sequences = concr->sequences;
|
||||
st->prefix = "";
|
||||
st->seq_idx = 0;
|
||||
st->case_sensitive = true;
|
||||
return &st->en;
|
||||
}
|
||||
|
||||
PGF_API GuString
|
||||
pgf_fullform_get_string(PgfFullFormEntry* entry)
|
||||
{
|
||||
return entry->tokens;
|
||||
}
|
||||
|
||||
PGF_API void
|
||||
pgf_fullform_get_analyses(PgfFullFormEntry* entry,
|
||||
PgfMorphoCallback* callback, GuExn* err)
|
||||
{
|
||||
pgf_morpho_iter(entry->idx, callback, err);
|
||||
}
|
||||
|
||||
PGF_API GuEnum*
|
||||
pgf_lookup_word_prefix(PgfConcr *concr, GuString prefix,
|
||||
GuPool* pool, GuExn* err)
|
||||
{
|
||||
if (concr->sequences == NULL) {
|
||||
GuExnData* err_data = gu_raise(err, PgfExn);
|
||||
if (err_data) {
|
||||
err_data->data = "The concrete syntax is not loaded";
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
PgfFullFormState* state = gu_new(PgfFullFormState, pool);
|
||||
state->en.next = gu_fullform_enum_next;
|
||||
state->sequences = concr->sequences;
|
||||
state->prefix = prefix;
|
||||
state->seq_idx = 0;
|
||||
state->case_sensitive = pgf_is_case_sensitive(concr);
|
||||
|
||||
PgfSequenceOrder order = { { pgf_sequence_cmp_fn },
|
||||
state->case_sensitive };
|
||||
if (!gu_seq_binsearch_index(concr->sequences, &order.order,
|
||||
PgfSequence, (void*) prefix,
|
||||
&state->seq_idx)) {
|
||||
state->seq_idx++;
|
||||
} else if (!state->case_sensitive) {
|
||||
/* If the match is case-insensitive then there might be more
|
||||
* matches around the current index. Since we scroll down
|
||||
* anyway, it is enough to search upwards now.
|
||||
*/
|
||||
|
||||
while (state->seq_idx > 0) {
|
||||
PgfSequence* seq =
|
||||
gu_seq_index(concr->sequences, PgfSequence, state->seq_idx-1);
|
||||
|
||||
size_t sym_idx = 0;
|
||||
PgfCohortSpot spot = {0, state->prefix};
|
||||
if (pgf_symbols_cmp(&spot, seq->syms, &sym_idx, state->case_sensitive) > 0 || *spot.ptr != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
state->seq_idx--;
|
||||
}
|
||||
}
|
||||
|
||||
return &state->en;
|
||||
}
|
||||
@@ -499,14 +499,17 @@ store_expr(SgSG* sg,
|
||||
PgfExprLit* elit = ei.data;
|
||||
|
||||
Mem mem[2];
|
||||
size_t len = 0;
|
||||
|
||||
GuVariantInfo li = gu_variant_open(elit->lit);
|
||||
switch (li.tag) {
|
||||
case PGF_LITERAL_STR: {
|
||||
PgfLiteralStr* lstr = li.data;
|
||||
|
||||
len = strlen(lstr->val);
|
||||
|
||||
mem[0].flags = MEM_Str;
|
||||
mem[0].n = strlen(lstr->val);
|
||||
mem[0].n = len;
|
||||
mem[0].z = lstr->val;
|
||||
break;
|
||||
}
|
||||
@@ -515,6 +518,7 @@ store_expr(SgSG* sg,
|
||||
|
||||
mem[0].flags = MEM_Int;
|
||||
mem[0].u.i = lint->val;
|
||||
len = sizeof(mem[0].u.i);
|
||||
break;
|
||||
}
|
||||
case PGF_LITERAL_FLT: {
|
||||
@@ -522,6 +526,7 @@ store_expr(SgSG* sg,
|
||||
|
||||
mem[0].flags = MEM_Real;
|
||||
mem[0].u.r = lflt->val;
|
||||
len = sizeof(mem[0].u.r);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -556,7 +561,7 @@ store_expr(SgSG* sg,
|
||||
int serial_type_arg = sqlite3BtreeSerialType(&mem[1], file_format);
|
||||
int serial_type_arg_hdr_len = sqlite3BtreeVarintLen(serial_type_arg);
|
||||
|
||||
unsigned char* buf = malloc(1+serial_type_lit_hdr_len+(serial_type_arg_hdr_len > 1 ? serial_type_arg_hdr_len : 1)+mem[0].n+8);
|
||||
unsigned char* buf = malloc(1+serial_type_lit_hdr_len+(serial_type_arg_hdr_len > 1 ? serial_type_arg_hdr_len : 1)+len+8);
|
||||
unsigned char* p = buf;
|
||||
*p++ = 1+serial_type_lit_hdr_len+serial_type_arg_hdr_len;
|
||||
p += putVarint32(p, serial_type_lit);
|
||||
|
||||
@@ -4835,7 +4835,6 @@ SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void);
|
||||
SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
|
||||
SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
|
||||
|
||||
typedef int (*RecordCompare)(int,const void*,UnpackedRecord*);
|
||||
SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
|
||||
|
||||
/************** End of btreeInt.h ********************************************/
|
||||
|
||||
@@ -70,7 +70,7 @@ module PGF2 (-- * PGF
|
||||
-- ** Generation
|
||||
generateAll,
|
||||
-- ** Morphological Analysis
|
||||
MorphoAnalysis, lookupMorpho, fullFormLexicon,
|
||||
MorphoAnalysis, lookupMorpho, lookupCohorts, fullFormLexicon,
|
||||
-- ** Visualizations
|
||||
GraphvizOptions(..), graphvizDefaults,
|
||||
graphvizAbstractTree, graphvizParseTree, graphvizWordAlignment,
|
||||
@@ -466,8 +466,23 @@ newGraphvizOptions pool opts = do
|
||||
-- Functions using Concr
|
||||
-- Morpho analyses, parsing & linearization
|
||||
|
||||
type MorphoAnalysis = (Fun,Cat,Float)
|
||||
-- | This triple is returned by all functions that deal with
|
||||
-- the grammar's lexicon. Its first element is the name of an abstract
|
||||
-- lexical function which can produce a given word or
|
||||
-- a multiword expression (i.e. this is the lemma).
|
||||
-- After that follows a string which describes
|
||||
-- the particular inflection form.
|
||||
--
|
||||
-- The last element is a logarithm from the
|
||||
-- the probability of the function. The probability is not
|
||||
-- conditionalized on the category of the function. This makes it
|
||||
-- possible to compare the likelihood of two functions even if they
|
||||
-- have different types.
|
||||
type MorphoAnalysis = (Fun,String,Float)
|
||||
|
||||
-- | 'lookupMorpho' takes a string which must be a single word or
|
||||
-- a multiword expression. It then computes the list of all possible
|
||||
-- morphological analyses.
|
||||
lookupMorpho :: Concr -> String -> [MorphoAnalysis]
|
||||
lookupMorpho (Concr concr master) sent =
|
||||
unsafePerformIO $
|
||||
@@ -481,6 +496,45 @@ lookupMorpho (Concr concr master) sent =
|
||||
freeHaskellFunPtr fptr
|
||||
readIORef ref
|
||||
|
||||
-- | 'lookupCohorts' takes an arbitrary string an produces
|
||||
-- a list of all places where lexical items from the grammar have been
|
||||
-- identified (i.e. cohorts). The list consists of triples of the format @(start,ans,end)@,
|
||||
-- where @start-end@ identifies the span in the text and @ans@ is
|
||||
-- the list of possible morphological analyses similar to 'lookupMorpho'.
|
||||
--
|
||||
-- The list is sorted first by the @start@ position and after than
|
||||
-- by the @end@ position. This can be used for instance if you want to
|
||||
-- filter only the longest matches.
|
||||
lookupCohorts :: Concr -> String -> [(Int,[MorphoAnalysis],Int)]
|
||||
lookupCohorts lang@(Concr concr master) sent =
|
||||
unsafePerformIO $
|
||||
do pl <- gu_new_pool
|
||||
ref <- newIORef []
|
||||
cback <- gu_malloc pl (#size PgfMorphoCallback)
|
||||
fptr <- wrapLookupMorphoCallback (getAnalysis ref)
|
||||
(#poke PgfMorphoCallback, callback) cback fptr
|
||||
c_sent <- newUtf8CString sent pl
|
||||
enum <- pgf_lookup_cohorts concr c_sent cback pl nullPtr
|
||||
fpl <- newForeignPtr gu_pool_finalizer pl
|
||||
fromCohortRange enum fpl fptr ref
|
||||
where
|
||||
fromCohortRange enum fpl fptr ref =
|
||||
allocaBytes (#size PgfCohortRange) $ \ptr ->
|
||||
withForeignPtr fpl $ \pl ->
|
||||
do gu_enum_next enum ptr pl
|
||||
buf <- (#peek PgfCohortRange, buf) ptr
|
||||
if buf == nullPtr
|
||||
then do finalizeForeignPtr fpl
|
||||
freeHaskellFunPtr fptr
|
||||
touchConcr lang
|
||||
return []
|
||||
else do start <- (#peek PgfCohortRange, start.pos) ptr
|
||||
end <- (#peek PgfCohortRange, end.pos) ptr
|
||||
ans <- readIORef ref
|
||||
writeIORef ref []
|
||||
cohs <- unsafeInterleaveIO (fromCohortRange enum fpl fptr ref)
|
||||
return ((start,ans,end):cohs)
|
||||
|
||||
fullFormLexicon :: Concr -> [(String, [MorphoAnalysis])]
|
||||
fullFormLexicon lang =
|
||||
unsafePerformIO $
|
||||
@@ -990,11 +1044,13 @@ withBracketLinFuncs ref exn f =
|
||||
|
||||
end_phrase ref _ c_cat c_fid c_lindex c_fun = do
|
||||
(bs':stack,bs) <- readIORef ref
|
||||
cat <- peekUtf8CString c_cat
|
||||
let fid = fromIntegral c_fid
|
||||
let lindex = fromIntegral c_lindex
|
||||
fun <- peekUtf8CString c_fun
|
||||
writeIORef ref (stack, Bracket cat fid lindex fun (reverse bs) : bs')
|
||||
if null bs
|
||||
then writeIORef ref (stack, bs')
|
||||
else do cat <- peekUtf8CString c_cat
|
||||
let fid = fromIntegral c_fid
|
||||
let lindex = fromIntegral c_lindex
|
||||
fun <- peekUtf8CString c_fun
|
||||
writeIORef ref (stack, Bracket cat fid lindex fun (reverse bs) : bs')
|
||||
|
||||
symbol_ne exn _ = do
|
||||
gu_exn_raise exn gu_exn_type_PgfLinNonExist
|
||||
|
||||
@@ -6,7 +6,9 @@ import System.IO.Unsafe(unsafePerformIO)
|
||||
import Foreign hiding (unsafePerformIO)
|
||||
import Foreign.C
|
||||
import Data.IORef
|
||||
import Data.Data
|
||||
import PGF2.FFI
|
||||
import Data.Maybe(fromJust)
|
||||
|
||||
-- | An data type that represents
|
||||
-- identifiers for functions and categories in PGF.
|
||||
@@ -42,6 +44,20 @@ instance Eq Expr where
|
||||
e1_touch >> e2_touch
|
||||
return (res /= 0)
|
||||
|
||||
instance Data Expr where
|
||||
gfoldl f z e = z (fromJust . readExpr) `f` (showExpr [] e)
|
||||
toConstr _ = readExprConstr
|
||||
gunfold k z c = case constrIndex c of
|
||||
1 -> k (z (fromJust . readExpr))
|
||||
_ -> error "gunfold"
|
||||
dataTypeOf _ = exprDataType
|
||||
|
||||
readExprConstr :: Constr
|
||||
readExprConstr = mkConstr exprDataType "(fromJust . readExpr)" [] Prefix
|
||||
|
||||
exprDataType :: DataType
|
||||
exprDataType = mkDataType "PGF2.Expr" [readExprConstr]
|
||||
|
||||
-- | Constructs an expression by lambda abstraction
|
||||
mkAbs :: BindType -> CId -> Expr -> Expr
|
||||
mkAbs bind_type var (Expr body bodyTouch) =
|
||||
|
||||
@@ -100,7 +100,7 @@ foreign import ccall unsafe "gu/string.h gu_string_buf_out"
|
||||
foreign import ccall unsafe "gu/file.h gu_file_in"
|
||||
gu_file_in :: Ptr () -> Ptr GuPool -> IO (Ptr GuIn)
|
||||
|
||||
foreign import ccall unsafe "gu/enum.h gu_enum_next"
|
||||
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"
|
||||
@@ -401,6 +401,9 @@ foreign import ccall "pgf/pgf.h pgf_parse_with_oracle"
|
||||
foreign import ccall "pgf/pgf.h pgf_lookup_morpho"
|
||||
pgf_lookup_morpho :: Ptr PgfConcr -> CString -> Ptr PgfMorphoCallback -> Ptr GuExn -> IO ()
|
||||
|
||||
foreign import ccall "pgf/pgf.h pgf_lookup_cohorts"
|
||||
pgf_lookup_cohorts :: Ptr PgfConcr -> CString -> Ptr PgfMorphoCallback -> Ptr GuPool -> Ptr GuExn -> IO (Ptr GuEnum)
|
||||
|
||||
type LookupMorphoCallback = Ptr PgfMorphoCallback -> CString -> CString -> Float -> Ptr GuExn -> IO ()
|
||||
|
||||
foreign import ccall "wrapper"
|
||||
|
||||
@@ -528,17 +528,17 @@ newAbstr aflags cats funs = unsafePerformIO $ do
|
||||
|
||||
data ConcrInfo = ConcrInfo (Ptr GuSeq) (Ptr GuMap) (Ptr GuMap) (Ptr GuSeq) (Ptr GuSeq) (Ptr GuMap) (Ptr PgfConcr -> Ptr GuPool -> IO ()) CInt
|
||||
|
||||
newConcr :: (?builder :: Builder s) => AbstrInfo ->
|
||||
[(String,Literal)] -> -- ^ Concrete syntax flags
|
||||
[(String,String)] -> -- ^ Printnames
|
||||
[(FId,[FunId])] -> -- ^ Lindefs
|
||||
[(FId,[FunId])] -> -- ^ Linrefs
|
||||
[(FId,[Production])] -> -- ^ Productions
|
||||
[(Fun,[SeqId])] -> -- ^ Concrete functions (must be sorted by Fun)
|
||||
[[Symbol]] -> -- ^ Sequences (must be sorted)
|
||||
[(Cat,FId,FId,[String])] -> -- ^ Concrete categories
|
||||
FId -> -- ^ The total count of the categories
|
||||
ConcrInfo
|
||||
newConcr :: (?builder :: Builder s) => AbstrInfo
|
||||
-> [(String,Literal)] -- ^ Concrete syntax flags
|
||||
-> [(String,String)] -- ^ Printnames
|
||||
-> [(FId,[FunId])] -- ^ Lindefs
|
||||
-> [(FId,[FunId])] -- ^ Linrefs
|
||||
-> [(FId,[Production])] -- ^ Productions
|
||||
-> [(Fun,[SeqId])] -- ^ Concrete functions (must be sorted by Fun)
|
||||
-> [[Symbol]] -- ^ Sequences (must be sorted)
|
||||
-> [(Cat,FId,FId,[String])] -- ^ Concrete categories
|
||||
-> FId -- ^ The total count of the categories
|
||||
-> ConcrInfo
|
||||
newConcr (AbstrInfo _ _ abscats _ absfuns c_abs_lin_fun c_non_lexical_buf _) cflags printnames lindefs linrefs prods cncfuns sequences cnccats total_cats = unsafePerformIO $ do
|
||||
c_cflags <- newFlags cflags pool
|
||||
c_printname <- newMap (#size GuString) gu_string_hasher newUtf8CString
|
||||
|
||||
@@ -100,7 +100,7 @@ hspgf_predict_callback(PgfOracleCallback* self,
|
||||
size_t offset)
|
||||
{
|
||||
HSPgfOracleCallback* oracle = gu_container(self, HSPgfOracleCallback, oracle);
|
||||
oracle->predict(cat,label,hspgf_offset2hs(oracle->sentence, offset));
|
||||
return oracle->predict(cat,label,hspgf_offset2hs(oracle->sentence, offset));
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -110,7 +110,7 @@ hspgf_complete_callback(PgfOracleCallback* self,
|
||||
size_t offset)
|
||||
{
|
||||
HSPgfOracleCallback* oracle = gu_container(self, HSPgfOracleCallback, oracle);
|
||||
oracle->complete(cat,label,hspgf_offset2hs(oracle->sentence, offset));
|
||||
return oracle->complete(cat,label,hspgf_offset2hs(oracle->sentence, offset));
|
||||
}
|
||||
|
||||
static PgfExprProb*
|
||||
|
||||
@@ -58,8 +58,8 @@ bracketedTokn :: Maybe Int -> Forest -> BracketedTokn
|
||||
bracketedTokn dp f@(Forest abs cnc forest root) =
|
||||
case [computeSeq isTrusted seq (map (render forest) args) | (seq,args) <- root] of
|
||||
([bs@(Bracket_{})]:_) -> bs
|
||||
(bss:_) -> Bracket_ wildCId 0 0 wildCId [] bss
|
||||
[] -> Bracket_ wildCId 0 0 wildCId [] []
|
||||
(bss:_) -> Bracket_ wildCId 0 0 0 wildCId [] bss
|
||||
[] -> Bracket_ wildCId 0 0 0 wildCId [] []
|
||||
where
|
||||
isTrusted (_,fid) = IntSet.member fid trusted
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ fromStr = from False id
|
||||
from space cap ts =
|
||||
case ts of
|
||||
[] -> []
|
||||
TK "":ts -> from space cap ts
|
||||
TK s:ts -> put s++from True cap ts
|
||||
BIND:ts -> from False cap ts
|
||||
SOFT_BIND:ts -> from False cap ts
|
||||
|
||||
@@ -138,7 +138,7 @@ cidVar = mkCId "__gfVar"
|
||||
-- mark the beginning and the end of each constituent.
|
||||
data BracketedString
|
||||
= Leaf Token -- ^ this is the leaf i.e. a single token
|
||||
| Bracket CId {-# UNPACK #-} !FId {-# UNPACK #-} !LIndex CId [Expr] [BracketedString]
|
||||
| Bracket CId {-# UNPACK #-} !FId {-# UNPACK #-} !FId {-# UNPACK #-} !LIndex CId [Expr] [BracketedString]
|
||||
-- ^ this is a bracket. The 'CId' is the category of
|
||||
-- the phrase. The 'FId' is an unique identifier for
|
||||
-- every phrase in the sentence. For context-free grammars
|
||||
@@ -152,7 +152,7 @@ data BracketedString
|
||||
-- that represents the same constituent.
|
||||
|
||||
data BracketedTokn
|
||||
= Bracket_ CId {-# UNPACK #-} !FId {-# UNPACK #-} !LIndex CId [Expr] [BracketedTokn] -- Invariant: the list is not empty
|
||||
= Bracket_ CId {-# UNPACK #-} !FId {-# UNPACK #-} !FId {-# UNPACK #-} !LIndex CId [Expr] [BracketedTokn] -- Invariant: the list is not empty
|
||||
| LeafKS Token
|
||||
| LeafNE
|
||||
| LeafBIND
|
||||
@@ -170,12 +170,12 @@ showBracketedString :: BracketedString -> String
|
||||
showBracketedString = render . ppBracketedString
|
||||
|
||||
ppBracketedString (Leaf t) = text t
|
||||
ppBracketedString (Bracket cat fid index _ _ bss) = parens (ppCId cat <> colon <> int fid <+> hsep (map ppBracketedString bss))
|
||||
ppBracketedString (Bracket cat fid fid' index _ _ bss) = parens (ppCId cat <> colon <> int fid <+> hsep (map ppBracketedString bss))
|
||||
|
||||
-- | The length of the bracketed string in number of tokens.
|
||||
lengthBracketedString :: BracketedString -> Int
|
||||
lengthBracketedString (Leaf _) = 1
|
||||
lengthBracketedString (Bracket _ _ _ _ _ bss) = sum (map lengthBracketedString bss)
|
||||
lengthBracketedString (Leaf _) = 1
|
||||
lengthBracketedString (Bracket _ _ _ _ _ _ bss) = sum (map lengthBracketedString bss)
|
||||
|
||||
untokn :: Maybe String -> [BracketedTokn] -> (Maybe String,[BracketedString])
|
||||
untokn nw bss =
|
||||
@@ -184,10 +184,10 @@ untokn nw bss =
|
||||
Just bss -> (nw,concat bss)
|
||||
Nothing -> (nw,[])
|
||||
where
|
||||
untokn nw (Bracket_ cat fid index fun es bss) =
|
||||
untokn nw (Bracket_ cat fid fid' index fun es bss) =
|
||||
let (nw',bss') = mapAccumR untokn nw bss
|
||||
in case sequence bss' of
|
||||
Just bss -> (nw',Just [Bracket cat fid index fun es (concat bss)])
|
||||
Just bss -> (nw',Just [Bracket cat fid fid' index fun es (concat bss)])
|
||||
Nothing -> (Nothing, Nothing)
|
||||
untokn nw (LeafKS t)
|
||||
| null t = (nw,Just [])
|
||||
@@ -228,16 +228,16 @@ computeSeq filter seq args = concatMap compute seq
|
||||
|
||||
getArg d r
|
||||
| not (null arg_lin) &&
|
||||
filter ct = [Bracket_ cat fid r fun es arg_lin]
|
||||
filter ct = [Bracket_ cat fid fid' r fun es arg_lin]
|
||||
| otherwise = arg_lin
|
||||
where
|
||||
arg_lin = lin ! r
|
||||
(ct@(cat,fid),_,fun,es,(_xs,lin)) = args !! d
|
||||
arg_lin = lin ! r
|
||||
(ct@(cat,fid),fid',fun,es,(_xs,lin)) = args !! d
|
||||
|
||||
getVar d r = [LeafKS (showCId (xs !! r))]
|
||||
where
|
||||
(_ct,_,_fun,_es,(xs,_lin)) = args !! d
|
||||
|
||||
flattenBracketedString :: BracketedString -> [String]
|
||||
flattenBracketedString (Leaf w) = [w]
|
||||
flattenBracketedString (Bracket _ _ _ _ _ bss) = concatMap flattenBracketedString bss
|
||||
flattenBracketedString (Leaf w) = [w]
|
||||
flattenBracketedString (Bracket _ _ _ _ _ _ bss) = concatMap flattenBracketedString bss
|
||||
|
||||
@@ -35,9 +35,9 @@ import PGF.Macros (lookValCat, BracketedString(..))
|
||||
|
||||
import qualified Data.Map as Map
|
||||
--import qualified Data.IntMap as IntMap
|
||||
import Data.List (intersperse,nub,mapAccumL,find,groupBy,sortBy)
|
||||
import Data.List (intersperse,nub,mapAccumL,find,groupBy,sortBy,partition)
|
||||
import Data.Ord (comparing)
|
||||
--import Data.Char (isDigit)
|
||||
import Data.Char (isDigit)
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Text.PrettyPrint
|
||||
|
||||
@@ -133,6 +133,7 @@ graphvizDependencyTree format debug mlab mclab pgf lang t =
|
||||
"latex" -> render . ppLaTeX $ conll2latex' conll
|
||||
"svg" -> render . ppSVG . toSVG $ conll2latex' conll
|
||||
"conll" -> printCoNLL conll
|
||||
"conllu" -> printCoNLL ([["# text = " ++ linearize pgf lang t], ["# tree = " ++ showExpr [] t]] ++ conll)
|
||||
"malt_tab" -> render $ vcat (map (hcat . intersperse (char '\t') . (\ws -> [ws !! 0,ws !! 1,ws !! 3,ws !! 6,ws !! 7])) wnodes)
|
||||
"malt_input" -> render $ vcat (map (hcat . intersperse (char '\t') . take 6) wnodes)
|
||||
_ -> render $ text "digraph {" $$
|
||||
@@ -146,16 +147,16 @@ graphvizDependencyTree format debug mlab mclab pgf lang t =
|
||||
conll = maybe conll0 (\ls -> fixCoNLL ls conll0) mclab
|
||||
conll0 = (map.map) render wnodes
|
||||
nodes = map mkNode leaves
|
||||
links = map mkLink [(fid, fromMaybe (dep_lbl,nil) (lookup fid deps)) | ((cat,fid,fun),_,w) <- tail leaves]
|
||||
links = map mkLink [(fid, fromMaybe (dep_lbl,nil) (lookup fid deps)) | ((cat,fid,fun,_),_,w) <- tail leaves]
|
||||
|
||||
-- CoNLL format: ID FORM LEMMA PLEMMA POS PPOS FEAT PFEAT HEAD PHEAD DEPREL PDEPREL
|
||||
-- P variants are automatically predicted rather than gold standard
|
||||
|
||||
wnodes = [[int i, maltws ws, ppCId fun, ppCId (posCat cat), ppCId cat, unspec, int parent, text lab, unspec, unspec] |
|
||||
((cat,fid,fun),i,ws) <- tail leaves,
|
||||
wnodes = [[int i, maltws ws, ppCId fun, ppCId (posCat cat), ppCId cat, int lind, int parent, text lab, unspec, unspec] |
|
||||
((cat,fid,fun,lind),i,ws) <- tail leaves,
|
||||
let (lab,parent) = fromMaybe (dep_lbl,0)
|
||||
(do (lbl,fid) <- lookup fid deps
|
||||
(_,i,_) <- find (\((_,fid1,_),i,_) -> fid == fid1) leaves
|
||||
(_,i,_) <- find (\((_,fid1,_,_),i,_) -> fid == fid1) leaves
|
||||
return (lbl,i))
|
||||
]
|
||||
maltws = text . concat . intersperse "+" . words -- no spaces in column 2
|
||||
@@ -164,7 +165,7 @@ graphvizDependencyTree format debug mlab mclab pgf lang t =
|
||||
|
||||
bss = bracketedLinearize pgf lang t
|
||||
|
||||
root = (wildCId,nil,wildCId)
|
||||
root = (wildCId,nil,wildCId,0)
|
||||
|
||||
leaves = (root,0,root_lbl) : (groupAndIndexIt 1 . concatMap (getLeaves root)) bss
|
||||
deps = let (_,(h,deps)) = getDeps 0 [] t []
|
||||
@@ -182,10 +183,10 @@ graphvizDependencyTree format debug mlab mclab pgf lang t =
|
||||
|
||||
getLeaves parent bs =
|
||||
case bs of
|
||||
Leaf w -> [(parent,w)]
|
||||
Bracket cat fid _ fun _ bss -> concatMap (getLeaves (cat,fid,fun)) bss
|
||||
Leaf w -> [(parent,w)]
|
||||
Bracket cat fid _ lind fun _ bss -> concatMap (getLeaves (cat,fid,fun,lind)) bss
|
||||
|
||||
mkNode ((_,p,_),i,w) =
|
||||
mkNode ((_,p,_,_),i,w) =
|
||||
tag p <+> brackets (text "label = " <> doubleQuotes (int i <> char '.' <+> text w)) <+> semi
|
||||
|
||||
mkLink (x,(lbl,y)) = tag y <+> text "->" <+> tag x <+> text "[label = " <> doubleQuotes (text lbl) <> text "] ;"
|
||||
@@ -236,10 +237,18 @@ graphvizDependencyTree format debug mlab mclab pgf lang t =
|
||||
root_lbl = "ROOT"
|
||||
unspec = text "_"
|
||||
|
||||
-- auxiliaries for UD conversion PK 15/12/2018
|
||||
rmcomments :: String -> String
|
||||
rmcomments [] = []
|
||||
rmcomments ('-':'-':xs) = []
|
||||
rmcomments ('-':x :xs) = '-':rmcomments (x:xs)
|
||||
rmcomments (x:xs) = x:rmcomments xs
|
||||
|
||||
-- | Prepare lines obtained from a configuration file for labels for
|
||||
-- use with 'graphvizDependencyTree'. Format per line /fun/ /label/@*@.
|
||||
getDepLabels :: String -> Labels
|
||||
getDepLabels s = Map.fromList [(mkCId f,ls) | f:ls <- map words (lines s)]
|
||||
-- getDepLabels s = Map.fromList [(mkCId f,ls) | f:ls <- map words (lines s)]
|
||||
getDepLabels s = Map.fromList [(mkCId f,ls) | f:ls <- map (words . rmcomments) (lines s)]
|
||||
|
||||
-- the old function, without dependencies
|
||||
graphvizParseTree :: PGF -> Language -> GraphvizOptions -> Tree -> String
|
||||
@@ -293,13 +302,13 @@ graphvizBracketedString opts mbl tree bss = render graphviz_code
|
||||
getInternals [] = []
|
||||
getInternals nodes
|
||||
= nub [(parent, fid, mkNode fun cat) |
|
||||
(parent, Bracket cat fid _ fun _ _) <- nodes]
|
||||
(parent, Bracket cat fid _ _ fun _ _) <- nodes]
|
||||
: getInternals [(fid, child) |
|
||||
(_, Bracket _ fid _ _ _ children) <- nodes,
|
||||
(_, Bracket _ fid _ _ _ _ children) <- nodes,
|
||||
child <- children]
|
||||
|
||||
getLeaves cat parent (Leaf word) = [(parent, (cat, word))] -- the lowest cat before the word
|
||||
getLeaves _ parent (Bracket cat fid i _ _ children)
|
||||
getLeaves _ parent (Bracket cat fid _ i _ _ children)
|
||||
= concatMap (getLeaves cat fid) children
|
||||
|
||||
mkLevel nodes
|
||||
@@ -403,8 +412,8 @@ genPreAlignment pgf langs = lin2align . linsBracketed
|
||||
|
||||
getLeaves parent bs =
|
||||
case bs of
|
||||
Leaf w -> [(parent,w)]
|
||||
Bracket _ fid _ _ _ bss -> concatMap (getLeaves fid) bss
|
||||
Leaf w -> [(parent,w)]
|
||||
Bracket _ fid _ _ _ _ bss -> concatMap (getLeaves fid) bss
|
||||
|
||||
mkLayers (cs:css:rest) = let (lrest, rrest) = mkLayers (css:rest)
|
||||
in ((fields cs) : lrest, (map (mkLinks css) cs) : rrest)
|
||||
@@ -514,7 +523,7 @@ conll2latex' = dep2latex . conll2dep'
|
||||
|
||||
data Dep = Dep {
|
||||
wordLength :: Int -> Double -- length of word at position int -- was: fixed width, millimetres (>= 20.0)
|
||||
, tokens :: [(String,String)] -- word, pos (0..)
|
||||
, tokens :: [(String,(String,String))] -- word, (pos,features) (0..)
|
||||
, deps :: [((Int,Int),String)] -- from, to, label
|
||||
, root :: Int -- root word position
|
||||
}
|
||||
@@ -554,7 +563,8 @@ dep2latex d =
|
||||
[Comment (unwords (map fst (tokens d))),
|
||||
Picture defaultUnit (width,height) (
|
||||
[Put (wpos rwld i,0) (Text w) | (i,w) <- zip [0..] (map fst (tokens d))] -- words
|
||||
++ [Put (wpos rwld i,15) (TinyText w) | (i,w) <- zip [0..] (map snd (tokens d))] -- pos tags 15u above bottom
|
||||
++ [Put (wpos rwld i,15) (TinyText w) | (i,(w,_)) <- zip [0..] (map snd (tokens d))] -- pos tags 15u above bottom
|
||||
--- ++ [Put (wpos rwld i,-15) (TinyText w) | (i,(_,w)) <- zip [0..] (map snd (tokens d))] -- features 15u below bottom -> DON'T SHOW
|
||||
++ concat [putArc rwld (aheight x y) x y label | ((x,y),label) <- deps d] -- arcs and labels
|
||||
++ [Put (wpos rwld (root d) + 15,height) (ArrowDown (height-arcbase))]
|
||||
++ [Put (wpos rwld (root d) + 20,height - 10) (TinyText "ROOT")]
|
||||
@@ -585,8 +595,8 @@ conll2dep' ls = Dep {
|
||||
, root = head $ [read x-1 | x:_:_:_:_:_:"0":_ <- ls] ++ [1]
|
||||
}
|
||||
where
|
||||
wld i = maximum (0:[charWidth * fromIntegral (length w) | w <- let (tok,pos) = toks !! i in [tok,pos]])
|
||||
toks = [(w,c) | _:w:_:c:_ <- ls]
|
||||
wld i = maximum (0:[charWidth * fromIntegral (length w) | w <- let (tok,(pos,feat)) = toks !! i in [tok,pos {-,feat-}]]) --- feat not shown
|
||||
toks = [(w,(c,m)) | _:w:_:c:_:m:_ <- ls]
|
||||
dps = [((read y-1, read x-1),lab) | x:_:_:_:_:_:y:lab:_ <- ls, y /="0"]
|
||||
--maxdist = maximum [abs (x-y) | ((x,y),_) <- dps]
|
||||
|
||||
@@ -751,18 +761,26 @@ ppSVG svg =
|
||||
-- UseComp {"not"} PART neg head
|
||||
-- UseComp {*} AUX cop head
|
||||
|
||||
type CncLabels = [(String, String -> Maybe (String -> String,String,String))]
|
||||
-- (fun, word -> (pos,label,target))
|
||||
-- the pos can remain unchanged, as in the current notation in the article
|
||||
type CncLabels = [
|
||||
Either
|
||||
(String, String -> Maybe (String -> String,String,String))
|
||||
-- (fun, word -> (pos,label,target))
|
||||
-- the pos can remain unchanged, as in the current notation in the article
|
||||
(String,[String])
|
||||
-- (category, morphological forms)
|
||||
]
|
||||
|
||||
fixCoNLL :: CncLabels -> CoNLL -> CoNLL
|
||||
fixCoNLL labels conll = map fixc conll where
|
||||
fixCoNLL cncLabels conll = map fixc conll where
|
||||
labels = [l | Left l <- cncLabels]
|
||||
flabels = [r | Right r <- cncLabels]
|
||||
|
||||
fixc row = case row of
|
||||
(i:word:fun:pos:cat:x_:"0":"dep":xs) -> (i:word:fun:pos:cat:x_:"0":"root":xs) --- change the root label from dep to root
|
||||
(i:word:fun:pos:cat:x_:"0":"dep":xs) -> (i:word:fun:pos:cat:(feat cat word x_):"0":"root":xs) --- change the root label from dep to root
|
||||
(i:word:fun:pos:cat:x_:j:label:xs) -> case look (fun,word) of
|
||||
Just (pos',label',"head") -> (i:word:fun:pos' pos:cat:x_:j :label':xs)
|
||||
Just (pos',label',target) -> (i:word:fun:pos' pos:cat:x_: getDep j target:label':xs)
|
||||
_ -> row
|
||||
Just (pos',label',"head") -> (i:word:fun:pos' pos:cat:(feat cat word x_):j :label':xs)
|
||||
Just (pos',label',target) -> (i:word:fun:pos' pos:cat:(feat cat word x_): getDep j target:label':xs)
|
||||
_ -> (i:word:fun:pos:cat:(feat cat word x_):j:label:xs)
|
||||
_ -> row
|
||||
|
||||
look (fun,word) = case lookup fun labels of
|
||||
@@ -777,18 +795,43 @@ fixCoNLL labels conll = map fixc conll where
|
||||
|
||||
getDep j label = maybe j id $ lookup (label,j) [((label,j),i) | i:word:fun:pos:cat:x_:j:label:xs <- conll]
|
||||
|
||||
feat cat word x = case lookup cat flabels of
|
||||
Just tags | all isDigit x && length tags > read x -> tags !! read x
|
||||
_ -> case lookup (show word) flabels of
|
||||
Just (t:_) -> t
|
||||
_ -> cat ++ "-" ++ x
|
||||
|
||||
getCncDepLabels :: String -> CncLabels
|
||||
getCncDepLabels =
|
||||
map merge .
|
||||
groupBy (\ (x,_) (a,_) -> x == a) .
|
||||
sortBy (comparing fst) .
|
||||
concatMap analyse .
|
||||
filter choose .
|
||||
lines
|
||||
getCncDepLabels s = wlabels ws ++ flabels fs
|
||||
where
|
||||
wlabels =
|
||||
map Left .
|
||||
map merge .
|
||||
groupBy (\ (x,_) (a,_) -> x == a) .
|
||||
sortBy (comparing fst) .
|
||||
concatMap analyse .
|
||||
filter chooseW
|
||||
|
||||
flabels =
|
||||
map Right .
|
||||
map collectTags .
|
||||
map words
|
||||
|
||||
(fs,ws) = partition chooseF $ map uncomment $ lines s
|
||||
|
||||
--- choose is for compatibility with the general notation
|
||||
choose line = notElem '(' line && elem '{' line --- ignoring non-local (with "(") and abstract (without "{") rules
|
||||
|
||||
chooseW line = notElem '(' line &&
|
||||
elem '{' line
|
||||
--- ignoring non-local (with "(") and abstract (without "{") rules
|
||||
---- TODO: this means that "(" cannot be a token
|
||||
|
||||
chooseF line = take 1 line == "@" --- feature assignments have the form e.g. @N SgNom SgGen ; no spaces inside tags
|
||||
|
||||
uncomment line = case line of
|
||||
'-':'-':_ -> ""
|
||||
c:cs -> c : uncomment cs
|
||||
_ -> line
|
||||
|
||||
analyse line = case break (=='{') line of
|
||||
(beg,_:ws) -> case break (=='}') ws of
|
||||
(toks,_:target) -> case (getToks beg, words target) of
|
||||
@@ -804,8 +847,11 @@ getCncDepLabels =
|
||||
)
|
||||
getToks = map unquote . filter (/=",") . toks
|
||||
toks s = case lex s of [(t,"")] -> [t] ; [(t,cc)] -> t:toks cc ; _ -> []
|
||||
unquote s = case s of '"':cc@(_:_) | last cc == '"' -> init cc ; _ -> s
|
||||
unquote s = case s of '"':cc@(_:_) | last cc == '"' -> init cc ; _ -> s
|
||||
|
||||
collectTags (w:ws) = (tail w,ws)
|
||||
|
||||
-- added init to remove the last \n. otherwise, two empty lines are in between each sentence PK 17/12/2018
|
||||
printCoNLL :: CoNLL -> String
|
||||
printCoNLL = unlines . map (concat . intersperse "\t")
|
||||
printCoNLL = init . unlines . map (concat . intersperse "\t")
|
||||
|
||||
|
||||
@@ -1,29 +1,37 @@
|
||||
INSTALL_PATH = /usr/local
|
||||
|
||||
C_SOURCES = jpgf.c jsg.c jni_utils.c
|
||||
JAVA_SOURCES = $(wildcard org/grammaticalframework/pgf/*.java) \
|
||||
$(wildcard org/grammaticalframework/sg/*.java)
|
||||
|
||||
JNI_INCLUDES = $(if $(wildcard /usr/lib/jvm/default-java/include/.*), -I/usr/lib/jvm/default-java/include -I/usr/lib/jvm/default-java/include/linux, \
|
||||
$(if $(wildcard /System/Library/Frameworks/JavaVM.framework/Versions/A/Headers/.*), -I/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers, \
|
||||
$(if $(wildcard /Library/Java/Home/include/.*), -I/Library/Java/Home/include/ -I/Library/Java/Home/include/darwin, \
|
||||
$(error No JNI headers found))))
|
||||
$(if $(wildcard /usr/lib/jvm/java-1.11.0-openjdk-amd64/include/.*), -I/usr/lib/jvm/java-1.11.0-openjdk-amd64/include/ -I/usr/lib/jvm/java-1.11.0-openjdk-amd64/include/linux, \
|
||||
$(if $(wildcard /System/Library/Frameworks/JavaVM.framework/Versions/A/Headers/.*), -I/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers, \
|
||||
$(if $(wildcard /Library/Java/Home/include/.*), -I/Library/Java/Home/include/ -I/Library/Java/Home/include/darwin, \
|
||||
$(error No JNI headers found)))))
|
||||
|
||||
# For Windows replace the previous line with something like this:
|
||||
# For compilation on Windows replace the previous line with something like this:
|
||||
#
|
||||
# JNI_INCLUDES = -I "C:/Program Files/Java/jdk1.8.0_171/include" -I "C:/Program Files/Java/jdk1.8.0_171/include/win32" -I "C:/MinGW/msys/1.0/local/include"
|
||||
# WINDOWS_FLAGS = -L"C:/MinGW/msys/1.0/local/lib" -no-undefined
|
||||
# WINDOWS_LDFLAGS = -L"C:/MinGW/msys/1.0/local/lib" -no-undefined
|
||||
|
||||
INSTALL_PATH = /usr/local/lib
|
||||
LIBTOOL = glibtool --tag=CC
|
||||
GCC = gcc
|
||||
LIBTOOL = $(if $(shell command -v glibtool 2>/dev/null), glibtool, libtool) --tag=CC
|
||||
|
||||
LIBTOOL = $(if $(shell command -v glibtool 2>/dev/null), glibtool --tag=CC, libtool)
|
||||
# For cross-compilation from Linux to Windows replace the previous two lines with:
|
||||
#
|
||||
# GCC = x86_64-w64-mingw32-gcc
|
||||
# LIBTOOL = ../c/libtool
|
||||
# WINDOWS_CCFLAGS = -I$(INSTALL_PATH)/include
|
||||
# WINDOWS_LDFLAGS = -L$(INSTALL_PATH)/lib -no-undefined
|
||||
|
||||
all: libjpgf.la jpgf.jar
|
||||
|
||||
libjpgf.la: $(patsubst %.c, %.lo, $(C_SOURCES))
|
||||
$(LIBTOOL) --mode=link gcc $(CFLAGS) -g -O -o libjpgf.la -shared $^ -rpath $(INSTALL_PATH) -lgu -lpgf -lsg $(WINDOWS_FLAGS)
|
||||
$(LIBTOOL) --mode=link $(GCC) $(CFLAGS) -g -O -o libjpgf.la -shared $^ -rpath $(INSTALL_PATH)/lib -lgu -lpgf -lsg $(WINDOWS_LDFLAGS)
|
||||
|
||||
%.lo : %.c
|
||||
$(LIBTOOL) --mode=compile gcc $(CFLAGS) -g -O -c $(JNI_INCLUDES) -std=c99 -shared $< -o $@
|
||||
$(LIBTOOL) --mode=compile $(GCC) $(CFLAGS) -g -O -c $(JNI_INCLUDES) $(WINDOWS_CCFLAGS) -std=c99 -shared $< -o $@
|
||||
|
||||
jpgf.jar: $(patsubst %.java, %.class, $(JAVA_SOURCES))
|
||||
jar -cf $@ org/grammaticalframework/pgf/*.class org/grammaticalframework/sg/*.class
|
||||
@@ -32,8 +40,8 @@ jpgf.jar: $(patsubst %.java, %.class, $(JAVA_SOURCES))
|
||||
javac $<
|
||||
|
||||
install: libjpgf.la jpgf.jar
|
||||
$(LIBTOOL) --mode=install install -s libjpgf.la $(INSTALL_PATH)
|
||||
install jpgf.jar $(INSTALL_PATH)
|
||||
$(LIBTOOL) --mode=install install -s libjpgf.la $(INSTALL_PATH)/lib
|
||||
install jpgf.jar $(INSTALL_PATH)/lib
|
||||
|
||||
|
||||
doc:
|
||||
|
||||
3
src/runtime/javascript/.gitignore
vendored
Normal file
3
src/runtime/javascript/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
build
|
||||
node_modules
|
||||
*.log
|
||||
25
src/runtime/javascript/README.md
Normal file
25
src/runtime/javascript/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# JavaScript bindings to the C runtime
|
||||
|
||||
A Node.js package for accessing the C runtime.
|
||||
|
||||
## Dev notes
|
||||
|
||||
- Assumes runtime is already installed on system (does not compile itself)
|
||||
- ~~`npm install`~~ `npm run build` will create `./build/Release/native.node` (see `binding.gyp > target_name`
|
||||
- not sure if `--napi-modules` flag is necessary when running node
|
||||
- test with: `npm run build && node index.js`
|
||||
|
||||
### Resources
|
||||
|
||||
https://medium.com/@tarkus/how-to-call-c-c-code-from-node-js-86a773033892
|
||||
https://medium.com/@atulanand94/beginners-guide-to-writing-nodejs-addons-using-c-and-n-api-node-addon-api-9b3b718a9a7f
|
||||
|
||||
---
|
||||
|
||||
**What about the pure JS runtime?**
|
||||
|
||||
As of June 2019, the JavaScript version of the GF runtime
|
||||
has been replaced by a TypeScript version at: <https://github.com/GrammaticalFramework/gf-typescript>
|
||||
|
||||
This folder previously contained an example web application using the old JavaScript runtime,
|
||||
which you can access [here](https://github.com/GrammaticalFramework/gf-core/tree/12079550f847a9f98eb0e1eca2fd0ea3d986a94a/src/runtime/javascript).
|
||||
28
src/runtime/javascript/binding.cpp
Normal file
28
src/runtime/javascript/binding.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <napi.h>
|
||||
|
||||
// #include <pgf/pgf.h>
|
||||
// #include <gu/file.h>
|
||||
// #include <gu/variant.h>
|
||||
// #include <gu/map.h>
|
||||
// #include <gu/enum.h>
|
||||
// #include <gu/exn.h>
|
||||
// #include <pgf/literals.h>
|
||||
// #include <pgf/linearizer.h>
|
||||
|
||||
Napi::Value readPGF(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
if (info.Length() < 1) {
|
||||
Napi::TypeError::New(env, "Wrong number of arguments").ThrowAsJavaScriptException();
|
||||
return env.Null();
|
||||
}
|
||||
|
||||
return info[0].As<Napi::String>();
|
||||
}
|
||||
|
||||
Napi::Object initAll(Napi::Env env, Napi::Object exports) {
|
||||
exports.Set("readPGF", Napi::Function::New(env, readPGF));
|
||||
return exports;
|
||||
}
|
||||
|
||||
NODE_API_MODULE(pgf, initAll)
|
||||
22
src/runtime/javascript/binding.gyp
Normal file
22
src/runtime/javascript/binding.gyp
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "pgf",
|
||||
"sources": [
|
||||
"binding.cpp"
|
||||
],
|
||||
"include_dirs": [
|
||||
"<!@(node -p \"require('node-addon-api').include\")"
|
||||
],
|
||||
"dependencies": [
|
||||
"<!(node -p \"require('node-addon-api').gyp\")"
|
||||
],
|
||||
"libraries": [
|
||||
"/usr/local/lib/libpgf.dylib"
|
||||
],
|
||||
"cflags!": ["-fno-exceptions"],
|
||||
"cflags_cc!": ["-fno-exceptions"],
|
||||
"defines": ["NAPI_DISABLE_CPP_EXCEPTIONS"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
abstract Editor = {
|
||||
|
||||
cat Adjective ;
|
||||
Noun ;
|
||||
Verb ;
|
||||
Determiner ;
|
||||
Sentence ;
|
||||
|
||||
fun Available : Adjective ;
|
||||
Next : Adjective ;
|
||||
Previous : Adjective ;
|
||||
|
||||
fun Bulgarian : Noun ;
|
||||
Danish : Noun ;
|
||||
English : Noun ;
|
||||
Finnish : Noun ;
|
||||
French : Noun ;
|
||||
German : Noun ;
|
||||
Italian : Noun ;
|
||||
Norwegian : Noun ;
|
||||
Russian : Noun ;
|
||||
Spanish : Noun ;
|
||||
Swedish : Noun ;
|
||||
|
||||
fun Float_N : Noun ;
|
||||
Integer_N : Noun ;
|
||||
String_N : Noun ;
|
||||
|
||||
Language : Noun ;
|
||||
Node : Noun ;
|
||||
Page : Noun ;
|
||||
Refinement : Noun ;
|
||||
Tree : Noun ;
|
||||
Wrapper : Noun ;
|
||||
|
||||
fun Copy : Verb ;
|
||||
Cut : Verb ;
|
||||
Delete : Verb ;
|
||||
Enter : Verb ;
|
||||
Parse : Verb ;
|
||||
Paste : Verb ;
|
||||
Redo : Verb ;
|
||||
Refine : Verb ;
|
||||
Replace : Verb ;
|
||||
Select : Verb ;
|
||||
Show : Verb ;
|
||||
Undo : Verb ;
|
||||
Wrap : Verb ;
|
||||
|
||||
fun DefPlDet : Determiner ;
|
||||
DefSgDet : Determiner ;
|
||||
IndefPlDet : Determiner ;
|
||||
IndefSgDet : Determiner ;
|
||||
|
||||
fun Command : Verb -> Determiner -> Noun -> Sentence ;
|
||||
CommandAdj : Verb -> Determiner -> Adjective -> Noun -> Sentence ;
|
||||
ErrorMessage : Adjective -> Noun -> Sentence ;
|
||||
Label : Noun -> Sentence ;
|
||||
RandomlyCommand : Verb -> Determiner -> Noun -> Sentence ;
|
||||
SingleWordCommand : Verb -> Sentence ;
|
||||
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
--# -path=alltenses
|
||||
concrete EditorEng of Editor = open GrammarEng, ParadigmsEng in {
|
||||
|
||||
lincat Adjective = A ;
|
||||
Noun = N ;
|
||||
Verb = V ;
|
||||
Determiner = Det ;
|
||||
Sentence = Utt ;
|
||||
|
||||
lin Available = mkA "available" ;
|
||||
Next = mkA "next" ;
|
||||
Previous = mkA "previous" ;
|
||||
|
||||
lin Bulgarian = mkN "Bulgarian" ;
|
||||
Danish = mkN "Danish" ;
|
||||
English = mkN "English" ;
|
||||
Finnish = mkN "Finnish" ;
|
||||
French = mkN "French" ;
|
||||
German = mkN "German" ;
|
||||
Italian = mkN "Italian" ;
|
||||
Norwegian = mkN "Norwegian" ;
|
||||
Russian = mkN "Russian" ;
|
||||
Spanish = mkN "Spanish" ;
|
||||
Swedish = mkN "Swedish" ;
|
||||
|
||||
lin Float_N = mkN "float" ;
|
||||
Integer_N = mkN "integer" ;
|
||||
String_N = mkN "string" ;
|
||||
|
||||
Language = mkN "language" ;
|
||||
Node = mkN "node" ;
|
||||
Page = mkN "page" ;
|
||||
Refinement = mkN "refinement" ;
|
||||
Tree = mkN "tree" ;
|
||||
Wrapper = mkN "wrapper" ;
|
||||
|
||||
lin Copy = mkV "copy" ;
|
||||
Cut = mkV "cut" ;
|
||||
Delete = mkV "delete" ;
|
||||
Enter = mkV "enter" ;
|
||||
Parse = mkV "parse" ;
|
||||
Paste = mkV "paste" ;
|
||||
Redo = mkV "redo" ;
|
||||
Refine = mkV "refine" ;
|
||||
Replace = mkV "replace" ;
|
||||
Select = mkV "select" ;
|
||||
Show = mkV "show" ;
|
||||
Undo = mkV "undo" ;
|
||||
Wrap = mkV "wrap" ;
|
||||
|
||||
lin DefPlDet = DetQuant DefArt NumPl ;
|
||||
DefSgDet = DetQuant DefArt NumSg ;
|
||||
IndefPlDet = DetQuant IndefArt NumPl ;
|
||||
IndefSgDet = DetQuant IndefArt NumSg ;
|
||||
|
||||
lin Command v d n = UttImpSg PPos (ImpVP (ComplSlash (SlashV2a (mkV2 v)) (DetCN d (UseN n)))) ;
|
||||
CommandAdj v d a n = UttImpSg PPos (ImpVP (ComplSlash (SlashV2a (mkV2 v)) (DetCN d (AdjCN (PositA a) (UseN n))))) ;
|
||||
ErrorMessage a n = UttNP (DetCN (DetQuant no_Quant NumPl) (AdjCN (PositA a) (UseN n))) ;
|
||||
Label n = UttNP (MassNP (UseN n)) ;
|
||||
RandomlyCommand v d n = UttImpSg PPos (ImpVP (AdvVP (ComplSlash (SlashV2a (mkV2 v)) (DetCN d (UseN n))) (PrepNP (mkPrep "at") (MassNP (UseN (mkN "random")))))) ;
|
||||
SingleWordCommand v = UttImpSg PPos (ImpVP (UseV v)) ;
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
<script type="text/javascript" src="gflib.js"></script>
|
||||
<script type="text/javascript" src="editorGrammar.js"></script>
|
||||
<script type="text/javascript" src="grammar.js"></script>
|
||||
<script type="text/javascript" src="gfjseditor.js"></script>
|
||||
<title>Web-based Syntax Editor</title>
|
||||
</head>
|
||||
<body onload="mkEditor('editor', Foods)" onkeydown="return hotKeys(event)">
|
||||
<div id="editor">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 161 B |
File diff suppressed because it is too large
Load Diff
@@ -1,54 +0,0 @@
|
||||
/* Output */
|
||||
|
||||
function sayText(text) {
|
||||
document.voice_output_text = text;
|
||||
activateForm("voice_output");
|
||||
}
|
||||
|
||||
/* XHTML+Voice Utilities */
|
||||
|
||||
function activateForm(formid) {
|
||||
var form = document.getElementById(formid);
|
||||
var e = document.createEvent("UIEvents");
|
||||
e.initEvent("DOMActivate","true","true");
|
||||
form.dispatchEvent(e);
|
||||
}
|
||||
|
||||
|
||||
/* DOM utilities */
|
||||
|
||||
/* Gets the head element of the document. */
|
||||
function getHeadElement() {
|
||||
var hs = document.getElementsByTagName("head");
|
||||
if (hs.length == 0) {
|
||||
var head = document.createElement("head");
|
||||
document.documentElement.insertBefore(head, document.documentElement.firstChild);
|
||||
return head;
|
||||
} else {
|
||||
return hs[0];
|
||||
}
|
||||
}
|
||||
|
||||
/* Gets the body element of the document. */
|
||||
function getBodyElement() {
|
||||
var bs = document.getElementsByTagName("body");
|
||||
if (bs.length == 0) {
|
||||
var body = document.createElement("body");
|
||||
document.documentElement.appendChild(body);
|
||||
return body;
|
||||
} else {
|
||||
return bs[0];
|
||||
}
|
||||
}
|
||||
|
||||
/* Removes all the children of a node */
|
||||
function removeChildren(node) {
|
||||
while (node.hasChildNodes()) {
|
||||
node.removeChild(node.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
function setText(node, text) {
|
||||
removeChildren(node);
|
||||
node.appendChild(document.createTextNode(text));
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
||||
var Foods = new GFGrammar(new GFAbstract("Phrase",{Boring: new Type([], "Quality"), Cheese: new Type([], "Kind"), Delicious: new Type([], "Quality"), Expensive: new Type([], "Quality"), Fish: new Type([], "Kind"), Fresh: new Type([], "Quality"), Is: new Type(["Item", "Quality"], "Phrase"), Italian: new Type([], "Quality"), Pizza: new Type([], "Kind"), QKind: new Type(["Quality", "Kind"], "Kind"), That: new Type(["Kind"], "Item"), These: new Type(["Kind"], "Item"), This: new Type(["Kind"], "Item"), Those: new Type(["Kind"], "Item"), Very: new Type(["Quality"], "Quality"), Warm: new Type([], "Quality"), Wine: new Type([], "Kind")}),{FoodsEng: new GFConcrete({},{0:[new Apply(15,[new PArg(2)]), new Apply(17,[new PArg(2)])], 1:[new Apply(16,[new PArg(2)]), new Apply(18,[new PArg(2)])], 2:[new Apply(5,[]), new Apply(8,[]), new Apply(13,[]), new Apply(14,[new PArg(4), new PArg(2)]), new Apply(21,[])], 3:[new Apply(10,[new PArg(0), new PArg(4)]), new Apply(11,[new PArg(1), new PArg(4)])], 4:[new Apply(4,[]), new Apply(6,[]), new Apply(7,[]), new Apply(9,[]), new Apply(12,[]), new Apply(19,[new PArg(4)]), new Apply(20,[])]},[new CncFun("lindef Item",[0]), new CncFun("lindef Kind",[0, 0]), new CncFun("lindef Phrase",[0]), new CncFun("lindef Quality",[0]), new CncFun("Boring",[1]), new CncFun("Cheese",[2, 3]), new CncFun("Delicious",[4]), new CncFun("Expensive",[5]), new CncFun("Fish",[6, 6]), new CncFun("Fresh",[7]), new CncFun("Is",[8]), new CncFun("Is",[9]), new CncFun("Italian",[10]), new CncFun("Pizza",[11, 12]), new CncFun("QKind",[13, 14]), new CncFun("That",[15]), new CncFun("These",[16]), new CncFun("This",[17]), new CncFun("Those",[18]), new CncFun("Very",[19]), new CncFun("Warm",[20]), new CncFun("Wine",[21, 22])],[[new SymLit(0, 0)],[new SymKS("boring")],[new SymKS("cheese")],[new SymKS("cheeses")],[new SymKS("delicious")],[new SymKS("expensive")],[new SymKS("fish")],[new SymKS("fresh")],[new SymCat(0, 0), new SymKS("is"), new SymCat(1, 0)],[new SymCat(0, 0), new SymKS("are"), new SymCat(1, 0)],[new SymKS("Italian")],[new SymKS("pizza")],[new SymKS("pizzas")],[new SymCat(0, 0), new SymCat(1, 0)],[new SymCat(0, 0), new SymCat(1, 1)],[new SymKS("that"), new SymCat(0, 0)],[new SymKS("these"), new SymCat(0, 1)],[new SymKS("this"), new SymCat(0, 0)],[new SymKS("those"), new SymCat(0, 1)],[new SymKS("very"), new SymCat(0, 0)],[new SymKS("warm")],[new SymKS("wine")],[new SymKS("wines")]],{Float:{s: -3, e: -3}, Int:{s: -2, e: -2}, Item:{s: 0, e: 1}, Kind:{s: 2, e: 2}, Phrase:{s: 3, e: 3}, Quality:{s: 4, e: 4}, String:{s: -1, e: -1}, __gfVar:{s: -4, e: -4}}, 6)});
|
||||
16
src/runtime/javascript/index.js
Normal file
16
src/runtime/javascript/index.js
Normal file
@@ -0,0 +1,16 @@
|
||||
const pgf = require('bindings')('pgf')
|
||||
// console.log('pgf', pgf)
|
||||
console.log(pgf.readPGF('/Users/john/repositories/gf-typescript/test/grammars/Zero.pgf'));
|
||||
module.exports = pgf
|
||||
|
||||
/*
|
||||
let gr = pgf.readPGF('App12.pgf')
|
||||
let eng = gr.languages['AppEng']
|
||||
let i = eng.parse('this is a small theatre', pgf.readType('NP'))
|
||||
let pr = i.next() // pr.tree, pr.prob
|
||||
|
||||
let e = pgf.readExpr("AdjCN (PositA red_A) (UseN theatre_N)")
|
||||
eng.linearize(e) // : string
|
||||
eng.linearizeAll(e) // : string[]
|
||||
eng.tabularLinearize(e) // : {[key]:string : string}
|
||||
*/
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 201 B |
824
src/runtime/javascript/package-lock.json
generated
Normal file
824
src/runtime/javascript/package-lock.json
generated
Normal file
@@ -0,0 +1,824 @@
|
||||
{
|
||||
"name": "gf-js-bindings",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.10.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
|
||||
"integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^2.0.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
||||
"dev": true
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
|
||||
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"delegates": "^1.0.0",
|
||||
"readable-stream": "^2.0.6"
|
||||
}
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
|
||||
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safer-buffer": "~2.1.0"
|
||||
}
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
||||
"dev": true
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
||||
"dev": true
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
|
||||
"dev": true
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
|
||||
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
|
||||
"dev": true
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
||||
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
},
|
||||
"bindings": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
|
||||
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
|
||||
"requires": {
|
||||
"file-uri-to-path": "1.0.0"
|
||||
}
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
|
||||
"dev": true
|
||||
},
|
||||
"chownr": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz",
|
||||
"integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==",
|
||||
"dev": true
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||
"dev": true
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
||||
"dev": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"dev": true
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||
"dev": true
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
||||
"dev": true
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"env-paths": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-1.0.0.tgz",
|
||||
"integrity": "sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=",
|
||||
"dev": true
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
||||
"dev": true
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
|
||||
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
|
||||
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
|
||||
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
|
||||
"dev": true
|
||||
},
|
||||
"file-uri-to-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
|
||||
"dev": true
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz",
|
||||
"integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minipass": "^2.2.1"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
},
|
||||
"gauge": {
|
||||
"version": "2.7.4",
|
||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
|
||||
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aproba": "^1.0.3",
|
||||
"console-control-strings": "^1.0.0",
|
||||
"has-unicode": "^2.0.0",
|
||||
"object-assign": "^4.1.0",
|
||||
"signal-exit": "^3.0.0",
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1",
|
||||
"wide-align": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
|
||||
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
|
||||
"integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==",
|
||||
"dev": true
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
|
||||
"dev": true
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
|
||||
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.5.5",
|
||||
"har-schema": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
|
||||
"dev": true
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"jsprim": "^1.2.2",
|
||||
"sshpk": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
|
||||
"dev": true
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"dev": true
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
||||
"dev": true
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
|
||||
"dev": true
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
||||
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
|
||||
"dev": true
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
"json-schema": "0.2.3",
|
||||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.40.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
|
||||
"integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.24",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
|
||||
"integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mime-db": "1.40.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"dev": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
|
||||
"integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz",
|
||||
"integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minipass": "^2.2.1"
|
||||
}
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"node-addon-api": {
|
||||
"version": "1.6.3",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.6.3.tgz",
|
||||
"integrity": "sha512-FXWH6mqjWgU8ewuahp4spec8LkroFZK2NicOv6bNwZC3kcwZUI8LeZdG80UzTSLLhK4T7MsgNwlYDVRlDdfTDg=="
|
||||
},
|
||||
"node-gyp": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.0.2.tgz",
|
||||
"integrity": "sha512-sNcb5O7eJ9XiNAhWZ/UE2bWsBJn3Jb7rayMqMP4wjenlr1DwzZxUmbtmIrl04EU0p5fN2rU9WIDV+u0EbsI8oQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"env-paths": "^1.0.0",
|
||||
"glob": "^7.0.3",
|
||||
"graceful-fs": "^4.1.2",
|
||||
"mkdirp": "^0.5.0",
|
||||
"nopt": "2 || 3",
|
||||
"npmlog": "0 || 1 || 2 || 3 || 4",
|
||||
"request": "^2.87.0",
|
||||
"rimraf": "2",
|
||||
"semver": "~5.3.0",
|
||||
"tar": "^4.4.8",
|
||||
"which": "1"
|
||||
}
|
||||
},
|
||||
"nopt": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
|
||||
"integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"abbrev": "1"
|
||||
}
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
|
||||
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"are-we-there-yet": "~1.1.2",
|
||||
"console-control-strings": "~1.1.0",
|
||||
"gauge": "~2.7.3",
|
||||
"set-blocking": "~2.0.0"
|
||||
}
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||
"dev": true
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
|
||||
"dev": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"dev": true
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
|
||||
"dev": true
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||
"dev": true
|
||||
},
|
||||
"psl": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz",
|
||||
"integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==",
|
||||
"dev": true
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
"dev": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
|
||||
"dev": true
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"request": {
|
||||
"version": "2.88.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
|
||||
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.0",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.4.3",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
|
||||
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"dev": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
|
||||
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
|
||||
"dev": true
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
||||
"dev": true
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
||||
"dev": true
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
|
||||
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asn1": "~0.2.3",
|
||||
"assert-plus": "^1.0.0",
|
||||
"bcrypt-pbkdf": "^1.0.0",
|
||||
"dashdash": "^1.12.0",
|
||||
"ecc-jsbn": "~0.1.1",
|
||||
"getpass": "^0.1.1",
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.0.2",
|
||||
"tweetnacl": "~0.14.0"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
"strip-ansi": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"tar": {
|
||||
"version": "4.4.10",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz",
|
||||
"integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chownr": "^1.1.1",
|
||||
"fs-minipass": "^1.2.5",
|
||||
"minipass": "^2.3.5",
|
||||
"minizlib": "^1.2.1",
|
||||
"mkdirp": "^0.5.0",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.3"
|
||||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
|
||||
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"psl": "^1.1.24",
|
||||
"punycode": "^1.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
|
||||
"dev": true
|
||||
},
|
||||
"uri-js": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
|
||||
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"dev": true
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
|
||||
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
|
||||
"dev": true
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
|
||||
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
"extsprintf": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
|
||||
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^1.0.2 || 2"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
|
||||
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
21
src/runtime/javascript/package.json
Normal file
21
src/runtime/javascript/package.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "gf-js-bindings",
|
||||
"version": "1.0.0",
|
||||
"description": "JavaScript bindings to the GF C runtime",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "node-gyp rebuild",
|
||||
"clean": "node-gyp clean",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "John J. Camilleri",
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"gypfile": true,
|
||||
"dependencies": {
|
||||
"bindings": "^1.5.0",
|
||||
"node-addon-api": "^1.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"node-gyp": "^5.0.2"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 229 B |
@@ -1,252 +0,0 @@
|
||||
body {
|
||||
font-family:arial,helvetica,sans-serif;
|
||||
font-size:12px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
width:740px;
|
||||
height:520px;
|
||||
margin:auto 50px;
|
||||
border:1px solid gray;
|
||||
padding:10px;
|
||||
|
||||
}
|
||||
|
||||
#absFrame {
|
||||
width:250px;
|
||||
height:250px;
|
||||
padding:10px;
|
||||
border:1px solid gray;
|
||||
float:left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#conFrame {
|
||||
width:436px;
|
||||
height:250px;
|
||||
margin-left:10px;
|
||||
padding:10px;
|
||||
border:1px solid gray;
|
||||
float:left;
|
||||
white-space: normal;
|
||||
overflow:auto;
|
||||
}
|
||||
|
||||
#actFrame {
|
||||
width:250px;
|
||||
height:170px;
|
||||
margin-top:10px;
|
||||
padding:10px;
|
||||
border:1px solid gray;
|
||||
float:left;
|
||||
overflow:auto;
|
||||
}
|
||||
|
||||
#refFrame {
|
||||
width:436px;
|
||||
height:170px;
|
||||
margin-left:10px;
|
||||
margin-top:10px;
|
||||
padding:10px;
|
||||
border:1px solid gray;
|
||||
float:left;
|
||||
overflow:auto;
|
||||
}
|
||||
|
||||
#messageFrame {
|
||||
width:506px;
|
||||
height:15px;
|
||||
margin-top:10px;
|
||||
margin-right:10px;
|
||||
padding:10px;
|
||||
border:1px solid gray;
|
||||
float:left;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
#clipboardFrame {
|
||||
width:180px;
|
||||
height:15px;
|
||||
margin-top:10px;
|
||||
padding:10px;
|
||||
border:1px solid gray;
|
||||
float:left;
|
||||
overflow:auto;
|
||||
}
|
||||
|
||||
#tree {
|
||||
left: -10px;
|
||||
top: -10px;
|
||||
margin: 0px;
|
||||
padding: 10px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
ul {
|
||||
position: relative;
|
||||
list-style: none;
|
||||
margin-left: 20px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
img.tree-menu {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
a.tree:link, a.tree:visited, a.tree:active {
|
||||
color: black;
|
||||
background-color: white;
|
||||
text-decoration: none;
|
||||
margin-right:10px;
|
||||
}
|
||||
|
||||
a.tree:hover {
|
||||
color: blue;
|
||||
background-color: white;
|
||||
text-decoration: underline;
|
||||
margin-right:10px;
|
||||
}
|
||||
|
||||
a.treeSelected:link, a.treeSelected:visited, a.treeSelected:active {
|
||||
color: white;
|
||||
background-color: #3366CC;
|
||||
text-decoration: none;
|
||||
margin-right:10px;
|
||||
}
|
||||
|
||||
a.treeSelected:hover {
|
||||
color: white;
|
||||
background-color: #3366CC;
|
||||
text-decoration: underline;
|
||||
margin-right:10px;
|
||||
}
|
||||
|
||||
a.treeGray:link, a.treeGray:visited, a.treeGray:active {
|
||||
color: silver;
|
||||
background-color: white;
|
||||
text-decoration: none;
|
||||
margin-right:10px;
|
||||
}
|
||||
|
||||
a.treeGray:hover {
|
||||
color: silver;
|
||||
background-color: white;
|
||||
text-decoration: none;
|
||||
margin-right:10px;
|
||||
}
|
||||
|
||||
table.action, table.refinement, table.wrapper, table.tree, table.language {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border-style: none;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0px;
|
||||
}
|
||||
|
||||
tr.selected {
|
||||
color: white;
|
||||
background-color: #3366CC;
|
||||
}
|
||||
|
||||
tr.unavailable, tr.closed {
|
||||
color: silver;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
tr.unavailable:hover {
|
||||
color: silver;
|
||||
background-color: #3366CC;
|
||||
}
|
||||
|
||||
tr.action, tr.refinement, tr.wrapper, tr.tree {
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
tr.action:hover, tr.refinement:hover, tr.wrapper:hover, tr.tree:hover {
|
||||
color: white;
|
||||
background-color: #3366CC;
|
||||
}
|
||||
|
||||
td.action {
|
||||
width: 220px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
td.refinement, td.wrapper, td.tree {
|
||||
width: 515px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
td.hotKey {
|
||||
width: 30px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
td.language {
|
||||
color: black;
|
||||
background-color: white;
|
||||
margin: 1px;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
td.language:hover {
|
||||
color: blue;
|
||||
background-color: white;
|
||||
text-decoration: underline;
|
||||
margin: 1px;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
td.selected {
|
||||
color: white;
|
||||
background-color: #3366CC;
|
||||
margin: 1px;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
td.selected:hover {
|
||||
color: white;
|
||||
background-color: #3366CC;
|
||||
text-decoration: underline;
|
||||
margin: 1px;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
span.normal {
|
||||
color: black;
|
||||
background-color: white;
|
||||
text-decoration: none;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
span.edit {
|
||||
color: black;
|
||||
background-color: white;
|
||||
text-decoration: none;
|
||||
border:2px inset;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
span.selected {
|
||||
color: white;
|
||||
background-color: #3366CC;
|
||||
text-decoration: none;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
body {
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
dl {
|
||||
|
||||
}
|
||||
|
||||
dt {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
dl dd {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
dl.fromLang dt {
|
||||
display: none;
|
||||
}
|
||||
|
||||
dl.toLang {
|
||||
border-width: 1px 0 0 0;
|
||||
border-style: solid;
|
||||
border-color: #c0c0c0;
|
||||
}
|
||||
|
||||
dl.toLang dt {
|
||||
color: #c0c0c0;
|
||||
display: block;
|
||||
float: left;
|
||||
width: 5em;
|
||||
}
|
||||
|
||||
|
||||
dl.toLang dd {
|
||||
border-width: 0 0 1px 0;
|
||||
border-style: solid;
|
||||
border-color: #c0c0c0;
|
||||
}
|
||||
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<link rel="stylesheet" type="text/css" href="translator.css" />
|
||||
<script type="text/javascript" src="gflib.js"></script>
|
||||
<script type="text/javascript" src="grammar.js"></script>
|
||||
<script type="text/javascript" src="translator.js"></script>
|
||||
<script type="text/javascript">
|
||||
/* CHANGE ME */
|
||||
var grammar = Foods;
|
||||
|
||||
function updateTranslation () {
|
||||
var input = document.getElementById('inputText').value;
|
||||
var fromLang = document.getElementById('fromLang').value;
|
||||
var toLang = document.getElementById('toLang').value;
|
||||
var output = document.getElementById('output');
|
||||
var translation = grammar.translate(input, fromLang, toLang);
|
||||
removeChildren(output);
|
||||
output.appendChild(formatTranslation(translation));
|
||||
}
|
||||
|
||||
function populateLangs () {
|
||||
var f = document.getElementById('fromLang');
|
||||
var t = document.getElementById('toLang');
|
||||
for (var c in grammar.concretes) {
|
||||
addOption(f, c, c);
|
||||
addOption(t, c, c);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<title>Web-based GF Translator</title>
|
||||
</head>
|
||||
<body onload="populateLangs(Food, 'fromLang', 'toLang')">
|
||||
<form id="translate">
|
||||
<p>
|
||||
<input type="text" name="inputText" id="inputText" value="this cheese is warm" size="50" />
|
||||
</p>
|
||||
<p>
|
||||
From: <select name="fromLang" id="fromLang" onchange=""><option value="">Any language</option></select>
|
||||
To: <select name="toLang" id="toLang"><option value="">All languages</option></select>
|
||||
<input type="button" value="Translate" onclick="updateTranslation()" />
|
||||
</p>
|
||||
</form>
|
||||
<div id="output"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,51 +0,0 @@
|
||||
function formatTranslation (outputs) {
|
||||
var dl1 = document.createElement("dl");
|
||||
dl1.className = "fromLang";
|
||||
for (var fromLang in outputs) {
|
||||
var ul = document.createElement("ul");
|
||||
addDefinition(dl1, document.createTextNode(fromLang), ul);
|
||||
for (var i in outputs[fromLang]) {
|
||||
var dl2 = document.createElement("dl");
|
||||
dl2.className = "toLang";
|
||||
for (var toLang in outputs[fromLang][i]) {
|
||||
addDefinition(dl2, document.createTextNode(toLang), document.createTextNode(outputs[fromLang][i][toLang]));
|
||||
}
|
||||
addItem(ul, dl2);
|
||||
}
|
||||
}
|
||||
|
||||
return dl1;
|
||||
}
|
||||
|
||||
/* DOM utilities for specific tags */
|
||||
|
||||
function addDefinition (dl, t, d) {
|
||||
var dt = document.createElement("dt");
|
||||
dt.appendChild(t);
|
||||
dl.appendChild(dt);
|
||||
var dd = document.createElement("dd");
|
||||
dd.appendChild(d);
|
||||
dl.appendChild(dd);
|
||||
}
|
||||
|
||||
function addItem (ul, i) {
|
||||
var li = document.createElement("li");
|
||||
li.appendChild(i);
|
||||
ul.appendChild(li);
|
||||
}
|
||||
|
||||
function addOption (select, value, content) {
|
||||
var option = document.createElement("option");
|
||||
option.value = value;
|
||||
option.appendChild(document.createTextNode(content));
|
||||
select.appendChild(option);
|
||||
}
|
||||
|
||||
/* General DOM utilities */
|
||||
|
||||
/* Removes all the children of a node */
|
||||
function removeChildren(node) {
|
||||
while (node.hasChildNodes()) {
|
||||
node.removeChild(node.firstChild);
|
||||
}
|
||||
}
|
||||
7
src/runtime/typescript/MOVED.md
Normal file
7
src/runtime/typescript/MOVED.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Project moved
|
||||
|
||||
The GF TypeScript runtime has been moved to the repository:
|
||||
<https://github.com/GrammaticalFramework/gf-typescript>
|
||||
|
||||
If you are looking for an updated version of the JavaScript runtime,
|
||||
you should also look there.
|
||||
337
src/runtime/typescript/gflib.d.ts
vendored
337
src/runtime/typescript/gflib.d.ts
vendored
@@ -1,337 +0,0 @@
|
||||
/**
|
||||
* gflib.dt.s
|
||||
*
|
||||
* by John J. Camilleri
|
||||
*
|
||||
* TypeScript type definitions for the "original" JS GF runtime (GF:src/runtime/javascript/gflib.js)
|
||||
*/
|
||||
|
||||
// Note: the String prototype is extended with:
|
||||
// String.prototype.tag = "";
|
||||
// String.prototype.setTag = function (tag) { this.tag = tag; };
|
||||
|
||||
/**
|
||||
* A GF grammar is one abstract and multiple concretes
|
||||
*/
|
||||
declare class GFGrammar {
|
||||
abstract: GFAbstract
|
||||
concretes: {[key: string]: GFConcrete}
|
||||
|
||||
constructor(abstract: GFAbstract, concretes: {[key: string]: GFConcrete})
|
||||
|
||||
translate(
|
||||
input: string,
|
||||
fromLang: string,
|
||||
toLang: string
|
||||
): {[key: string]: {[key: string]: string}}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract Syntax Tree
|
||||
*/
|
||||
declare class Fun {
|
||||
name: string
|
||||
args: Fun[]
|
||||
|
||||
constructor(name: string, ...args: Fun[])
|
||||
|
||||
print(): string
|
||||
show(): string
|
||||
getArg(i: number): Fun
|
||||
setArg(i: number, c: Fun): void
|
||||
isMeta(): boolean
|
||||
isComplete(): boolean
|
||||
isLiteral(): boolean
|
||||
isString(): boolean
|
||||
isInt(): boolean
|
||||
isFloat(): boolean
|
||||
isEqual(obj: any): boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract syntax
|
||||
*/
|
||||
declare class GFAbstract {
|
||||
startcat: string
|
||||
types: {[key: string]: Type} // key is function name
|
||||
|
||||
constructor(startcat: string, types: {[key: string]: Type})
|
||||
|
||||
addType(fun: string, args: string[], cat: string): void
|
||||
getArgs(fun: string): string[]
|
||||
getCat(fun: string): string
|
||||
annotate(tree: Fun, type: string): Fun
|
||||
handleLiterals(tree: Fun, type: Type): Fun
|
||||
copyTree(x: Fun): Fun
|
||||
parseTree(str: string, type: string): Fun
|
||||
parseTree_(tokens: string[], prec: number): Fun
|
||||
}
|
||||
|
||||
/**
|
||||
* Type
|
||||
*/
|
||||
declare class Type {
|
||||
args: string[]
|
||||
cat: string
|
||||
|
||||
constructor(args: string[], cat: string)
|
||||
}
|
||||
|
||||
type ApplyOrCoerce = Apply | Coerce
|
||||
|
||||
/**
|
||||
* Concrete syntax
|
||||
*/
|
||||
declare class GFConcrete {
|
||||
flags: {[key: string]: string}
|
||||
productions: {[key: number]: ApplyOrCoerce[]}
|
||||
functions: CncFun[]
|
||||
sequences: Array<Array<Sym>>
|
||||
startCats: {[key: string]: {s: number, e: number}}
|
||||
totalFIds: number
|
||||
pproductions: {[key: number]: ApplyOrCoerce[]}
|
||||
lproductions: {[key: string]: {fid: FId, fun: CncFun}}
|
||||
|
||||
constructor(
|
||||
flags: {[key: string]: string},
|
||||
productions: {[key: number]: ApplyOrCoerce[]},
|
||||
functions: CncFun[],
|
||||
sequences: Array<Array<Sym>>,
|
||||
startCats: {[key: string]: {s: number, e: number}},
|
||||
totalFIds: number
|
||||
)
|
||||
|
||||
linearizeSyms(tree: Fun, tag: string): Array<{fid: FId, table: any}>
|
||||
syms2toks(syms: Sym[]): string[]
|
||||
linearizeAll(tree: Fun): string[]
|
||||
linearize(tree: Fun): string
|
||||
tagAndLinearize(tree: Fun): string[]
|
||||
unlex(ts: string): string
|
||||
tagIt(obj: any, tag: string): any
|
||||
// showRules(): string // Uncaught TypeError: Cannot read property 'length' of undefined at gflib.js:451
|
||||
tokenize(string: string): string[]
|
||||
parseString(string: string, cat: string): Fun[]
|
||||
complete(
|
||||
input: string,
|
||||
cat: string
|
||||
): {consumed: string[], suggestions: string[]}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function ID
|
||||
*/
|
||||
type FId = number
|
||||
|
||||
/**
|
||||
* Apply
|
||||
*/
|
||||
declare class Apply {
|
||||
id: string
|
||||
fun: FId
|
||||
args: PArg[]
|
||||
|
||||
constructor(fun: FId, args: PArg[])
|
||||
|
||||
show(cat: string): string
|
||||
isEqual(obj: any): boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* PArg
|
||||
*/
|
||||
declare class PArg {
|
||||
fid: FId
|
||||
hypos: any[]
|
||||
|
||||
constructor(fid: FId, ...hypos: any[])
|
||||
}
|
||||
|
||||
/**
|
||||
* Coerce
|
||||
*/
|
||||
declare class Coerce {
|
||||
id: string
|
||||
arg: FId
|
||||
|
||||
constructor(arg: FId)
|
||||
|
||||
show(cat: string): string
|
||||
}
|
||||
|
||||
/**
|
||||
* Const
|
||||
*/
|
||||
declare class Const {
|
||||
id: string
|
||||
lit: Fun
|
||||
toks: any[]
|
||||
|
||||
constructor(lit: Fun, toks: any[])
|
||||
|
||||
show(cat: string): string
|
||||
isEqual(obj: any): boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* CncFun
|
||||
*/
|
||||
declare class CncFun {
|
||||
name: string
|
||||
lins: FId[]
|
||||
|
||||
constructor(name: string, lins: FId[])
|
||||
}
|
||||
|
||||
type Sym = SymCat | SymKS | SymKP | SymLit
|
||||
|
||||
/**
|
||||
* SymCat
|
||||
*/
|
||||
declare class SymCat {
|
||||
id: string
|
||||
i: number
|
||||
label: number
|
||||
|
||||
constructor(i: number, label: number)
|
||||
|
||||
getId(): string
|
||||
getArgNum(): number
|
||||
show(): string
|
||||
}
|
||||
|
||||
/**
|
||||
* SymKS
|
||||
*/
|
||||
declare class SymKS {
|
||||
id: string
|
||||
tokens: string[]
|
||||
|
||||
constructor(...tokens: string[])
|
||||
|
||||
getId(): string
|
||||
show(): string
|
||||
}
|
||||
|
||||
/**
|
||||
* SymKP
|
||||
*/
|
||||
declare class SymKP {
|
||||
id: string
|
||||
tokens: string[]
|
||||
alts: Alt[]
|
||||
|
||||
constructor(tokens: string[], alts: Alt[])
|
||||
|
||||
getId(): string
|
||||
show(): string
|
||||
}
|
||||
|
||||
/**
|
||||
* Alt
|
||||
*/
|
||||
declare class Alt {
|
||||
tokens: string[]
|
||||
prefixes: string[]
|
||||
|
||||
constructor(tokens: string[], prefixes: string[])
|
||||
}
|
||||
|
||||
/**
|
||||
* SymLit
|
||||
*/
|
||||
declare class SymLit {
|
||||
id: string
|
||||
i: number
|
||||
label: number
|
||||
|
||||
constructor(i: number, label: number)
|
||||
|
||||
getId(): string
|
||||
show(): string
|
||||
}
|
||||
|
||||
/**
|
||||
* Trie
|
||||
*/
|
||||
declare class Trie {
|
||||
value: any
|
||||
items: Trie[]
|
||||
|
||||
insertChain(keys, obj): void
|
||||
insertChain1(keys, obj): void
|
||||
lookup(key, obj): any
|
||||
isEmpty(): boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* ParseState
|
||||
*/
|
||||
declare class ParseState {
|
||||
concrete: GFConcrete
|
||||
startCat: string
|
||||
items: Trie
|
||||
chart: Chart
|
||||
|
||||
constructor(concrete: GFConcrete, startCat: string)
|
||||
|
||||
next(token: string): boolean
|
||||
complete(correntToken: string): Trie
|
||||
extractTrees(): any[]
|
||||
process(
|
||||
agenda,
|
||||
literalCallback: (fid: FId) => any,
|
||||
tokenCallback: (tokens: string[], item: any) => any
|
||||
): void
|
||||
}
|
||||
|
||||
/**
|
||||
* Chart
|
||||
*/
|
||||
declare class Chart {
|
||||
active: any
|
||||
actives: {[key: number]: any}
|
||||
passive: any
|
||||
forest: {[key: number]: ApplyOrCoerce[]}
|
||||
nextId: number
|
||||
offset: number
|
||||
|
||||
constructor(concrete: GFConcrete)
|
||||
|
||||
lookupAC(fid: FId,label)
|
||||
lookupACo(offset, fid: FId, label)
|
||||
|
||||
labelsAC(fid: FId)
|
||||
insertAC(fid: FId, label, items): void
|
||||
|
||||
lookupPC(fid: FId, label, offset)
|
||||
insertPC(fid1: FId, label, offset, fid2: FId): void
|
||||
shift(): void
|
||||
expandForest(fid: FId): any[]
|
||||
}
|
||||
|
||||
/**
|
||||
* ActiveItem
|
||||
*/
|
||||
declare class ActiveItem {
|
||||
offset: number
|
||||
dot: number
|
||||
fun: CncFun
|
||||
seq: Array<Sym>
|
||||
args: PArg[]
|
||||
fid: FId
|
||||
lbl: number
|
||||
|
||||
constructor(
|
||||
offset: number,
|
||||
dot: number,
|
||||
fun: CncFun,
|
||||
seq: Array<Sym>,
|
||||
args: PArg[],
|
||||
fid: FId,
|
||||
lbl: number
|
||||
)
|
||||
|
||||
isEqual(obj: any): boolean
|
||||
shiftOverArg(i: number, fid: FId): ActiveItem
|
||||
shiftOverTokn(): ActiveItem
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import Data.Maybe(mapMaybe)
|
||||
import System.Directory (getModificationTime)
|
||||
import System.Mem(performGC)
|
||||
import Data.Time (UTCTime,getCurrentTime,diffUTCTime)
|
||||
import Data.Time.Compat (toUTCTime)
|
||||
--import Data.Time.Compat (toUTCTime)
|
||||
|
||||
data Cache a = Cache {
|
||||
cacheLoad :: FilePath -> IO a,
|
||||
@@ -63,7 +63,7 @@ readCache' c file =
|
||||
Nothing -> do v <- newMVar Nothing
|
||||
return (Map.insert file v objs, v)
|
||||
-- Check time stamp, and reload if different than the cache entry
|
||||
readObject m = do t' <- toUTCTime `fmap` getModificationTime file
|
||||
readObject m = do t' <- {-toUTCTime `fmap`-} getModificationTime file
|
||||
now <- getCurrentTime
|
||||
x' <- case m of
|
||||
Just (t,_,x) | t' == t -> return x
|
||||
|
||||
@@ -153,6 +153,8 @@ cpgfMain qsem command (t,(pgf,pc)) =
|
||||
"c-parse" -> withQSem qsem $
|
||||
out t=<< join (parse # input % start % limit % treeopts)
|
||||
"c-linearize" -> out t=<< lin # tree % to
|
||||
"c-bracketedLinearize"
|
||||
-> out t=<< bracketedLin # tree % to
|
||||
"c-linearizeAll"-> out t=<< linAll # tree % to
|
||||
"c-translate" -> withQSem qsem $
|
||||
out t=<<join(trans # input % to % start % limit%treeopts)
|
||||
@@ -224,6 +226,10 @@ cpgfMain qsem command (t,(pgf,pc)) =
|
||||
lin' tree (tos,unlex) =
|
||||
[makeObj ["to".=to,"text".=unlex (C.linearize c tree)]|(to,c)<-tos]
|
||||
|
||||
bracketedLin tree to = showJSON (bracketedLin' tree to)
|
||||
bracketedLin' tree (tos,unlex) =
|
||||
[makeObj ["to".=to,"brackets".=showJSON (C.bracketedLinearize c tree)]|(to,c)<-tos]
|
||||
|
||||
trans input@((from,_),_) to start mlimit (trie,jsontree) =
|
||||
do parses <- parse' start mlimit input
|
||||
return $
|
||||
@@ -974,10 +980,19 @@ instance JSON PGF.Expr where
|
||||
|
||||
instance JSON PGF.BracketedString where
|
||||
readJSON x = return (PGF.Leaf "")
|
||||
showJSON (PGF.Bracket cat fid index fun _ bs) =
|
||||
showJSON (PGF.Bracket cat fid _ index fun _ bs) =
|
||||
makeObj ["cat".=cat, "fid".=fid, "index".=index, "fun".=fun, "children".=bs]
|
||||
showJSON (PGF.Leaf s) = makeObj ["token".=s]
|
||||
|
||||
#if C_RUNTIME
|
||||
instance JSON C.BracketedString where
|
||||
readJSON x = return (C.Leaf "")
|
||||
showJSON (C.Bracket cat fid index fun bs) =
|
||||
makeObj ["cat".=cat, "fid".=fid, "index".=index, "fun".=fun, "children".=bs]
|
||||
showJSON C.BIND = makeObj ["bind".=True]
|
||||
showJSON (C.Leaf s) = makeObj ["token".=s]
|
||||
#endif
|
||||
|
||||
-- * PGF utilities
|
||||
{-
|
||||
cat :: PGF -> Maybe PGF.Type -> PGF.Type
|
||||
|
||||
@@ -132,8 +132,10 @@ function initialize_sorting(tagList,classList) {
|
||||
elem.style.zIndex=0;
|
||||
move_element(elem,0,0);
|
||||
setDragHandlers(null,null)
|
||||
preventScroll=false;
|
||||
return false;
|
||||
}
|
||||
preventScroll=true;
|
||||
setDragHandlers(dragMove,dragEnd)
|
||||
return false;
|
||||
}
|
||||
@@ -146,8 +148,13 @@ function initialize_sorting(tagList,classList) {
|
||||
|
||||
//var jsdebug=debug;
|
||||
|
||||
//https://stackoverflow.com/questions/49500339/cant-prevent-touchmove-from-scrolling-window-on-ios
|
||||
var preventScroll=false;
|
||||
function pd(e) {if(preventScroll) e.preventDefault()}
|
||||
|
||||
function init() {
|
||||
setStartHandler(mousedown)
|
||||
document.addEventListener("touchmove",pd,{passive:false})
|
||||
//var d=element("javascriptdebug");
|
||||
//if(d) jsdebug=function(msg) { d.innerHTML=msg; }
|
||||
}
|
||||
|
||||
11
stack-ghc7.10.3.yaml
Normal file
11
stack-ghc7.10.3.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
resolver: lts-6.35 # ghc 7.10.3
|
||||
|
||||
packages:
|
||||
- . # GF, PGF
|
||||
- src/runtime/haskell-bind # PGF2 (requires C runtime to be installed)
|
||||
|
||||
extra-deps:
|
||||
|
||||
flags:
|
||||
gf:
|
||||
server: true
|
||||
11
stack-ghc8.0.2.yaml
Normal file
11
stack-ghc8.0.2.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
resolver: lts-9.21 # ghc 8.0.2
|
||||
|
||||
packages:
|
||||
- . # GF, PGF
|
||||
- src/runtime/haskell-bind # PGF2 (requires C runtime to be installed)
|
||||
|
||||
extra-deps:
|
||||
|
||||
flags:
|
||||
gf:
|
||||
server: true
|
||||
14
stack-ghc8.2.2.yaml
Normal file
14
stack-ghc8.2.2.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
resolver: lts-11.22 # ghc 8.2.2
|
||||
|
||||
packages:
|
||||
- . # GF, PGF
|
||||
- src/runtime/haskell-bind # PGF2 (requires C runtime to be installed)
|
||||
|
||||
extra-deps:
|
||||
- cgi-3001.3.0.2
|
||||
- httpd-shed-0.4.0.3
|
||||
- time-1.6.0.1 # cgi-3001.3.0.2: time-1.8.0.2 from stack configuration does not match >=1.5 && <1.7
|
||||
|
||||
flags:
|
||||
gf:
|
||||
server: true
|
||||
12
stack-ghc8.4.3.yaml
Normal file
12
stack-ghc8.4.3.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
resolver: lts-12.14 # ghc 8.4.3
|
||||
|
||||
packages:
|
||||
- . # GF, PGF
|
||||
- src/runtime/haskell-bind # PGF2 (requires C runtime to be installed)
|
||||
|
||||
extra-deps:
|
||||
- cgi-3001.3.0.3
|
||||
|
||||
flags:
|
||||
gf:
|
||||
server: true
|
||||
13
stack-ghc8.6.2.yaml
Normal file
13
stack-ghc8.6.2.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
resolver: nightly-2018-12-04 # ghc 8.6.2
|
||||
|
||||
packages:
|
||||
- . # GF, PGF
|
||||
- src/runtime/haskell-bind # PGF2 (requires C runtime to be installed)
|
||||
|
||||
extra-deps:
|
||||
- json-0.9.2
|
||||
- network-2.6.3.6
|
||||
|
||||
flags:
|
||||
gf:
|
||||
server: true
|
||||
@@ -5,8 +5,6 @@ packages:
|
||||
- src/runtime/haskell-bind # PGF2 (requires C runtime to be installed)
|
||||
|
||||
extra-deps:
|
||||
# - happy-1.19.9
|
||||
# - alex-3.2.4
|
||||
- cgi-3001.3.0.2
|
||||
- httpd-shed-0.4.0.3
|
||||
- time-1.6.0.1 # cgi-3001.3.0.2: time-1.8.0.2 from stack configuration does not match >=1.5 && <1.7
|
||||
|
||||
Reference in New Issue
Block a user