forked from GitHub/gf-core
Compare commits
250 Commits
remove-exa
...
compact-pg
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
320ead943c | ||
|
|
c119d5e34b | ||
|
|
529635e0e9 | ||
|
|
a33a84df3d | ||
|
|
9e3512db81 | ||
|
|
8a419f66a6 | ||
|
|
29662350dc | ||
|
|
a27bcb8092 | ||
|
|
4d79aa8b19 | ||
|
|
e989cc69a2 | ||
|
|
5c5af8df79 | ||
|
|
084b345663 | ||
|
|
400aad1d07 | ||
|
|
a0cfe09e09 | ||
|
|
12912299be | ||
|
|
b3c07d45b9 | ||
|
|
acb70ccc1b | ||
|
|
4a71464ca7 | ||
|
|
e993ae59f8 | ||
|
|
f12557acf8 | ||
|
|
9d3badd8b2 | ||
|
|
e2ddea6c7d | ||
|
|
59a6e3cfdd | ||
|
|
1e8d684f9a | ||
|
|
72cfc1f48a | ||
|
|
724bf67295 | ||
|
|
a7a592d93e | ||
|
|
d1bb1de87f | ||
|
|
394d033d19 | ||
|
|
cb678dfdc8 | ||
|
|
4161bbf0ec | ||
|
|
148590927c | ||
|
|
85a81ef741 | ||
|
|
3e662475ee | ||
|
|
b77626b802 | ||
|
|
12f2520b3c | ||
|
|
941b4ddf1f | ||
|
|
85f12a5544 | ||
|
|
81362ed7b7 | ||
|
|
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 | ||
|
|
d06539c35c | ||
|
|
60738dda6d | ||
|
|
e628e3fe0f | ||
|
|
769743c5c0 | ||
|
|
1c75d417ee | ||
|
|
5c518de0f2 | ||
|
|
e6c2c844e9 | ||
|
|
883a7a95a1 | ||
|
|
831252eb81 | ||
|
|
fdc5659f80 | ||
|
|
4d34c7f66b | ||
|
|
f898c250ba | ||
|
|
5ef390f188 | ||
|
|
fa5c6a2949 | ||
|
|
d0bc368358 | ||
|
|
e0dca729d6 | ||
|
|
47c983c625 | ||
|
|
01f61c526f | ||
|
|
538fe5bddb | ||
|
|
f4052c8a5e | ||
|
|
e0a3b0030e | ||
|
|
b30456aa0c | ||
|
|
61c58316ea | ||
|
|
001d036a2c | ||
|
|
fe7d01f7e3 | ||
|
|
a7e43d872f | ||
|
|
d6fc50b40b | ||
|
|
9e02319b6d | ||
|
|
6278deb7a2 | ||
|
|
c6ec8cf302 | ||
|
|
07768ba4c4 | ||
|
|
e2401f32ca | ||
|
|
83abaa9b44 | ||
|
|
c7a14537c1 | ||
|
|
6352799ccb | ||
|
|
b1611eccd8 | ||
|
|
c8eb1010c5 | ||
|
|
14d35c8a31 | ||
|
|
9bf5c98509 | ||
|
|
8821f8baa8 | ||
|
|
8a45d23d63 | ||
|
|
cb0e919bf5 | ||
|
|
d1a435ad9d | ||
|
|
69ba677136 | ||
|
|
406eec6690 | ||
|
|
2f1ee094d2 | ||
|
|
390a6a04a1 | ||
|
|
37e0754cf0 | ||
|
|
a7b2f77227 | ||
|
|
9a7862ea9e | ||
|
|
914d54255f | ||
|
|
aea8548930 | ||
|
|
99dad48961 | ||
|
|
6a5053daeb | ||
|
|
5a2b200948 | ||
|
|
f7dc9a6eaf | ||
|
|
bf5abe2948 | ||
|
|
7867c8c828 | ||
|
|
632cd1e522 |
2
.ghci
2
.ghci
@@ -1,2 +1,2 @@
|
|||||||
:set -isrc/compiler -isrc/binary -isrc/runtime/haskell -isrc/server -isrc/server/transfer -idist/build/autogen -idist/build
|
:set -isrc/compiler -isrc/binary -isrc/runtime/haskell -isrc/server -isrc/example-based -isrc/server/transfer -idist/build/autogen -idist/build
|
||||||
:set -fwarn-unused-imports -optP-DSERVER_MODE -optP-DUSE_INTERRUPT -optP-DCC_LAZY -optP-include -optPdist/build/autogen/cabal_macros.h -odir dist/build/gf/gf-tmp -hidir dist/build/gf/gf-tmp -stubdir dist/build/gf/gf-tmp
|
:set -fwarn-unused-imports -optP-DSERVER_MODE -optP-DUSE_INTERRUPT -optP-DCC_LAZY -optP-include -optPdist/build/autogen/cabal_macros.h -odir dist/build/gf/gf-tmp -hidir dist/build/gf/gf-tmp -stubdir dist/build/gf/gf-tmp
|
||||||
|
|||||||
19
.gitignore
vendored
19
.gitignore
vendored
@@ -43,3 +43,22 @@ src/runtime/python/build/
|
|||||||
cabal.sandbox.config
|
cabal.sandbox.config
|
||||||
.stack-work
|
.stack-work
|
||||||
DATA_DIR
|
DATA_DIR
|
||||||
|
|
||||||
|
stack*.yaml.lock
|
||||||
|
|
||||||
|
# Generated documentation (not exhaustive)
|
||||||
|
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-refman.html
|
||||||
|
doc/gf-shell-reference.html
|
||||||
|
doc/icfp-2012.html
|
||||||
|
download/*.html
|
||||||
|
gf-book/index.html
|
||||||
|
src/www/gf-web-api.html
|
||||||
|
|||||||
3
Makefile
3
Makefile
@@ -20,6 +20,7 @@ doc:
|
|||||||
|
|
||||||
clean:
|
clean:
|
||||||
cabal clean
|
cabal clean
|
||||||
|
bash bin/clean_html
|
||||||
|
|
||||||
gf:
|
gf:
|
||||||
cabal build rgl-none
|
cabal build rgl-none
|
||||||
@@ -32,7 +33,7 @@ html::
|
|||||||
# number to the top of debian/changelog.
|
# number to the top of debian/changelog.
|
||||||
# (Tested on Ubuntu 15.04. You need to install dpkg-dev & debhelper.)
|
# (Tested on Ubuntu 15.04. You need to install dpkg-dev & debhelper.)
|
||||||
deb:
|
deb:
|
||||||
dpkg-buildpackage -b
|
dpkg-buildpackage -b -uc
|
||||||
|
|
||||||
# Make an OS X Installer package
|
# Make an OS X Installer package
|
||||||
pkg:
|
pkg:
|
||||||
|
|||||||
@@ -37,13 +37,6 @@ The simplest way of installing GF is with the command:
|
|||||||
cabal install
|
cabal install
|
||||||
```
|
```
|
||||||
|
|
||||||
This can be broken down into the usual sub-steps:
|
|
||||||
```
|
|
||||||
cabal configure
|
|
||||||
cabal build
|
|
||||||
cabal copy
|
|
||||||
```
|
|
||||||
|
|
||||||
For more details, see the [download page](http://www.grammaticalframework.org/download/index.html)
|
For more details, see the [download page](http://www.grammaticalframework.org/download/index.html)
|
||||||
and [developers manual](http://www.grammaticalframework.org/doc/gf-developers.html).
|
and [developers manual](http://www.grammaticalframework.org/doc/gf-developers.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(defaultMainWithHooks,UserHooks(..),simpleUserHooks)
|
||||||
import Distribution.Simple.LocalBuildInfo(LocalBuildInfo(..),absoluteInstallDirs,datadir)
|
import Distribution.Simple.LocalBuildInfo(LocalBuildInfo(..),absoluteInstallDirs,datadir)
|
||||||
import Distribution.Simple.Setup(BuildFlags(..),Flag(..),InstallFlags(..),CopyDest(..),CopyFlags(..),SDistFlags(..))
|
import Distribution.Simple.Setup(BuildFlags(..),Flag(..),InstallFlags(..),CopyDest(..),CopyFlags(..),SDistFlags(..))
|
||||||
@@ -73,5 +74,9 @@ dataDirFile = "DATA_DIR"
|
|||||||
default_gf :: LocalBuildInfo -> FilePath
|
default_gf :: LocalBuildInfo -> FilePath
|
||||||
default_gf lbi = buildDir lbi </> exeName' </> exeNameReal
|
default_gf lbi = buildDir lbi </> exeName' </> exeNameReal
|
||||||
where
|
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"
|
exeName' = "gf"
|
||||||
exeNameReal = exeName' <.> exeExtension
|
exeNameReal = exeName' <.> exeExtension
|
||||||
|
|||||||
@@ -104,9 +104,10 @@ setupWeb dest (pkg,lbi) = do
|
|||||||
copy_pgf (pgf,subdir,_) =
|
copy_pgf (pgf,subdir,_) =
|
||||||
do let src = gfo_dir </> pgf
|
do let src = gfo_dir </> pgf
|
||||||
let dst = grammars_dir </> pgf
|
let dst = grammars_dir </> pgf
|
||||||
putStrLn $ "Installing "++dst
|
|
||||||
ex <- doesFileExist src
|
ex <- doesFileExist src
|
||||||
if ex then copyFile src dst else return ()
|
if ex then do putStrLn $ "Installing "++dst
|
||||||
|
copyFile src dst
|
||||||
|
else putStrLn $ "Not installing "++dst
|
||||||
|
|
||||||
gf_logo = "gf0.png"
|
gf_logo = "gf0.png"
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
### This script builds a binary distribution of GF from the source
|
### 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
|
### 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
|
### Two binary package formats are supported: plain tar files (.tar.gz) and
|
||||||
### OS X Installer packages (.pkg).
|
### OS X Installer packages (.pkg).
|
||||||
|
|
||||||
@@ -16,13 +16,14 @@ name="gf-$ver"
|
|||||||
destdir="$PWD/dist/$name" # assemble binary dist here
|
destdir="$PWD/dist/$name" # assemble binary dist here
|
||||||
prefix=${PREFIX:-/usr/local} # where to install
|
prefix=${PREFIX:-/usr/local} # where to install
|
||||||
fmt=${FMT:-tar.gz} # binary package format (tar.gz or pkg)
|
fmt=${FMT:-tar.gz} # binary package format (tar.gz or pkg)
|
||||||
|
ghc=${GHC:-ghc} # which Haskell compiler to use
|
||||||
|
|
||||||
extralib="$destdir$prefix/lib"
|
extralib="$destdir$prefix/lib"
|
||||||
extrainclude="$destdir$prefix/include"
|
extrainclude="$destdir$prefix/include"
|
||||||
extra="--extra-lib-dirs=$extralib --extra-include-dirs=$extrainclude"
|
extra="--extra-lib-dirs=$extralib --extra-include-dirs=$extrainclude"
|
||||||
|
|
||||||
set -e # Stop if an error occurs
|
set -e # Stop if an error occurs
|
||||||
set -x # print commands before exuting them
|
set -x # print commands before executing them
|
||||||
|
|
||||||
## First configure & build the C run-time system
|
## First configure & build the C run-time system
|
||||||
pushd src/runtime/c
|
pushd src/runtime/c
|
||||||
@@ -64,8 +65,8 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
## Build GF, with C run-time support enabled
|
## Build GF, with C run-time support enabled
|
||||||
cabal install --only-dependencies -fserver -fc-runtime $extra
|
cabal install -w "$ghc" --only-dependencies -fserver -fc-runtime $extra
|
||||||
cabal configure --prefix="$prefix" -fserver -fc-runtime $extra
|
cabal configure -w "$ghc" --prefix="$prefix" -fserver -fc-runtime $extra
|
||||||
DYLD_LIBRARY_PATH="$extralib" LD_LIBRARY_PATH="$extralib" cabal build
|
DYLD_LIBRARY_PATH="$extralib" LD_LIBRARY_PATH="$extralib" cabal build
|
||||||
# Building the example grammars will fail, because the RGL is missing
|
# Building the example grammars will fail, because the RGL is missing
|
||||||
cabal copy --destdir="$destdir" # create www directory
|
cabal copy --destdir="$destdir" # create www directory
|
||||||
|
|||||||
20
bin/clean_html
Executable file
20
bin/clean_html
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
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
|
||||||
146
bin/template.html
Normal file
146
bin/template.html
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="$lang$" xml:lang="$lang$"$if(dir)$ dir="$dir$"$endif$>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
$for(author-meta)$
|
||||||
|
<meta name="author" content="$author-meta$" />
|
||||||
|
$endfor$
|
||||||
|
$if(date-meta)$
|
||||||
|
<meta name="dcterms.date" content="$date-meta$" />
|
||||||
|
$endif$
|
||||||
|
$if(keywords)$
|
||||||
|
<meta name="keywords" content="$for(keywords)$$keywords$$sep$, $endfor$" />
|
||||||
|
$endif$
|
||||||
|
<title>$if(title-prefix)$$title-prefix$ – $endif$$pagetitle$</title>
|
||||||
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||||
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.2/css/all.css" integrity="sha384-/rXc/GQVaYpyDdyxK+ecHPVYJSN9bmVFBvjA/9eOB+pb3F2w2N6fc5qB9Ew5yIns" crossorigin="anonymous">
|
||||||
|
$for(css)$
|
||||||
|
<link rel="stylesheet" href="$css$" />
|
||||||
|
$endfor$
|
||||||
|
$if(math)$
|
||||||
|
$math$
|
||||||
|
$endif$
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
$for(header-includes)$
|
||||||
|
$header-includes$
|
||||||
|
$endfor$
|
||||||
|
</head>
|
||||||
|
<body class="bg-light">
|
||||||
|
<div class="bg-white pb-5">
|
||||||
|
$for(include-before)$
|
||||||
|
$include-before$
|
||||||
|
$endfor$
|
||||||
|
<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="200" class="float-md-right ml-3 mb-3 bg-white" alt="GF Logo">
|
||||||
|
</a>
|
||||||
|
<h1 class="title">$title$</h1>
|
||||||
|
$if(subtitle)$
|
||||||
|
<p class="subtitle">$subtitle$</p>
|
||||||
|
$endif$
|
||||||
|
$for(author)$
|
||||||
|
<p class="author">$author$</p>
|
||||||
|
$endfor$
|
||||||
|
$if(date)$
|
||||||
|
<p class="date">$date$</p>
|
||||||
|
$endif$
|
||||||
|
</header>
|
||||||
|
$endif$
|
||||||
|
$if(toc)$
|
||||||
|
<nav id="$idprefix$TOC">
|
||||||
|
$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="py-5">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-6 col-sm-3">
|
||||||
|
<a href="$rel-root$">
|
||||||
|
<i class="fas fa-home"></i>
|
||||||
|
Home
|
||||||
|
</a>
|
||||||
|
<h6 class="text-muted mt-3">Get started</h6>
|
||||||
|
<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>
|
||||||
|
/
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<div class="col-6 col-sm-3">
|
||||||
|
<h6 class="text-muted">Learn more</h6>
|
||||||
|
<ul class="list-unstyled">
|
||||||
|
<li><a href="$rel-root$/gf-book">The GF Book</a></li>
|
||||||
|
<li><a href="$rel-root$/doc/gf-refman.html">Reference Manual</a></li>
|
||||||
|
<li><a href="$rel-root$/doc/gf-shell-reference.html">GF Shell Reference</a></li>
|
||||||
|
<li><a href="http://www.molto-project.eu/sites/default/files/MOLTO_D2.3.pdf">Best Practices</a></li>
|
||||||
|
<li><a href="$rel-root$/lib/doc/synopsis/index.html"><strong>RGL Synopsis</strong></a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-6 col-sm-3">
|
||||||
|
<h6 class="text-muted">Develop</h6>
|
||||||
|
<ul class="list-unstyled">
|
||||||
|
<li><a href="$rel-root$/doc/gf-developers.html">Developers Guide</a></li>
|
||||||
|
<li><a href="http://hackage.haskell.org/package/gf/docs/PGF.html">PGF library API (Haskell runtime)</a></li>
|
||||||
|
<li><a href="$rel-root$/doc/runtime-api.html">PGF library API (C runtime)</a></li>
|
||||||
|
<li><a href="http://hackage.haskell.org/package/gf/docs/GF.html">GF compiler API</a></li>
|
||||||
|
<li><a href="$rel-root$/doc/gf-editor-modes.html">Text Editor Support</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-6 col-sm-3">
|
||||||
|
<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>
|
||||||
|
<li><a href="$rel-root$/doc/gf-people.html">Authors</a></li>
|
||||||
|
<li><a href="http://school.grammaticalframework.org/2018/">Summer School</a></li>
|
||||||
|
</ul>
|
||||||
|
<h6 class="text-muted">
|
||||||
|
Repositories
|
||||||
|
<i class="fab fa-github ml-1"></i>
|
||||||
|
</h6>
|
||||||
|
<a href="https://github.com/GrammaticalFramework/gf-core">GF</a> ·
|
||||||
|
<a href="https://github.com/GrammaticalFramework/gf-rgl">RGL</a> ·
|
||||||
|
<a href="https://github.com/GrammaticalFramework/gf-contrib">Contributions</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
$for(include-after)$
|
||||||
|
$include-after$
|
||||||
|
$endfor$
|
||||||
|
<script type="text/javascript">
|
||||||
|
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||||
|
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
try {
|
||||||
|
var pageTracker = _gat._getTracker("UA-7811807-3");
|
||||||
|
pageTracker._trackPageview();
|
||||||
|
} catch(err) {}</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
159
bin/update_html
159
bin/update_html
@@ -1,11 +1,156 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
### This script finds all .t2t (txt2tags) files and updates the corresponding
|
# Generate HTML from txt2tags (.t2t) and Markdown (.md)
|
||||||
### .html file, if it is out-of-date.
|
# 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.
|
||||||
|
|
||||||
find . -name '*.t2t' | while read t2t ; do
|
# Path to directory where this script is
|
||||||
html="${t2t%.t2t}.html"
|
# https://stackoverflow.com/a/246128/98600
|
||||||
if [ "$t2t" -nt "$html" ] ; then
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||||
txt2tags -thtml "$t2t"
|
|
||||||
|
# HTML template
|
||||||
|
template="$DIR/template.html"
|
||||||
|
|
||||||
|
# Render txt2tags into html file
|
||||||
|
# Arguments:
|
||||||
|
# 1. txt2tags source file, e.g. download/index.t2t
|
||||||
|
# 2. html target file, e.g. download/index.html
|
||||||
|
function render_t2t_html {
|
||||||
|
t2t="$1"
|
||||||
|
html="$2"
|
||||||
|
tmp="$2.tmp"
|
||||||
|
relroot="$( dirname $t2t | sed -E 's/^.\///' | sed -E 's/[^/]+/../g' )"
|
||||||
|
|
||||||
|
# First render with txt2tags to handle pre/post processing
|
||||||
|
txt2tags \
|
||||||
|
--target=html \
|
||||||
|
--no-headers \
|
||||||
|
--quiet \
|
||||||
|
--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")
|
||||||
|
l2=$(tail -n+2 "$t2t" | head -n 1)
|
||||||
|
l3=$(tail -n+3 "$t2t" | head -n 1)
|
||||||
|
title=
|
||||||
|
author=
|
||||||
|
date=
|
||||||
|
if [ -n "$l1" ] ; then
|
||||||
|
title="$l1"
|
||||||
|
if [ -n "$l2" ] ; then author="$l2" ; fi
|
||||||
|
if [ -n "$l3" ] ; then date="$l3" ; fi
|
||||||
fi
|
fi
|
||||||
done
|
|
||||||
|
# Run txt2tag's HTML through Pandoc for cleanup
|
||||||
|
pandoc \
|
||||||
|
--from=html \
|
||||||
|
--to=html5 \
|
||||||
|
--standalone \
|
||||||
|
--template="$template" \
|
||||||
|
--variable="lang:en" \
|
||||||
|
--variable="rel-root:$relroot" \
|
||||||
|
--metadata="title:$title" \
|
||||||
|
--metadata="author:$author" \
|
||||||
|
--metadata="date:$date" \
|
||||||
|
"$tmp" \
|
||||||
|
--output="$html"
|
||||||
|
rm -f "$tmp"
|
||||||
|
|
||||||
|
# Final post-processing
|
||||||
|
if [ -f "$html" ] ; then
|
||||||
|
sed -i.bak "s/<table/<table class=\"table\"/" "$html" && rm "$html.bak"
|
||||||
|
echo "$html"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Render markdown into html file
|
||||||
|
# Arguments:
|
||||||
|
# 1. markdown source file, e.g. download/index.md
|
||||||
|
# 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 \
|
||||||
|
$tocflag \
|
||||||
|
--template="$template" \
|
||||||
|
--variable="lang:en" \
|
||||||
|
--variable="rel-root:$relroot" \
|
||||||
|
"$md" \
|
||||||
|
--output="$html"
|
||||||
|
|
||||||
|
# Final post-processing
|
||||||
|
if [ -f "$html" ] ; then
|
||||||
|
# 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
|
||||||
|
ext="${file##*.}"
|
||||||
|
html="${file%.$ext}.html"
|
||||||
|
case $ext in
|
||||||
|
"md")
|
||||||
|
render_md_html "$file" "$html"
|
||||||
|
;;
|
||||||
|
"t2t")
|
||||||
|
render_t2t_html "$file" "$html"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
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" ] || [ "$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" ] || [ "$template" -nt "$html" ] ; then
|
||||||
|
render_md_html "$file" "$html"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|||||||
18
debian/changelog
vendored
18
debian/changelog
vendored
@@ -1,3 +1,21 @@
|
|||||||
|
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, 2 Dec 2018 15:00:00 +0100
|
||||||
|
|
||||||
gf (3.9-1) vivid xenial zesty; urgency=low
|
gf (3.9-1) vivid xenial zesty; urgency=low
|
||||||
|
|
||||||
* GF 3.9
|
* GF 3.9
|
||||||
|
|||||||
2
debian/control
vendored
2
debian/control
vendored
@@ -3,7 +3,7 @@ Section: devel
|
|||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: Thomas Hallgren <hallgren@chalmers.se>
|
Maintainer: Thomas Hallgren <hallgren@chalmers.se>
|
||||||
Standards-Version: 3.9.2
|
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/
|
Homepage: http://www.grammaticalframework.org/
|
||||||
|
|
||||||
Package: gf
|
Package: gf
|
||||||
|
|||||||
33
debian/rules
vendored
Normal file → Executable file
33
debian/rules
vendored
Normal file → Executable file
@@ -13,19 +13,6 @@
|
|||||||
override_dh_shlibdeps:
|
override_dh_shlibdeps:
|
||||||
dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info
|
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
|
|
||||||
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:
|
override_dh_auto_configure:
|
||||||
cd src/runtime/c && bash setup.sh configure --prefix=/usr
|
cd src/runtime/c && bash setup.sh configure --prefix=/usr
|
||||||
cd src/runtime/c && bash setup.sh build
|
cd src/runtime/c && bash setup.sh build
|
||||||
@@ -33,13 +20,31 @@ override_dh_auto_configure:
|
|||||||
cabal install --only-dependencies
|
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
|
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
|
||||||
|
export $(SET_LDL); 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:
|
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/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/python && python setup.py install --prefix=$(CURDIR)/debian/gf/usr
|
||||||
cd src/runtime/java && make INSTALL_PATH=$(CURDIR)/debian/gf/usr/lib install
|
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
|
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:
|
override_dh_auto_test:
|
||||||
ifneq (nocheck,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
|
ifneq (nocheck,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
|
||||||
true
|
true
|
||||||
|
|||||||
15
doc/Makefile
15
doc/Makefile
@@ -1,18 +1,3 @@
|
|||||||
resource:
|
|
||||||
gfdoc -txt2 ../lib/resource-1.0/abstract/*.gf
|
|
||||||
gfdoc -txt2 ../lib/resource-1.0/*/Paradigms*.gf
|
|
||||||
txt2tags --toc resource.txt
|
|
||||||
# cat resource-preamble resource.tex >final-resource.tex
|
|
||||||
sed -i 's/\\docum/%\\docum/g' resource.tex
|
|
||||||
sed -i 's/ion\*{/ion{/g' resource.tex
|
|
||||||
sed -i 's/\\paragraph{}//g' resource.tex
|
|
||||||
sed -i 's/}\\\\/}/g' resource.tex
|
|
||||||
cat resource-preamble resource.tex >resource.tmp
|
|
||||||
mv resource.tmp resource.tex
|
|
||||||
latex resource.tex
|
|
||||||
latex resource.tex
|
|
||||||
dvipdf resource.dvi
|
|
||||||
|
|
||||||
gf-help-full.txt::
|
gf-help-full.txt::
|
||||||
{ echo ; echo ; echo ; } > $@
|
{ echo ; echo ; echo ; } > $@
|
||||||
echo help -full -t2t | gf -run >> $@
|
echo help -full -t2t | gf -run >> $@
|
||||||
|
|||||||
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"
|
||||||
|
|
||||||
@@ -1,16 +1,8 @@
|
|||||||
GF Developers Guide
|
GF Developers Guide
|
||||||
Authors: Björn Bringert, Krasimir Angelov and Thomas Hallgren
|
|
||||||
Last update: %%mtime(%F, %H:%M)
|
|
||||||
|
|
||||||
% NOTE: this is a txt2tags file.
|
2018-07-26
|
||||||
% Create an html file from this file using:
|
|
||||||
% txt2tags -t html gf-developers.t2t
|
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!target:html
|
|
||||||
%!options(html): --toc
|
%!options(html): --toc
|
||||||
%!encoding:utf-8
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
== Before you start ==
|
== Before you start ==
|
||||||
|
|
||||||
@@ -63,18 +55,6 @@ Other required tools included in the Haskell Platform are
|
|||||||
and
|
and
|
||||||
[Happy http://www.haskell.org/happy/].
|
[Happy http://www.haskell.org/happy/].
|
||||||
|
|
||||||
%=== Darcs ===
|
|
||||||
%
|
|
||||||
%To get the GF source code, you also need //Darcs//, version 2 or later.
|
|
||||||
%Darcs 2.10 is recommended (July 2015).
|
|
||||||
%
|
|
||||||
%//Darcs//
|
|
||||||
%is a distributed version control system, see http://darcs.net/ for
|
|
||||||
%more information. There are precompiled packages for many platforms
|
|
||||||
%available and source code if you want to compile it yourself. Darcs
|
|
||||||
%is also written in Haskell and so you can use GHC to compile it.
|
|
||||||
|
|
||||||
|
|
||||||
=== Git ===
|
=== Git ===
|
||||||
|
|
||||||
To get the GF source code, you also need //Git//.
|
To get the GF source code, you also need //Git//.
|
||||||
@@ -425,13 +405,13 @@ There is also ``make build``, ``make copy`` and ``make clean`` which do what you
|
|||||||
=== Advanced ===
|
=== Advanced ===
|
||||||
For advanced build options, call the Haskell build script directly:
|
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].
|
For more details see the [README https://github.com/GrammaticalFramework/gf-rgl/blob/master/README.md].
|
||||||
|
|
||||||
=== Haskell-free ===
|
=== Haskell-free ===
|
||||||
If you do not have Haskell installed, you can use the simple build script ``Make.sh``
|
If you do not have Haskell installed, you can use the simple build script ``Setup.sh``
|
||||||
(or ``Make.bat`` for Windows).
|
(or ``Setup.bat`` for Windows).
|
||||||
|
|
||||||
|
|
||||||
== Creating binary distribution packages ==
|
== Creating binary distribution packages ==
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
Editor modes & IDE integration for GF
|
Editor modes & IDE integration for GF
|
||||||
|
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!options(html): --toc
|
|
||||||
%!postproc(html): <TITLE> <meta name = "viewport" content = "width = device-width"><TITLE>
|
|
||||||
%!encoding:utf-8
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
We collect GF modes for various editors on this page. Contributions are
|
We collect GF modes for various editors on this page. Contributions are
|
||||||
welcome!
|
welcome!
|
||||||
|
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
Grammatical Framework: Frequently Asked Quuestions
|
|
||||||
Aarne Ranta
|
|
||||||
%%date(%c)
|
|
||||||
|
|
||||||
% NOTE: this is a txt2tags file.
|
|
||||||
% Create an html file from this file using:
|
|
||||||
% txt2tags gf-bibliography.t2t
|
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!target:html
|
|
||||||
%!options(html): --toc
|
|
||||||
%!postproc(html): <TITLE> <meta name = "viewport" content = "width = device-width"><TITLE>
|
|
||||||
%!postproc(html): #BR <br>
|
|
||||||
%!encoding:utf-8
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
|
|
||||||
===What has been done with GF?===
|
|
||||||
|
|
||||||
**Translation**: systems with any number of parallel languages, with input in one language and output in all the others.
|
|
||||||
|
|
||||||
**Natural language generation** (NLG): translation from a formal language to natural languages.
|
|
||||||
|
|
||||||
**Ontology verbalization** is a special case of NLG.
|
|
||||||
|
|
||||||
**Language training**: grammar and vocabulary training systems.
|
|
||||||
|
|
||||||
**Human-computer interaction**: natural language interfaces, spoken dialogue systems.
|
|
||||||
|
|
||||||
**Linguistics**: comparisons between languages.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
===What parts does GF have?===
|
|
||||||
|
|
||||||
A **grammar compiler**, used for compiling grammars to parsing, generation, and translation code.
|
|
||||||
|
|
||||||
A **run-time system**, used for parsing, generation and translation. The run-time system is available in several languages:
|
|
||||||
Haskell, Java, C, C++, Javascript, and Python. The point with this is that you can include GF-based parsing and generation in
|
|
||||||
larger programs written in any of these languages.
|
|
||||||
|
|
||||||
A **resource grammar library**, containing the morphology and basic syntax of currently 26 languages.
|
|
||||||
|
|
||||||
A **web application toolkit**, containing server-side (Haskell) and client-side (Javascript) libraries.
|
|
||||||
|
|
||||||
An **integrated development environment**, the GF-Eclipse plug-in.
|
|
||||||
|
|
||||||
A **shell**, i.e. a command interpreter for testing and developing GF grammars. This is the program started by the command ``gf`` in a terminal.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
===Is GF open-source?===
|
|
||||||
|
|
||||||
|
|
||||||
===Can I use GF for commercial applications?===
|
|
||||||
|
|
||||||
Yes. Those parts of GF that you will need to distribute - the run-time system and the libraries - are licensed under LGPL and BSD; it's up to you to choose which.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
===When was GF started?===
|
|
||||||
|
|
||||||
|
|
||||||
===Where does the name GF come from?===
|
|
||||||
|
|
||||||
GF = Grammatical Framework = LF + concrete syntax
|
|
||||||
|
|
||||||
LF = Logical Framework
|
|
||||||
|
|
||||||
Logical Frameworks are implementations of type theory, which have been built since the 1980's to support formalized mathematics. GF has its roots in
|
|
||||||
type theory, which is widely used in the semantics of natural language. Some of these ideas were first implemented in ALF, Another Logical Framework,
|
|
||||||
in 1992; the book //Type-Theoretical Grammar// (by A. Ranta, OUP 1994) has a chapter and an appendix on this. The first implementations did not have
|
|
||||||
a parser, and GF proper, started in 1998, was an implementation of yet another LF together with concrete syntax supporting generation and parsing.
|
|
||||||
Grammatical Framework was a natural name for this. We tried to avoid it in the beginning, because it sounded pretentious in its generality. But the
|
|
||||||
name was just too natural to be avoided.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
===Is GF backward compatible?===
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
===Do I need Haskell to use GF?===
|
|
||||||
|
|
||||||
No. GF is a language of its own, and you don't need to know Haskell. And if you download the GF binary, you don't need any Haskell tools. But if you want to
|
|
||||||
become a GF developer, then it's better you install GF from the latest source, and then you need the GHC Haskell compiler to compile GF. But even then, you
|
|
||||||
don't need to know Haskell yourself.
|
|
||||||
|
|
||||||
|
|
||||||
===What is a lock field?===
|
|
||||||
|
|
||||||
@@ -68,9 +68,9 @@ metavariables and the type of the expression.
|
|||||||
Prints a set of strings in the .dot format (the graphviz format).
|
Prints a set of strings in the .dot format (the graphviz format).
|
||||||
The graph can be saved in a file by the wf command as usual.
|
The graph can be saved in a file by the wf command as usual.
|
||||||
If the -view flag is defined, the graph is saved in a temporary file
|
If the -view flag is defined, the graph is saved in a temporary file
|
||||||
which is processed by graphviz and displayed by the program indicated
|
which is processed by 'dot' (graphviz) and displayed by the program indicated
|
||||||
by the flag. The target format is postscript, unless overridden by the
|
by the view flag. The target format is png, unless overridden by the
|
||||||
flag -format.
|
flag -format. Results from multiple trees are combined to pdf with convert (ImageMagick).
|
||||||
|
|
||||||
|
|
||||||
- Options:
|
- Options:
|
||||||
@@ -151,6 +151,7 @@ of a pipe.
|
|||||||
| ``-one`` | pick the first strings, if there is any, from records and tables
|
| ``-one`` | pick the first strings, if there is any, from records and tables
|
||||||
| ``-table`` | show all strings labelled by parameters
|
| ``-table`` | show all strings labelled by parameters
|
||||||
| ``-unqual`` | hide qualifying module names
|
| ``-unqual`` | hide qualifying module names
|
||||||
|
| ``-trace`` | trace computations
|
||||||
|
|
||||||
|
|
||||||
#NORMAL
|
#NORMAL
|
||||||
@@ -242,7 +243,7 @@ and thus cannot be a part of a pipe.
|
|||||||
|
|
||||||
====e = empty====
|
====e = empty====
|
||||||
#NOINDENT
|
#NOINDENT
|
||||||
``e`` = ``empty``: //empty the environment.//
|
``e`` = ``empty``: //empty the environment (except the command history).//
|
||||||
|
|
||||||
#TINY
|
#TINY
|
||||||
|
|
||||||
@@ -281,6 +282,19 @@ but the resulting .gf file must be imported separately.
|
|||||||
#NORMAL
|
#NORMAL
|
||||||
|
|
||||||
|
|
||||||
|
#VSPACE
|
||||||
|
|
||||||
|
====eh = execute_history====
|
||||||
|
#NOINDENT
|
||||||
|
``eh`` = ``execute_history``: //read commands from a file and execute them.//
|
||||||
|
|
||||||
|
#TINY
|
||||||
|
|
||||||
|
- Syntax: ``eh FILE``
|
||||||
|
|
||||||
|
#NORMAL
|
||||||
|
|
||||||
|
|
||||||
#VSPACE
|
#VSPACE
|
||||||
|
|
||||||
====gr = generate_random====
|
====gr = generate_random====
|
||||||
@@ -434,12 +448,14 @@ sequences; see example.
|
|||||||
| ``-list`` | show all forms and variants, comma-separated on one line (cf. l -all)
|
| ``-list`` | show all forms and variants, comma-separated on one line (cf. l -all)
|
||||||
| ``-multi`` | linearize to all languages (default)
|
| ``-multi`` | linearize to all languages (default)
|
||||||
| ``-table`` | show all forms labelled by parameters
|
| ``-table`` | show all forms labelled by parameters
|
||||||
|
| ``-tabtreebank`` | show the tree and its linearizations on a tab-separated line
|
||||||
| ``-treebank`` | show the tree and tag linearizations with language names
|
| ``-treebank`` | show the tree and tag linearizations with language names
|
||||||
| ``-bind`` | bind tokens separated by Prelude.BIND, i.e. &+
|
| ``-bind`` | bind tokens separated by Prelude.BIND, i.e. &+
|
||||||
| ``-chars`` | lexer that makes every non-space character a token
|
| ``-chars`` | lexer that makes every non-space character a token
|
||||||
| ``-from_amharic`` | from unicode to GF Amharic transliteration
|
| ``-from_amharic`` | from unicode to GF Amharic transliteration
|
||||||
| ``-from_ancientgreek`` | from unicode to GF ancient Greek transliteration
|
| ``-from_ancientgreek`` | from unicode to GF ancient Greek transliteration
|
||||||
| ``-from_arabic`` | from unicode to GF Arabic transliteration
|
| ``-from_arabic`` | from unicode to GF Arabic transliteration
|
||||||
|
| ``-from_arabic_unvocalized`` | from unicode to GF unvocalized Arabic transliteration
|
||||||
| ``-from_cp1251`` | decode from cp1251 (Cyrillic used in Bulgarian resource)
|
| ``-from_cp1251`` | decode from cp1251 (Cyrillic used in Bulgarian resource)
|
||||||
| ``-from_devanagari`` | from unicode to GF Devanagari transliteration
|
| ``-from_devanagari`` | from unicode to GF Devanagari transliteration
|
||||||
| ``-from_greek`` | from unicode to GF modern Greek transliteration
|
| ``-from_greek`` | from unicode to GF modern Greek transliteration
|
||||||
@@ -453,11 +469,14 @@ sequences; see example.
|
|||||||
| ``-from_urdu`` | from unicode to GF Urdu transliteration
|
| ``-from_urdu`` | from unicode to GF Urdu transliteration
|
||||||
| ``-from_utf8`` | decode from utf8 (default)
|
| ``-from_utf8`` | decode from utf8 (default)
|
||||||
| ``-lexcode`` | code-like lexer
|
| ``-lexcode`` | code-like lexer
|
||||||
|
| ``-lexgreek`` | lexer normalizing ancient Greek accentuation
|
||||||
|
| ``-lexgreek2`` | lexer normalizing ancient Greek accentuation for text with vowel length annotations
|
||||||
| ``-lexmixed`` | mixture of text and code, as in LaTeX (code between $...$, \(...)\, \[...\])
|
| ``-lexmixed`` | mixture of text and code, as in LaTeX (code between $...$, \(...)\, \[...\])
|
||||||
| ``-lextext`` | text-like lexer
|
| ``-lextext`` | text-like lexer
|
||||||
| ``-to_amharic`` | from GF Amharic transliteration to unicode
|
| ``-to_amharic`` | from GF Amharic transliteration to unicode
|
||||||
| ``-to_ancientgreek`` | from GF ancient Greek transliteration to unicode
|
| ``-to_ancientgreek`` | from GF ancient Greek transliteration to unicode
|
||||||
| ``-to_arabic`` | from GF Arabic transliteration to unicode
|
| ``-to_arabic`` | from GF Arabic transliteration to unicode
|
||||||
|
| ``-to_arabic_unvocalized`` | from GF unvocalized Arabic transliteration to unicode
|
||||||
| ``-to_cp1251`` | encode to cp1251 (Cyrillic used in Bulgarian resource)
|
| ``-to_cp1251`` | encode to cp1251 (Cyrillic used in Bulgarian resource)
|
||||||
| ``-to_devanagari`` | from GF Devanagari transliteration to unicode
|
| ``-to_devanagari`` | from GF Devanagari transliteration to unicode
|
||||||
| ``-to_greek`` | from GF modern Greek transliteration to unicode
|
| ``-to_greek`` | from GF modern Greek transliteration to unicode
|
||||||
@@ -473,6 +492,7 @@ sequences; see example.
|
|||||||
| ``-to_utf8`` | encode to utf8 (default)
|
| ``-to_utf8`` | encode to utf8 (default)
|
||||||
| ``-unchars`` | unlexer that puts no spaces between tokens
|
| ``-unchars`` | unlexer that puts no spaces between tokens
|
||||||
| ``-unlexcode`` | code-like unlexer
|
| ``-unlexcode`` | code-like unlexer
|
||||||
|
| ``-unlexgreek`` | unlexer de-normalizing ancient Greek accentuation
|
||||||
| ``-unlexmixed`` | mixture of text and code (code between $...$, \(...)\, \[...\])
|
| ``-unlexmixed`` | mixture of text and code (code between $...$, \(...)\, \[...\])
|
||||||
| ``-unlextext`` | text-like unlexer
|
| ``-unlextext`` | text-like unlexer
|
||||||
| ``-unwords`` | unlexer that puts a single space between tokens (default)
|
| ``-unwords`` | unlexer that puts a single space between tokens (default)
|
||||||
@@ -513,6 +533,7 @@ trees where a function node is a metavariable.
|
|||||||
| ``-from_amharic`` | from unicode to GF Amharic transliteration
|
| ``-from_amharic`` | from unicode to GF Amharic transliteration
|
||||||
| ``-from_ancientgreek`` | from unicode to GF ancient Greek transliteration
|
| ``-from_ancientgreek`` | from unicode to GF ancient Greek transliteration
|
||||||
| ``-from_arabic`` | from unicode to GF Arabic transliteration
|
| ``-from_arabic`` | from unicode to GF Arabic transliteration
|
||||||
|
| ``-from_arabic_unvocalized`` | from unicode to GF unvocalized Arabic transliteration
|
||||||
| ``-from_cp1251`` | decode from cp1251 (Cyrillic used in Bulgarian resource)
|
| ``-from_cp1251`` | decode from cp1251 (Cyrillic used in Bulgarian resource)
|
||||||
| ``-from_devanagari`` | from unicode to GF Devanagari transliteration
|
| ``-from_devanagari`` | from unicode to GF Devanagari transliteration
|
||||||
| ``-from_greek`` | from unicode to GF modern Greek transliteration
|
| ``-from_greek`` | from unicode to GF modern Greek transliteration
|
||||||
@@ -526,11 +547,14 @@ trees where a function node is a metavariable.
|
|||||||
| ``-from_urdu`` | from unicode to GF Urdu transliteration
|
| ``-from_urdu`` | from unicode to GF Urdu transliteration
|
||||||
| ``-from_utf8`` | decode from utf8 (default)
|
| ``-from_utf8`` | decode from utf8 (default)
|
||||||
| ``-lexcode`` | code-like lexer
|
| ``-lexcode`` | code-like lexer
|
||||||
|
| ``-lexgreek`` | lexer normalizing ancient Greek accentuation
|
||||||
|
| ``-lexgreek2`` | lexer normalizing ancient Greek accentuation for text with vowel length annotations
|
||||||
| ``-lexmixed`` | mixture of text and code, as in LaTeX (code between $...$, \(...)\, \[...\])
|
| ``-lexmixed`` | mixture of text and code, as in LaTeX (code between $...$, \(...)\, \[...\])
|
||||||
| ``-lextext`` | text-like lexer
|
| ``-lextext`` | text-like lexer
|
||||||
| ``-to_amharic`` | from GF Amharic transliteration to unicode
|
| ``-to_amharic`` | from GF Amharic transliteration to unicode
|
||||||
| ``-to_ancientgreek`` | from GF ancient Greek transliteration to unicode
|
| ``-to_ancientgreek`` | from GF ancient Greek transliteration to unicode
|
||||||
| ``-to_arabic`` | from GF Arabic transliteration to unicode
|
| ``-to_arabic`` | from GF Arabic transliteration to unicode
|
||||||
|
| ``-to_arabic_unvocalized`` | from GF unvocalized Arabic transliteration to unicode
|
||||||
| ``-to_cp1251`` | encode to cp1251 (Cyrillic used in Bulgarian resource)
|
| ``-to_cp1251`` | encode to cp1251 (Cyrillic used in Bulgarian resource)
|
||||||
| ``-to_devanagari`` | from GF Devanagari transliteration to unicode
|
| ``-to_devanagari`` | from GF Devanagari transliteration to unicode
|
||||||
| ``-to_greek`` | from GF modern Greek transliteration to unicode
|
| ``-to_greek`` | from GF modern Greek transliteration to unicode
|
||||||
@@ -546,6 +570,7 @@ trees where a function node is a metavariable.
|
|||||||
| ``-to_utf8`` | encode to utf8 (default)
|
| ``-to_utf8`` | encode to utf8 (default)
|
||||||
| ``-unchars`` | unlexer that puts no spaces between tokens
|
| ``-unchars`` | unlexer that puts no spaces between tokens
|
||||||
| ``-unlexcode`` | code-like unlexer
|
| ``-unlexcode`` | code-like unlexer
|
||||||
|
| ``-unlexgreek`` | unlexer de-normalizing ancient Greek accentuation
|
||||||
| ``-unlexmixed`` | mixture of text and code (code between $...$, \(...)\, \[...\])
|
| ``-unlexmixed`` | mixture of text and code (code between $...$, \(...)\, \[...\])
|
||||||
| ``-unlextext`` | text-like unlexer
|
| ``-unlextext`` | text-like unlexer
|
||||||
| ``-unwords`` | unlexer that puts a single space between tokens (default)
|
| ``-unwords`` | unlexer that puts a single space between tokens (default)
|
||||||
@@ -666,10 +691,9 @@ command (flag -printer):
|
|||||||
fa finite automaton in graphviz format
|
fa finite automaton in graphviz format
|
||||||
gsl Nuance speech recognition format
|
gsl Nuance speech recognition format
|
||||||
haskell Haskell (abstract syntax)
|
haskell Haskell (abstract syntax)
|
||||||
|
java Java (abstract syntax)
|
||||||
js JavaScript (whole grammar)
|
js JavaScript (whole grammar)
|
||||||
jsgf JSGF speech recognition format
|
jsgf JSGF speech recognition format
|
||||||
lambda_prolog LambdaProlog (abstract syntax)
|
|
||||||
lp_byte_code Bytecode for Teyjus (abstract syntax, experimental)
|
|
||||||
pgf_pretty human-readable pgf
|
pgf_pretty human-readable pgf
|
||||||
prolog Prolog (whole grammar)
|
prolog Prolog (whole grammar)
|
||||||
python Python (whole grammar)
|
python Python (whole grammar)
|
||||||
@@ -753,6 +777,7 @@ To see transliteration tables, use command ut.
|
|||||||
| ``-from_amharic`` | from unicode to GF Amharic transliteration
|
| ``-from_amharic`` | from unicode to GF Amharic transliteration
|
||||||
| ``-from_ancientgreek`` | from unicode to GF ancient Greek transliteration
|
| ``-from_ancientgreek`` | from unicode to GF ancient Greek transliteration
|
||||||
| ``-from_arabic`` | from unicode to GF Arabic transliteration
|
| ``-from_arabic`` | from unicode to GF Arabic transliteration
|
||||||
|
| ``-from_arabic_unvocalized`` | from unicode to GF unvocalized Arabic transliteration
|
||||||
| ``-from_cp1251`` | decode from cp1251 (Cyrillic used in Bulgarian resource)
|
| ``-from_cp1251`` | decode from cp1251 (Cyrillic used in Bulgarian resource)
|
||||||
| ``-from_devanagari`` | from unicode to GF Devanagari transliteration
|
| ``-from_devanagari`` | from unicode to GF Devanagari transliteration
|
||||||
| ``-from_greek`` | from unicode to GF modern Greek transliteration
|
| ``-from_greek`` | from unicode to GF modern Greek transliteration
|
||||||
@@ -766,11 +791,14 @@ To see transliteration tables, use command ut.
|
|||||||
| ``-from_urdu`` | from unicode to GF Urdu transliteration
|
| ``-from_urdu`` | from unicode to GF Urdu transliteration
|
||||||
| ``-from_utf8`` | decode from utf8 (default)
|
| ``-from_utf8`` | decode from utf8 (default)
|
||||||
| ``-lexcode`` | code-like lexer
|
| ``-lexcode`` | code-like lexer
|
||||||
|
| ``-lexgreek`` | lexer normalizing ancient Greek accentuation
|
||||||
|
| ``-lexgreek2`` | lexer normalizing ancient Greek accentuation for text with vowel length annotations
|
||||||
| ``-lexmixed`` | mixture of text and code, as in LaTeX (code between $...$, \(...)\, \[...\])
|
| ``-lexmixed`` | mixture of text and code, as in LaTeX (code between $...$, \(...)\, \[...\])
|
||||||
| ``-lextext`` | text-like lexer
|
| ``-lextext`` | text-like lexer
|
||||||
| ``-to_amharic`` | from GF Amharic transliteration to unicode
|
| ``-to_amharic`` | from GF Amharic transliteration to unicode
|
||||||
| ``-to_ancientgreek`` | from GF ancient Greek transliteration to unicode
|
| ``-to_ancientgreek`` | from GF ancient Greek transliteration to unicode
|
||||||
| ``-to_arabic`` | from GF Arabic transliteration to unicode
|
| ``-to_arabic`` | from GF Arabic transliteration to unicode
|
||||||
|
| ``-to_arabic_unvocalized`` | from GF unvocalized Arabic transliteration to unicode
|
||||||
| ``-to_cp1251`` | encode to cp1251 (Cyrillic used in Bulgarian resource)
|
| ``-to_cp1251`` | encode to cp1251 (Cyrillic used in Bulgarian resource)
|
||||||
| ``-to_devanagari`` | from GF Devanagari transliteration to unicode
|
| ``-to_devanagari`` | from GF Devanagari transliteration to unicode
|
||||||
| ``-to_greek`` | from GF modern Greek transliteration to unicode
|
| ``-to_greek`` | from GF modern Greek transliteration to unicode
|
||||||
@@ -786,6 +814,7 @@ To see transliteration tables, use command ut.
|
|||||||
| ``-to_utf8`` | encode to utf8 (default)
|
| ``-to_utf8`` | encode to utf8 (default)
|
||||||
| ``-unchars`` | unlexer that puts no spaces between tokens
|
| ``-unchars`` | unlexer that puts no spaces between tokens
|
||||||
| ``-unlexcode`` | code-like unlexer
|
| ``-unlexcode`` | code-like unlexer
|
||||||
|
| ``-unlexgreek`` | unlexer de-normalizing ancient Greek accentuation
|
||||||
| ``-unlexmixed`` | mixture of text and code (code between $...$, \(...)\, \[...\])
|
| ``-unlexmixed`` | mixture of text and code (code between $...$, \(...)\, \[...\])
|
||||||
| ``-unlextext`` | text-like unlexer
|
| ``-unlextext`` | text-like unlexer
|
||||||
| ``-unwords`` | unlexer that puts a single space between tokens (default)
|
| ``-unwords`` | unlexer that puts a single space between tokens (default)
|
||||||
@@ -799,13 +828,14 @@ To see transliteration tables, use command ut.
|
|||||||
|
|
||||||
- Examples:
|
- Examples:
|
||||||
|
|
||||||
| ``l (EAdd 3 4) | ps -code`` | linearize code-like output
|
| ``l (EAdd 3 4) | ps -unlexcode`` | linearize code-like output
|
||||||
| ``ps -lexer=code | p -cat=Exp`` | parse code-like input
|
| ``ps -lexcode | p -cat=Exp`` | parse code-like input
|
||||||
| ``gr -cat=QCl | l | ps -bind`` | linearization output from LangFin
|
| ``gr -cat=QCl | l | ps -bind`` | linearization output from LangFin
|
||||||
| ``ps -to_devanagari "A-p"`` | show Devanagari in UTF8 terminal
|
| ``ps -to_devanagari "A-p"`` | show Devanagari in UTF8 terminal
|
||||||
| ``rf -file=Hin.gf | ps -env=quotes -to_devanagari`` | convert translit to UTF8
|
| ``rf -file=Hin.gf | ps -env=quotes -to_devanagari`` | convert translit to UTF8
|
||||||
| ``rf -file=Ara.gf | ps -from_utf8 -env=quotes -from_arabic`` | convert UTF8 to transliteration
|
| ``rf -file=Ara.gf | ps -from_utf8 -env=quotes -from_arabic`` | convert UTF8 to transliteration
|
||||||
| ``ps -to=chinese.trans "abc"`` | apply transliteration defined in file chinese.trans
|
| ``ps -to=chinese.trans "abc"`` | apply transliteration defined in file chinese.trans
|
||||||
|
| ``ps -lexgreek "a)gavoi` a)'nvrwpoi' tines*"`` | normalize ancient greek accentuation
|
||||||
|
|
||||||
|
|
||||||
#NORMAL
|
#NORMAL
|
||||||
@@ -828,7 +858,6 @@ are type checking and semantic computation.
|
|||||||
- Options:
|
- Options:
|
||||||
|
|
||||||
| ``-compute`` | compute by using semantic definitions (def)
|
| ``-compute`` | compute by using semantic definitions (def)
|
||||||
| ``-paraphrase`` | paraphrase by using semantic definitions (def)
|
|
||||||
| ``-largest`` | sort trees from largest to smallest, in number of nodes
|
| ``-largest`` | sort trees from largest to smallest, in number of nodes
|
||||||
| ``-nub`` | remove duplicate trees
|
| ``-nub`` | remove duplicate trees
|
||||||
| ``-smallest`` | sort trees from smallest to largest, in number of nodes
|
| ``-smallest`` | sort trees from smallest to largest, in number of nodes
|
||||||
@@ -838,12 +867,10 @@ are type checking and semantic computation.
|
|||||||
- Flags:
|
- Flags:
|
||||||
|
|
||||||
| ``-number`` | take at most this many trees
|
| ``-number`` | take at most this many trees
|
||||||
| ``-transfer`` | syntactic transfer by applying function, recursively in subtrees
|
|
||||||
|
|
||||||
- Examples:
|
- Examples:
|
||||||
|
|
||||||
| ``pt -compute (plus one two)`` | compute value
|
| ``pt -compute (plus one two)`` | compute value
|
||||||
| ``p "4 dogs love 5 cats" | pt -transfer=digits2numeral | l`` | four...five...
|
|
||||||
|
|
||||||
|
|
||||||
#NORMAL
|
#NORMAL
|
||||||
@@ -990,8 +1017,6 @@ This command requires a source grammar to be in scope, imported with 'import -re
|
|||||||
The operations include the parameter constructors that are in scope.
|
The operations include the parameter constructors that are in scope.
|
||||||
The optional TYPE filters according to the value type.
|
The optional TYPE filters according to the value type.
|
||||||
The grep STRINGs filter according to other substrings of the type signatures.
|
The grep STRINGs filter according to other substrings of the type signatures.
|
||||||
This command must be a line of its own, and thus cannot be a part
|
|
||||||
of a pipe.
|
|
||||||
|
|
||||||
- Syntax: ``so (-grep=STRING)* TYPE?``
|
- Syntax: ``so (-grep=STRING)* TYPE?``
|
||||||
- Options:
|
- Options:
|
||||||
@@ -1002,6 +1027,12 @@ of a pipe.
|
|||||||
|
|
||||||
| ``-grep`` | substring used for filtering (the command can have many of these)
|
| ``-grep`` | substring used for filtering (the command can have many of these)
|
||||||
|
|
||||||
|
- Examples:
|
||||||
|
|
||||||
|
| ``so Det`` | show all opers that create a Det
|
||||||
|
| ``so -grep=Prep`` | find opers relating to Prep
|
||||||
|
| ``so | wf -file=/tmp/opers`` | write the list of opers to a file
|
||||||
|
|
||||||
|
|
||||||
#NORMAL
|
#NORMAL
|
||||||
|
|
||||||
@@ -1113,6 +1144,7 @@ This command must be a line of its own, and thus cannot be a part of a pipe.
|
|||||||
| ``-amharic`` | Amharic
|
| ``-amharic`` | Amharic
|
||||||
| ``-ancientgreek`` | ancient Greek
|
| ``-ancientgreek`` | ancient Greek
|
||||||
| ``-arabic`` | Arabic
|
| ``-arabic`` | Arabic
|
||||||
|
| ``-arabic_unvocalized`` | unvocalized Arabic
|
||||||
| ``-devanagari`` | Devanagari
|
| ``-devanagari`` | Devanagari
|
||||||
| ``-greek`` | modern Greek
|
| ``-greek`` | modern Greek
|
||||||
| ``-hebrew`` | unvocalized Hebrew
|
| ``-hebrew`` | unvocalized Hebrew
|
||||||
@@ -1137,35 +1169,41 @@ This command must be a line of its own, and thus cannot be a part of a pipe.
|
|||||||
#TINY
|
#TINY
|
||||||
|
|
||||||
Prints a dependency tree in the .dot format (the graphviz format, default)
|
Prints a dependency tree in the .dot format (the graphviz format, default)
|
||||||
|
or LaTeX (flag -output=latex)
|
||||||
or the CoNLL/MaltParser format (flag -output=conll for training, malt_input
|
or the CoNLL/MaltParser format (flag -output=conll for training, malt_input
|
||||||
for unanalysed input).
|
for unanalysed input).
|
||||||
By default, the last argument is the head of every abstract syntax
|
By default, the last argument is the head of every abstract syntax
|
||||||
function; moreover, the head depends on the head of the function above.
|
function; moreover, the head depends on the head of the function above.
|
||||||
The graph can be saved in a file by the wf command as usual.
|
The graph can be saved in a file by the wf command as usual.
|
||||||
If the -view flag is defined, the graph is saved in a temporary file
|
If the -view flag is defined, the graph is saved in a temporary file
|
||||||
which is processed by graphviz and displayed by the program indicated
|
which is processed by dot (graphviz) and displayed by the program indicated
|
||||||
by the flag. The target format is png, unless overridden by the
|
by the view flag. The target format is png, unless overridden by the
|
||||||
flag -format.
|
flag -format. Results from multiple trees are combined to pdf with convert (ImageMagick).
|
||||||
|
See also 'vp -showdep' for another visualization of dependencies.
|
||||||
|
|
||||||
|
|
||||||
- Options:
|
- Options:
|
||||||
|
|
||||||
| ``-v`` | show extra information
|
| ``-v`` | show extra information
|
||||||
|
| ``-conll2latex`` | convert conll to latex
|
||||||
|
|
||||||
- Flags:
|
- Flags:
|
||||||
|
|
||||||
| ``-file`` | configuration file for labels per fun, format 'fun l1 ... label ... l2'
|
| ``-abslabels`` | abstract configuration file for labels, format per line 'fun label*'
|
||||||
| ``-format`` | format of the visualization file (default "png")
|
| ``-cnclabels`` | concrete configuration file for labels, format per line 'fun {words|*} pos label head'
|
||||||
| ``-output`` | output format of graph source (default "dot")
|
| ``-file`` | same as abslabels (abstract configuration file)
|
||||||
| ``-view`` | program to open the resulting file (default "open")
|
| ``-format`` | format of the visualization file using dot (default "png")
|
||||||
|
| ``-output`` | output format of graph source (latex, conll, dot (default but deprecated))
|
||||||
|
| ``-view`` | program to open the resulting graph file (default "open")
|
||||||
| ``-lang`` | the language of analysis
|
| ``-lang`` | the language of analysis
|
||||||
|
|
||||||
- Examples:
|
- Examples:
|
||||||
|
|
||||||
| ``gr | vd`` | generate a tree and show dependency tree in .dot
|
| ``gr | vd`` | generate a tree and show dependency tree in .dot
|
||||||
| ``gr | vd -view=open`` | generate a tree and display dependency tree on a Mac
|
| ``gr | vd -view=open`` | generate a tree and display dependency tree on with Mac's 'open'
|
||||||
| ``gr -number=1000 | vd -file=dep.labels -output=malt`` | generate training treebank
|
| ``gr | vd -view=open -output=latex`` | generate a tree and display latex dependency tree with Mac's 'open'
|
||||||
| ``gr -number=100 | vd -file=dep.labels -output=malt_input`` | generate test sentences
|
| ``gr -number=1000 | vd -abslabels=Lang.labels -cnclabels=LangSwe.labels -output=conll`` | generate a random treebank
|
||||||
|
| ``rf -file=ex.conll | vd -conll2latex | wf -file=ex.tex`` | convert conll file to latex
|
||||||
|
|
||||||
|
|
||||||
#NORMAL
|
#NORMAL
|
||||||
@@ -1182,15 +1220,16 @@ flag -format.
|
|||||||
Prints a parse tree in the .dot format (the graphviz format).
|
Prints a parse tree in the .dot format (the graphviz format).
|
||||||
The graph can be saved in a file by the wf command as usual.
|
The graph can be saved in a file by the wf command as usual.
|
||||||
If the -view flag is defined, the graph is saved in a temporary file
|
If the -view flag is defined, the graph is saved in a temporary file
|
||||||
which is processed by graphviz and displayed by the program indicated
|
which is processed by dot (graphviz) and displayed by the program indicated
|
||||||
by the flag. The target format is png, unless overridden by the
|
by the view flag. The target format is png, unless overridden by the
|
||||||
flag -format.
|
flag -format. Results from multiple trees are combined to pdf with convert (ImageMagick).
|
||||||
|
|
||||||
|
|
||||||
- Options:
|
- Options:
|
||||||
|
|
||||||
| ``-showcat`` | show categories in the tree nodes (default)
|
| ``-showcat`` | show categories in the tree nodes (default)
|
||||||
| ``-nocat`` | don't show categories
|
| ``-nocat`` | don't show categories
|
||||||
|
| ``-showdep`` | show dependency labels
|
||||||
| ``-showfun`` | show function names in the tree nodes
|
| ``-showfun`` | show function names in the tree nodes
|
||||||
| ``-nofun`` | don't show function names (default)
|
| ``-nofun`` | don't show function names (default)
|
||||||
| ``-showleaves`` | show the leaves of the tree (default)
|
| ``-showleaves`` | show the leaves of the tree (default)
|
||||||
@@ -1198,6 +1237,8 @@ flag -format.
|
|||||||
|
|
||||||
- Flags:
|
- Flags:
|
||||||
|
|
||||||
|
| ``-lang`` | the language to visualize
|
||||||
|
| ``-file`` | configuration file for dependency labels with -deps, format per line 'fun label*'
|
||||||
| ``-format`` | format of the visualization file (default "png")
|
| ``-format`` | format of the visualization file (default "png")
|
||||||
| ``-view`` | program to open the resulting file (default "open")
|
| ``-view`` | program to open the resulting file (default "open")
|
||||||
| ``-nodefont`` | font for tree nodes (default: Times -- graphviz standard font)
|
| ``-nodefont`` | font for tree nodes (default: Times -- graphviz standard font)
|
||||||
@@ -1210,7 +1251,8 @@ flag -format.
|
|||||||
- Examples:
|
- Examples:
|
||||||
|
|
||||||
| ``p "John walks" | vp`` | generate a tree and show parse tree as .dot script
|
| ``p "John walks" | vp`` | generate a tree and show parse tree as .dot script
|
||||||
| ``gr | vp -view="open"`` | generate a tree and display parse tree on a Mac
|
| ``gr | vp -view=open`` | generate a tree and display parse tree on a Mac
|
||||||
|
| ``p "she loves us" | vp -view=open -showdep -file=uddeps.labels -nocat`` | show a visual variant of a dependency tree
|
||||||
|
|
||||||
|
|
||||||
#NORMAL
|
#NORMAL
|
||||||
@@ -1227,9 +1269,9 @@ flag -format.
|
|||||||
Prints a set of trees in the .dot format (the graphviz format).
|
Prints a set of trees in the .dot format (the graphviz format).
|
||||||
The graph can be saved in a file by the wf command as usual.
|
The graph can be saved in a file by the wf command as usual.
|
||||||
If the -view flag is defined, the graph is saved in a temporary file
|
If the -view flag is defined, the graph is saved in a temporary file
|
||||||
which is processed by graphviz and displayed by the program indicated
|
which is processed by dot (graphviz) and displayed by the command indicated
|
||||||
by the flag. The target format is postscript, unless overridden by the
|
by the view flag. The target format is postscript, unless overridden by the
|
||||||
flag -format.
|
flag -format. Results from multiple trees are combined to pdf with convert (ImageMagick).
|
||||||
With option -mk, use for showing library style function names of form 'mkC'.
|
With option -mk, use for showing library style function names of form 'mkC'.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,132 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>GF People</title>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<link rel=stylesheet href="../css/style.css">
|
|
||||||
<meta name = "viewport" content = "width = device-width">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<center>
|
|
||||||
<IMG SRC="Logos/gf0.png" alt="[GF]">
|
|
||||||
|
|
||||||
<h1>Grammatical Framework: Authors and Acknowledgements</h1>
|
|
||||||
|
|
||||||
</center>
|
|
||||||
|
|
||||||
The current developers and maintainers are
|
|
||||||
<a href="http://www.chalmers.se/cse/EN/organization/divisions/computing-science/people/angelov-krasimir">Krasimir Angelov</a>,
|
|
||||||
<a href="http://www.cse.chalmers.se/~hallgren/">Thomas Hallgren</a>,
|
|
||||||
and
|
|
||||||
<a href="http://www.cse.chalmers.se/~aarne/">Aarne Ranta</a>. Bug reports should be
|
|
||||||
posted via the
|
|
||||||
<a href="http://code.google.com/p/grammatical-framework/issues/list">GF bug tracker</a>.
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
Also the following people have contributed code to some of the versions:
|
|
||||||
|
|
||||||
<dl>
|
|
||||||
|
|
||||||
<dt>Grégoire Détrez (University of Gothenburg)
|
|
||||||
<dt>Ramona Enache (University of Gothenburg)
|
|
||||||
<dt>
|
|
||||||
<a href="http://www.cse.chalmers.se/alumni/bringert">Björn Bringert</a> (University of Gothenburg)
|
|
||||||
<dt>
|
|
||||||
Håkan Burden (University of Gothenburg)
|
|
||||||
<dt>
|
|
||||||
Hans-Joachim Daniels (Karlsruhe)
|
|
||||||
<dt>
|
|
||||||
<a href="http://www.cs.chalmers.se/~markus">Markus Forsberg</a> (Chalmers)
|
|
||||||
<dt>
|
|
||||||
<a href="http://www.cs.chalmers.se/~krijo">Kristofer Johannisson</a> (University of Gothenburg)
|
|
||||||
<dt>
|
|
||||||
<a href="http://www.cs.chalmers.se/~janna">Janna Khegai</a> (Chalmers)
|
|
||||||
<dt>
|
|
||||||
<a href="http://www.cse.chalmers.se/~peb">Peter Ljunglöf</a> (University of Gothenburg)
|
|
||||||
<dt>
|
|
||||||
Petri Mäenpää (Nokia)
|
|
||||||
</dl>
|
|
||||||
|
|
||||||
|
|
||||||
At least the following colleagues are thanked for suggestions,
|
|
||||||
bug reports, and other indirect contributions to the code. (Notice:
|
|
||||||
these are early contributors - the list has not been updated since 2004 or so).
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<a href="http://www.di.unito.it/~stefano/">Stefano Berardi</a> (Torino),
|
|
||||||
|
|
||||||
Pascal Boldini (Paris),
|
|
||||||
|
|
||||||
<a href="http://www.dur.ac.uk/~dcs0pcc/">Paul Callaghan</a> (Durham),
|
|
||||||
|
|
||||||
Lauri Carlson (Helsinki),
|
|
||||||
|
|
||||||
<a href="http://www.cse.chalmers.se/~koen">Koen Claessen</a> (Chalmers),
|
|
||||||
|
|
||||||
<a href="http://www.cling.gu.se/~cooper">Robin Cooper</a> (Gothenburg),
|
|
||||||
|
|
||||||
<a href="http://www.cse.chalmers.se/~coquand">Thierry Coquand</a> (Chalmers),
|
|
||||||
|
|
||||||
<a
|
|
||||||
href="http://www.xrce.xerox.com/people/dymetman/dymetman.html">Marc
|
|
||||||
Dymetman</a> (XRCE),
|
|
||||||
|
|
||||||
Bertrand Grégoire (Tudor Institure, Luxembourg),
|
|
||||||
|
|
||||||
<a href="http://www.cse.chalmers.se/~reiner">Reiner Hähnle</a> (Chalmers),
|
|
||||||
|
|
||||||
<a href="http://pauillac.inria.fr/~huet/">Gérard Huet</a> (INRIA),
|
|
||||||
|
|
||||||
<a href="http://www.cse.chalmers.se/~patrikj">Patrik Jansson</a> (Chalmers),
|
|
||||||
|
|
||||||
Bernard Jaulin (Paris),
|
|
||||||
|
|
||||||
<a href="http://www.xrce.xerox.com/people/karttunen/karttunen.html">
|
|
||||||
Lauri Karttunen</a> (PARC),
|
|
||||||
|
|
||||||
Matti Kinnunen (Nokia),
|
|
||||||
|
|
||||||
<a
|
|
||||||
href="http://www.xrce.xerox.com/people/lux/">Veronika
|
|
||||||
Lux</a> (XRCE),
|
|
||||||
|
|
||||||
Per Martin-Löf (Stockholm),
|
|
||||||
|
|
||||||
<a href="http://www.cse.chalmers.se/~bengt">Bengt Nordström</a> (Chalmers),
|
|
||||||
|
|
||||||
<a
|
|
||||||
href="http://www.cis.uni-muenchen.de/studenten/stud_homepages/okrslar/reklame.html">
|
|
||||||
Martin Okrslar</a> (CIS),
|
|
||||||
|
|
||||||
Jianmin Pang (Durham),
|
|
||||||
|
|
||||||
<a
|
|
||||||
href="http://www.xrce.xerox.com/people/pogodalla/index.fr.html">Sylvain
|
|
||||||
Pogodalla</a> (XRCE),
|
|
||||||
|
|
||||||
<a href="http://www.inria.fr/Loic.Pottier">Loïc Pottier</a> (INRIA),
|
|
||||||
|
|
||||||
|
|
||||||
<a href="http://www2.parc.com/istl/members/zaenen/">Annie Zaenen</a> (PARC)
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
The GF logo was designed by Uula Ranta.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
From 2001 to 2004, GF enjoyed funding from the
|
|
||||||
<a href="http://www.vinnova.se">Vinnova</a> foundation, within the
|
|
||||||
<a href="http://www.cse.chalmers.se/research/group/Language-technology/ILT.html">
|
|
||||||
Interactive Languge Technology</a> project.
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
63
doc/gf-people.md
Normal file
63
doc/gf-people.md
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
---
|
||||||
|
title: "Grammatical Framework: Authors and Acknowledgements"
|
||||||
|
---
|
||||||
|
|
||||||
|
## Current maintainers
|
||||||
|
|
||||||
|
The current maintainers of GF are
|
||||||
|
|
||||||
|
[Krasimir Angelov](http://www.chalmers.se/cse/EN/organization/divisions/computing-science/people/angelov-krasimir),
|
||||||
|
[Thomas Hallgren](http://www.cse.chalmers.se/~hallgren/),
|
||||||
|
[Aarne Ranta](http://www.cse.chalmers.se/~aarne/),
|
||||||
|
[John J. Camilleri](http://johnjcamilleri.com), and
|
||||||
|
[Inari Listenmaa](https://inariksit.github.io/).
|
||||||
|
|
||||||
|
This page is otherwise not up to date.
|
||||||
|
For detailed data about contributors to the code repositories since 2007, see
|
||||||
|
[here (gf-core)](https://github.com/GrammaticalFramework/gf-core/graphs/contributors)
|
||||||
|
and
|
||||||
|
[here (gf-rgl)](https://github.com/GrammaticalFramework/gf-rgl/graphs/contributors).
|
||||||
|
|
||||||
|
## Previous contributors
|
||||||
|
|
||||||
|
The following people have contributed code to some of the versions:
|
||||||
|
|
||||||
|
- Grégoire Détrez (University of Gothenburg)
|
||||||
|
- Ramona Enache (University of Gothenburg)
|
||||||
|
- [Björn Bringert](http://www.cse.chalmers.se/alumni/bringert) (University of Gothenburg)
|
||||||
|
- Håkan Burden (University of Gothenburg)
|
||||||
|
- Hans-Joachim Daniels (Karlsruhe)
|
||||||
|
- [Markus Forsberg](http://www.cs.chalmers.se/~markus) (Chalmers)
|
||||||
|
- [Kristofer Johannisson](http://www.cs.chalmers.se/~krijo) (University of Gothenburg)
|
||||||
|
- [Janna Khegai](http://www.cs.chalmers.se/~janna) (Chalmers)
|
||||||
|
- [Peter Ljunglöf](http://www.cse.chalmers.se/~peb) (University of Gothenburg)
|
||||||
|
- Petri Mäenpää (Nokia)
|
||||||
|
|
||||||
|
At least the following colleagues are thanked for suggestions, bug
|
||||||
|
reports, and other indirect contributions to the code.
|
||||||
|
|
||||||
|
- [Stefano Berardi](http://www.di.unito.it/~stefano/) (Torino)
|
||||||
|
- Pascal Boldini (Paris)
|
||||||
|
- [Paul Callaghan](http://www.dur.ac.uk/~dcs0pcc/) (Durham)
|
||||||
|
- Lauri Carlson (Helsinki)
|
||||||
|
- [Koen Claessen](http://www.cse.chalmers.se/~koen) (Chalmers)
|
||||||
|
- [Robin Cooper](http://www.cling.gu.se/~cooper) (Gothenburg)
|
||||||
|
- [Thierry Coquand](http://www.cse.chalmers.se/~coquand) (Chalmers)
|
||||||
|
- [Marc Dymetman](http://www.xrce.xerox.com/people/dymetman/dymetman.html) (XRCE)
|
||||||
|
- Bertrand Grégoire (Tudor Institute, Luxembourg)
|
||||||
|
- [Reiner Hähnle](http://www.cse.chalmers.se/~reiner) (Chalmers)
|
||||||
|
- [Gérard Huet](http://pauillac.inria.fr/~huet/) (INRIA)
|
||||||
|
- [Patrik Jansson](http://www.cse.chalmers.se/~patrikj) (Chalmers)
|
||||||
|
- Bernard Jaulin (Paris)
|
||||||
|
- [Lauri Karttunen](http://www.xrce.xerox.com/people/karttunen/karttunen.html) (PARC)
|
||||||
|
- Matti Kinnunen (Nokia)
|
||||||
|
- [Veronika Lux](http://www.xrce.xerox.com/people/lux/) (XRCE)
|
||||||
|
- Per Martin-Löf (Stockholm)
|
||||||
|
- [Bengt Nordström](http://www.cse.chalmers.se/~bengt) (Chalmers)
|
||||||
|
- [Martin Okrslar](http://www.cis.uni-muenchen.de/studenten/stud_homepages/okrslar/reklame.html) (CIS)
|
||||||
|
- Jianmin Pang (Durham)
|
||||||
|
- [Sylvain Pogodalla](http://www.xrce.xerox.com/people/pogodalla/index.fr.html) (XRCE)
|
||||||
|
- [Loïc Pottier](http://www.inria.fr/Loic.Pottier) (INRIA)
|
||||||
|
- [Annie Zaenen](http://www2.parc.com/istl/members/zaenen/) (PARC)
|
||||||
|
|
||||||
|
The GF logo was designed by Uula Ranta.
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>GF Quickstart</title>
|
|
||||||
<link rel=stylesheet href="../css/style.css">
|
|
||||||
<meta name = "viewport" content = "width = device-width">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<center>
|
|
||||||
<img src="Logos/gf0.png">
|
|
||||||
<p>
|
|
||||||
Aarne Ranta
|
|
||||||
<p>
|
|
||||||
October 2011 for GF 3.3
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<h1>Grammatical Framework Quick Start</h1>
|
|
||||||
|
|
||||||
</center>
|
|
||||||
|
|
||||||
This Quick Start shows a few examples of how GF can be used.
|
|
||||||
We assume that you have downloaded and installed GF, so that
|
|
||||||
the command <tt>gf</tt> works for you. See download and install
|
|
||||||
instructions <a href="../download/index.html">here</a>.
|
|
||||||
|
|
||||||
<h2>Want to try without downloading?</h2>
|
|
||||||
|
|
||||||
<a href="../demos/phrasebook/">Using GF translation</a> with an existing grammar.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<a href="../demos/gfse/">Writing GF grammars</a> in the cloud, without installing GF.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2>Using GF for translation and generation</h2>
|
|
||||||
|
|
||||||
When you have downloaded and installed GF:
|
|
||||||
<ol>
|
|
||||||
<li> Copy the files
|
|
||||||
<a href="../examples/tutorial/food/Food.gf"><tt>Food.gf</tt></a>,
|
|
||||||
<a href="../examples/tutorial/food/FoodEng.gf"><tt>FoodEng.gf</tt></a>, and
|
|
||||||
<a href="../examples/tutorial/food/FoodIta.gf"><tt>FoodIta.gf</tt></a>.
|
|
||||||
Or go to <tt>GF/examples/tutorial/food/</tt>, if you have downloaded the
|
|
||||||
GF sources.
|
|
||||||
|
|
||||||
<li> Start GF with the shell command (without the prompt <tt>$</tt>)
|
|
||||||
<pre>
|
|
||||||
$ gf FoodIta.gf FoodEng.gf
|
|
||||||
</pre>
|
|
||||||
Alternatively, start GF with <tt>gf</tt> and give the GF command <tt>import FoodIta.gf FoodEng.gf</tt>.
|
|
||||||
|
|
||||||
<li> <b>Translation</b>. Try your first translation by giving the GF command
|
|
||||||
<pre>
|
|
||||||
parse "this cheese is very very Italian" | linearize
|
|
||||||
</pre>
|
|
||||||
Notice that the parser accept the tabulator for word completion.
|
|
||||||
|
|
||||||
<li> <b>Generation</b>. Random-generate sentences in two languages:
|
|
||||||
<pre>
|
|
||||||
generate_random | linearize
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<li> <b>Other commands</b>. Use the help command
|
|
||||||
<pre>
|
|
||||||
help
|
|
||||||
</pre>
|
|
||||||
<li> <b>More examples</b>. Go to <tt>GF/examples/phrasebook</tt> or some other
|
|
||||||
subdirectory of <tt>GF/examples/</tt>. Or try a resource grammar by, for instance,
|
|
||||||
<pre>
|
|
||||||
import alltenses/LangEng.gfo alltenses/LangGer.gfo
|
|
||||||
|
|
||||||
parse -lang=Eng "I love you" | linearize -treebank
|
|
||||||
</pre>
|
|
||||||
The resource grammars are found relative to the value of <tt>GF_LIB_PATH</tt>, which
|
|
||||||
you may have to set; see <a href="../download/index.html">here</a> for instructions.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2>Grammar development</h2>
|
|
||||||
|
|
||||||
Add words to the <tt>Food</tt>
|
|
||||||
grammars and try the above commands again. For instance, add the following lines:
|
|
||||||
<pre>
|
|
||||||
Bread : Kind ; -- in Food.gf
|
|
||||||
Bread = {s = "bread"} ; -- in FoodEng.gf
|
|
||||||
Bread = {s = "pane"} ; -- in FoodIta.gf
|
|
||||||
</pre>
|
|
||||||
and start GF again with the same command. Now you can even translate
|
|
||||||
<i>this bread is very Italian</i>.
|
|
||||||
</ol>
|
|
||||||
To lear more on GF commands and
|
|
||||||
grammar development, go to the one of the tutorials:
|
|
||||||
<ul>
|
|
||||||
<li> <a href="tutorial/gf-tutorial.html">GF Tutorial</a>: older, more programmer-oriented
|
|
||||||
<li> <a href="gf-lrec-2010.pdf">GF Resource Tutorial</a>: newer, more linguist-oriented
|
|
||||||
</ul>
|
|
||||||
To learn about how GF is used for easily writing grammars for 16 languages, consult the
|
|
||||||
<ul>
|
|
||||||
<li> <a href="../lib/doc/synopsis.html">GF Resource Grammar Library</a>.
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2>Run-time grammars and web applications</h2>
|
|
||||||
|
|
||||||
GF has its own "machine language", PGF (Portable Grammar Format),
|
|
||||||
which is recommended for use in applications at run time. To produce a PGF file from
|
|
||||||
the two grammars above, do
|
|
||||||
<pre>
|
|
||||||
gf -make FoodIta.gf FoodEng.gf
|
|
||||||
wrote Food.pgf
|
|
||||||
</pre>
|
|
||||||
You can use this in Haskell and Java programs, and also on web services, such as
|
|
||||||
<ul>
|
|
||||||
<li> the
|
|
||||||
<a href="http://cloud.grammaticalframework.org/minibar/minibar.html">minibar</a>
|
|
||||||
fridge magnets
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
The quickest way to provide a GF web service is to start GF with the <tt>-server</tt> option:
|
|
||||||
<pre>
|
|
||||||
$ gf -server
|
|
||||||
This is GF version 3.3
|
|
||||||
Built on linux/i386 with ghc-7.0, flags: interrupt server cclazy
|
|
||||||
Document root = /usr/local/share/gf-3.3/www
|
|
||||||
Starting HTTP server, open http://localhost:41296/ in your web browser.
|
|
||||||
</pre>
|
|
||||||
You can view it locally by pointing your
|
|
||||||
browser to the URL shown. You can add your own <tt>.pgf</tt> grammar to the service by
|
|
||||||
copying it over to the <tt>documentRoot</tt> directory. Just push "reload" in
|
|
||||||
your browser after each such update.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
To build more customized web application, consult the
|
|
||||||
<a href="http://code.google.com/p/grammatical-framework/wiki/SideBar?tm=6">developer wiki</a>.
|
|
||||||
|
|
||||||
|
|
||||||
<h2>User group</h2>
|
|
||||||
|
|
||||||
You are welcome to join the <A HREF="http://groups.google.com/group/gf-dev">User Group</A>
|
|
||||||
to get help and discuss GF-related issues!
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</body></html>
|
|
||||||
Binary file not shown.
@@ -1,493 +0,0 @@
|
|||||||
GF Quick Reference
|
|
||||||
Aarne Ranta
|
|
||||||
April 4, 2006
|
|
||||||
|
|
||||||
% NOTE: this is a txt2tags file.
|
|
||||||
% Create an html file from this file using:
|
|
||||||
% txt2tags -thtml gf-reference.t2t
|
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!target:html
|
|
||||||
%!options: --toc
|
|
||||||
%!postproc(html): <TITLE> <meta name = "viewport" content = "width = device-width"><TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
This is a quick reference on GF grammars. It aims to
|
|
||||||
cover all forms of expression available when writing
|
|
||||||
grammars. It assumes basic knowledge of GF, which
|
|
||||||
can be acquired from the
|
|
||||||
[GF Tutorial http://www.grammaticalframework.org/doc/tutorial/gf-tutorial.html].
|
|
||||||
Help on GF commands is obtained on line by the
|
|
||||||
help command (``help``), and help on invoking
|
|
||||||
GF with (``gf -help``).
|
|
||||||
|
|
||||||
|
|
||||||
===A complete example===
|
|
||||||
|
|
||||||
This is a complete example of a GF grammar divided
|
|
||||||
into three modules in files. The grammar recognizes the
|
|
||||||
phrases //one pizza// and //two pizzas//.
|
|
||||||
|
|
||||||
File ``Order.gf``:
|
|
||||||
```
|
|
||||||
abstract Order = {
|
|
||||||
cat
|
|
||||||
Order ;
|
|
||||||
Item ;
|
|
||||||
fun
|
|
||||||
One, Two : Item -> Order ;
|
|
||||||
Pizza : Item ;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
File ``OrderEng.gf`` (the top file):
|
|
||||||
```
|
|
||||||
--# -path=.:prelude
|
|
||||||
concrete OrderEng of Order =
|
|
||||||
open Res, Prelude in {
|
|
||||||
flags startcat=Order ;
|
|
||||||
lincat
|
|
||||||
Order = SS ;
|
|
||||||
Item = {s : Num => Str} ;
|
|
||||||
lin
|
|
||||||
One it = ss ("one" ++ it.s ! Sg) ;
|
|
||||||
Two it = ss ("two" ++ it.s ! Pl) ;
|
|
||||||
Pizza = regNoun "pizza" ;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
File ``Res.gf``:
|
|
||||||
```
|
|
||||||
resource Res = open Prelude in {
|
|
||||||
param Num = Sg | Pl ;
|
|
||||||
oper regNoun : Str -> {s : Num => Str} =
|
|
||||||
\dog -> {s = table {
|
|
||||||
Sg => dog ;
|
|
||||||
_ => dog + "s"
|
|
||||||
}
|
|
||||||
} ;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
To use this example, do
|
|
||||||
```
|
|
||||||
% gf -- in shell: start GF
|
|
||||||
> i OrderEng.gf -- in GF: import grammar
|
|
||||||
> p "one pizza" -- parse string
|
|
||||||
> l Two Pizza -- linearize tree
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
===Modules and files===
|
|
||||||
|
|
||||||
One module per file.
|
|
||||||
File named ``Foo.gf`` contains module named
|
|
||||||
``Foo``.
|
|
||||||
|
|
||||||
Each module has the structure
|
|
||||||
```
|
|
||||||
moduletypename =
|
|
||||||
Inherits ** -- optional
|
|
||||||
open Opens in -- optional
|
|
||||||
{ Judgements }
|
|
||||||
```
|
|
||||||
Inherits are names of modules of the same type.
|
|
||||||
Inheritance can be restricted:
|
|
||||||
```
|
|
||||||
Mo[f,g], -- inherit only f,g from Mo
|
|
||||||
Lo-[f,g] -- inheris all but f,g from Lo
|
|
||||||
```
|
|
||||||
Opens are possible in ``concrete`` and ``resource``.
|
|
||||||
They are names of modules of these two types, possibly
|
|
||||||
qualified:
|
|
||||||
```
|
|
||||||
(M = Mo), -- refer to f as M.f or Mo.f
|
|
||||||
(Lo = Lo) -- refer to f as Lo.f
|
|
||||||
```
|
|
||||||
Module types and judgements in them:
|
|
||||||
```
|
|
||||||
abstract A -- cat, fun, def, data
|
|
||||||
concrete C of A -- lincat, lin, lindef, printname
|
|
||||||
resource R -- param, oper
|
|
||||||
|
|
||||||
interface I -- like resource, but can have
|
|
||||||
oper f : T without definition
|
|
||||||
instance J of I -- like resource, defines opers
|
|
||||||
that I leaves undefined
|
|
||||||
incomplete -- functor: concrete that opens
|
|
||||||
concrete CI of A = one or more interfaces
|
|
||||||
open I in ...
|
|
||||||
concrete CJ of A = -- completion: concrete that
|
|
||||||
CI with instantiates a functor by
|
|
||||||
(I = J) instances of open interfaces
|
|
||||||
```
|
|
||||||
The forms
|
|
||||||
``param``, ``oper``
|
|
||||||
may appear in ``concrete`` as well, but are then
|
|
||||||
not inherited to extensions.
|
|
||||||
|
|
||||||
All modules can moreover have ``flags`` and comments.
|
|
||||||
Comments have the forms
|
|
||||||
```
|
|
||||||
-- till the end of line
|
|
||||||
{- any number of lines between -}
|
|
||||||
--# used for compiler pragmas
|
|
||||||
```
|
|
||||||
A ``concrete`` can be opened like a ``resource``.
|
|
||||||
It is translated as follows:
|
|
||||||
```
|
|
||||||
cat C ---> oper C : Type =
|
|
||||||
lincat C = T T ** {lock_C : {}}
|
|
||||||
|
|
||||||
fun f : G -> C ---> oper f : A* -> C* = \g ->
|
|
||||||
lin f = t t g ** {lock_C = <>}
|
|
||||||
```
|
|
||||||
An ``abstract`` can be opened like an ``interface``.
|
|
||||||
Any ``concrete`` of it then works as an ``instance``.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
===Judgements===
|
|
||||||
|
|
||||||
```
|
|
||||||
cat C -- declare category C
|
|
||||||
cat C (x:A)(y:B x) -- dependent category C
|
|
||||||
cat C A B -- same as C (x : A)(y : B)
|
|
||||||
fun f : T -- declare function f of type T
|
|
||||||
def f = t -- define f as t
|
|
||||||
def f p q = t -- define f by pattern matching
|
|
||||||
data C = f | g -- set f,g as constructors of C
|
|
||||||
data f : A -> C -- same as
|
|
||||||
fun f : A -> C; data C=f
|
|
||||||
|
|
||||||
lincat C = T -- define lin.type of cat C
|
|
||||||
lin f = t -- define lin. of fun f
|
|
||||||
lin f x y = t -- same as lin f = \x y -> t
|
|
||||||
lindef C = \s -> t -- default lin. of cat C
|
|
||||||
printname fun f = s -- printname shown in menus
|
|
||||||
printname cat C = s -- printname shown in menus
|
|
||||||
printname f = s -- same as printname fun f = s
|
|
||||||
|
|
||||||
param P = C | D Q R -- define parameter type P
|
|
||||||
with constructors
|
|
||||||
C : P, D : Q -> R -> P
|
|
||||||
oper h : T = t -- define oper h of type T
|
|
||||||
oper h = t -- omit type, if inferrable
|
|
||||||
|
|
||||||
flags p=v -- set value of flag p
|
|
||||||
```
|
|
||||||
Judgements are terminated by semicolons (``;``).
|
|
||||||
Subsequent judgments of the same form may share the
|
|
||||||
keyword:
|
|
||||||
```
|
|
||||||
cat C ; D ; -- same as cat C ; cat D ;
|
|
||||||
```
|
|
||||||
Judgements can also share RHS:
|
|
||||||
```
|
|
||||||
fun f,g : A -- same as fun f : A ; g : A
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
===Types===
|
|
||||||
|
|
||||||
Abstract syntax (in ``fun``):
|
|
||||||
```
|
|
||||||
C -- basic type, if cat C
|
|
||||||
C a b -- basic type for dep. category
|
|
||||||
(x : A) -> B -- dep. functions from A to B
|
|
||||||
(_ : A) -> B -- nondep. functions from A to B
|
|
||||||
(p,q : A) -> B -- same as (p : A)-> (q : A) -> B
|
|
||||||
A -> B -- same as (_ : A) -> B
|
|
||||||
Int -- predefined integer type
|
|
||||||
Float -- predefined float type
|
|
||||||
String -- predefined string type
|
|
||||||
```
|
|
||||||
Concrete syntax (in ``lincat``):
|
|
||||||
```
|
|
||||||
Str -- token lists
|
|
||||||
P -- parameter type, if param P
|
|
||||||
P => B -- table type, if P param. type
|
|
||||||
{s : Str ; p : P}-- record type
|
|
||||||
{s,t : Str} -- same as {s : Str ; t : Str}
|
|
||||||
{a : A} **{b : B}-- record type extension, same as
|
|
||||||
{a : A ; b : B}
|
|
||||||
A * B * C -- tuple type, same as
|
|
||||||
{p1 : A ; p2 : B ; p3 : C}
|
|
||||||
Ints n -- type of n first integers
|
|
||||||
```
|
|
||||||
Resource (in ``oper``): all those of concrete, plus
|
|
||||||
```
|
|
||||||
Tok -- tokens (subtype of Str)
|
|
||||||
A -> B -- functions from A to B
|
|
||||||
Int -- integers
|
|
||||||
Strs -- list of prefixes (for pre)
|
|
||||||
PType -- parameter type
|
|
||||||
Type -- any type
|
|
||||||
```
|
|
||||||
As parameter types, one can use any finite type:
|
|
||||||
``P`` defined in ``param P``,
|
|
||||||
``Ints n``, and record types of parameter types.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
===Expressions===
|
|
||||||
|
|
||||||
Syntax trees = full function applications
|
|
||||||
```
|
|
||||||
f a b -- : C if fun f : A -> B -> C
|
|
||||||
1977 -- : Int
|
|
||||||
3.14 -- : Float
|
|
||||||
"foo" -- : String
|
|
||||||
```
|
|
||||||
Higher-Order Abstract syntax (HOAS): functions as arguments:
|
|
||||||
```
|
|
||||||
F a (\x -> c) -- : C if a : A, c : C (x : B),
|
|
||||||
fun F : A -> (B -> C) -> C
|
|
||||||
```
|
|
||||||
Tokens and token lists
|
|
||||||
```
|
|
||||||
"hello" -- : Tok, singleton Str
|
|
||||||
"hello" ++ "world" -- : Str
|
|
||||||
["hello world"] -- : Str, same as "hello" ++ "world"
|
|
||||||
"hello" + "world" -- : Tok, computes to "helloworld"
|
|
||||||
[] -- : Str, empty list
|
|
||||||
```
|
|
||||||
Parameters
|
|
||||||
```
|
|
||||||
Sg -- atomic constructor
|
|
||||||
VPres Sg P2 -- applied constructor
|
|
||||||
{n = Sg ; p = P3} -- record of parameters
|
|
||||||
```
|
|
||||||
Tables
|
|
||||||
```
|
|
||||||
table { -- by full branches
|
|
||||||
Sg => "mouse" ;
|
|
||||||
Pl => "mice"
|
|
||||||
}
|
|
||||||
table { -- by pattern matching
|
|
||||||
Pl => "mice" ;
|
|
||||||
_ => "mouse" -- wildcard pattern
|
|
||||||
}
|
|
||||||
table {
|
|
||||||
n => regn n "cat" -- variable pattern
|
|
||||||
}
|
|
||||||
table Num {...} -- table given with arg. type
|
|
||||||
table ["ox"; "oxen"] -- table as course of values
|
|
||||||
\\_ => "fish" -- same as table {_ => "fish"}
|
|
||||||
\\p,q => t -- same as \\p => \\q => t
|
|
||||||
|
|
||||||
t ! p -- select p from table t
|
|
||||||
case e of {...} -- same as table {...} ! e
|
|
||||||
```
|
|
||||||
Records
|
|
||||||
```
|
|
||||||
{s = "Liz"; g = Fem} -- record in full form
|
|
||||||
{s,t = "et"} -- same as {s = "et";t= "et"}
|
|
||||||
{s = "Liz"} ** -- record extension: same as
|
|
||||||
{g = Fem} {s = "Liz" ; g = Fem}
|
|
||||||
|
|
||||||
<a,b,c> -- tuple, same as {p1=a;p2=b;p3=c}
|
|
||||||
```
|
|
||||||
Functions
|
|
||||||
```
|
|
||||||
\x -> t -- lambda abstract
|
|
||||||
\x,y -> t -- same as \x -> \y -> t
|
|
||||||
\x,_ -> t -- binding not in t
|
|
||||||
```
|
|
||||||
Local definitions
|
|
||||||
```
|
|
||||||
let x : A = d in t -- let definition
|
|
||||||
let x = d in t -- let defin, type inferred
|
|
||||||
let x=d ; y=e in t -- same as
|
|
||||||
let x=d in let y=e in t
|
|
||||||
let {...} in t -- same as let ... in t
|
|
||||||
|
|
||||||
t where {...} -- same as let ... in t
|
|
||||||
```
|
|
||||||
Free variation
|
|
||||||
```
|
|
||||||
variants {x ; y} -- both x and y possible
|
|
||||||
variants {} -- nothing possible
|
|
||||||
```
|
|
||||||
Prefix-dependent choices
|
|
||||||
```
|
|
||||||
pre {"a" ; "an" / v} -- "an" before v, "a" otherw.
|
|
||||||
strs {"a" ; "i" ;"o"}-- list of condition prefixes
|
|
||||||
```
|
|
||||||
Typed expression
|
|
||||||
```
|
|
||||||
<t:T> -- same as t, to help type inference
|
|
||||||
```
|
|
||||||
Accessing bound variables in ``lin``: use fields ``$1, $2, $3,...``.
|
|
||||||
Example:
|
|
||||||
```
|
|
||||||
fun F : (A : Set) -> (El A -> Prop) -> Prop ;
|
|
||||||
lin F A B = {s = ["for all"] ++ A.s ++ B.$1 ++ B.s}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
===Pattern matching===
|
|
||||||
|
|
||||||
These patterns can be used in branches of ``table`` and
|
|
||||||
``case`` expressions. Patterns are matched in the order in
|
|
||||||
which they appear in the grammar.
|
|
||||||
```
|
|
||||||
C -- atomic param constructor
|
|
||||||
C p q -- param constr. applied to patterns
|
|
||||||
x -- variable, matches anything
|
|
||||||
_ -- wildcard, matches anything
|
|
||||||
"foo" -- string
|
|
||||||
56 -- integer
|
|
||||||
{s = p ; y = q} -- record, matches extensions too
|
|
||||||
<p,q> -- tuple, same as {p1=p ; p2=q}
|
|
||||||
p | q -- disjunction, binds to first match
|
|
||||||
x@p -- binds x to what p matches
|
|
||||||
- p -- negation
|
|
||||||
p + "s" -- sequence of two string patterns
|
|
||||||
p* -- repetition of a string pattern
|
|
||||||
```
|
|
||||||
|
|
||||||
===Sample library functions===
|
|
||||||
|
|
||||||
```
|
|
||||||
-- lib/prelude/Predef.gf
|
|
||||||
drop : Int -> Tok -> Tok -- drop prefix of length
|
|
||||||
take : Int -> Tok -> Tok -- take prefix of length
|
|
||||||
tk : Int -> Tok -> Tok -- drop suffix of length
|
|
||||||
dp : Int -> Tok -> Tok -- take suffix of length
|
|
||||||
occur : Tok -> Tok -> PBool -- test if substring
|
|
||||||
occurs : Tok -> Tok -> PBool -- test if any char occurs
|
|
||||||
show : (P:Type) -> P ->Tok -- param to string
|
|
||||||
read : (P:Type) -> Tok-> P -- string to param
|
|
||||||
toStr : (L:Type) -> L ->Str -- find "first" string
|
|
||||||
|
|
||||||
-- lib/prelude/Prelude.gf
|
|
||||||
param Bool = True | False
|
|
||||||
oper
|
|
||||||
SS : Type -- the type {s : Str}
|
|
||||||
ss : Str -> SS -- construct SS
|
|
||||||
cc2 : (_,_ : SS) -> SS -- concat SS's
|
|
||||||
optStr : Str -> Str -- string or empty
|
|
||||||
strOpt : Str -> Str -- empty or string
|
|
||||||
bothWays : Str -> Str -> Str -- X++Y or Y++X
|
|
||||||
init : Tok -> Tok -- all but last char
|
|
||||||
last : Tok -> Tok -- last char
|
|
||||||
prefixSS : Str -> SS -> SS
|
|
||||||
postfixSS : Str -> SS -> SS
|
|
||||||
infixSS : Str -> SS -> SS -> SS
|
|
||||||
if_then_else : (A : Type) -> Bool -> A -> A -> A
|
|
||||||
if_then_Str : Bool -> Str -> Str -> Str
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
===Flags===
|
|
||||||
|
|
||||||
Flags can appear, with growing priority,
|
|
||||||
- in files, judgement ``flags`` and without dash (``-``)
|
|
||||||
- as flags to ``gf`` when invoked, with dash
|
|
||||||
- as flags to various GF commands, with dash
|
|
||||||
|
|
||||||
|
|
||||||
Some common flags used in grammars:
|
|
||||||
```
|
|
||||||
startcat=cat use this category as default
|
|
||||||
|
|
||||||
lexer=literals int and string literals recognized
|
|
||||||
lexer=code like program code
|
|
||||||
lexer=text like text: spacing, capitals
|
|
||||||
lexer=textlit text, unknowns as string lits
|
|
||||||
|
|
||||||
unlexer=code like program code
|
|
||||||
unlexer=codelit code, remove string lit quotes
|
|
||||||
unlexer=text like text: punctuation, capitals
|
|
||||||
unlexer=textlit text, remove string lit quotes
|
|
||||||
unlexer=concat remove all spaces
|
|
||||||
unlexer=bind remove spaces around "&+"
|
|
||||||
|
|
||||||
optimize=all_subs best for almost any concrete
|
|
||||||
optimize=values good for lexicon concrete
|
|
||||||
optimize=all usually good for resource
|
|
||||||
optimize=noexpand for resource, if =all too big
|
|
||||||
```
|
|
||||||
For the full set of values for ``FLAG``,
|
|
||||||
use on-line ``h -FLAG``.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
===File import search paths===
|
|
||||||
|
|
||||||
Colon-separated list of directories searched in the
|
|
||||||
given order:
|
|
||||||
```
|
|
||||||
--# -path=.:../abstract:../common:prelude
|
|
||||||
```
|
|
||||||
This can be (in order of increasing priority), as
|
|
||||||
first line in the file, as flag to ``gf``
|
|
||||||
when invoked, or as flag to the ``i`` command.
|
|
||||||
The prefix ``--#`` is used only in files.
|
|
||||||
|
|
||||||
GF attempts to satisfy an ``import`` command by searching for the
|
|
||||||
import filename in the above search paths, initially qualified
|
|
||||||
relative to the current working directory. If the file is not found in
|
|
||||||
that initial expansion, the search paths are re-qualified relative to
|
|
||||||
the directories given in the ``GF_LIB_PATH`` environment variable. If
|
|
||||||
``GF_LIB_PATH`` is not defined, its default value is
|
|
||||||
``/usr/local/share/gf-3.9/lib`` (assuming you have GF version 3.9).
|
|
||||||
|
|
||||||
If your GF resource grammar libraries are installed somewhere else,
|
|
||||||
you will want to set ``GF_LIB_PATH`` to point there instead. In a
|
|
||||||
pinch, you can point to the ``GF/lib/src/`` folder in your clone of
|
|
||||||
the GF source code repository.
|
|
||||||
|
|
||||||
Developers of resource grammars may find it useful to define multiple
|
|
||||||
directories, colon-separated, in ``GF_LIB_PATH``.
|
|
||||||
|
|
||||||
|
|
||||||
===Alternative grammar formats===
|
|
||||||
|
|
||||||
**Old GF** (before GF 2.0):
|
|
||||||
all judgements in any kinds of modules,
|
|
||||||
division into files uses ``include``s.
|
|
||||||
A file ``Foo.gf`` is recognized as the old format
|
|
||||||
if it lacks a module header.
|
|
||||||
|
|
||||||
**Context-free** (file ``foo.cf``). The form of rules is e.g.
|
|
||||||
```
|
|
||||||
Fun. S ::= NP "is" AP ;
|
|
||||||
```
|
|
||||||
If ``Fun`` is omitted, it is generated automatically.
|
|
||||||
Rules must be one per line. The RHS can be empty.
|
|
||||||
|
|
||||||
**Extended BNF** (file ``foo.ebnf``). The form of rules is e.g.
|
|
||||||
```
|
|
||||||
S ::= (NP+ ("is" | "was") AP | V NP*) ;
|
|
||||||
```
|
|
||||||
where the RHS is a regular expression of categories
|
|
||||||
and quoted tokens: ``"foo", CAT, T U, T|U, T*, T+, T?``, or empty.
|
|
||||||
Rule labels are generated automatically.
|
|
||||||
|
|
||||||
|
|
||||||
**Probabilistic grammars** (not a separate format).
|
|
||||||
You can set the probability of a function ``f`` (in its value category) by
|
|
||||||
```
|
|
||||||
--# prob f 0.009
|
|
||||||
```
|
|
||||||
These are put into a file given to GF using the ``probs=File`` flag
|
|
||||||
on command line. This file can be the grammar file itself.
|
|
||||||
|
|
||||||
**Example-based grammars** (file ``foo.gfe``). Expressions of the form
|
|
||||||
```
|
|
||||||
in Cat "example string"
|
|
||||||
```
|
|
||||||
are preprocessed by using a parser given by the flag
|
|
||||||
```
|
|
||||||
--# -resource=File
|
|
||||||
```
|
|
||||||
and the result is written to ``foo.gf``.
|
|
||||||
|
|
||||||
|
|
||||||
===References===
|
|
||||||
|
|
||||||
[GF Homepage http://www.grammaticalframework.org/]
|
|
||||||
|
|
||||||
A. Ranta, Grammatical Framework: A Type-Theoretical Grammar Formalism.
|
|
||||||
//The Journal of Functional Programming//, vol. 14:2. 2004, pp. 145-189.
|
|
||||||
|
|
||||||
4605
doc/gf-refman.html
4605
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,11 +1,8 @@
|
|||||||
The GF Software System
|
The GF Software System
|
||||||
|
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!options(html): --toc
|
%!options(html): --toc
|
||||||
%!options(html): --toc-level=4
|
%!options(html): --toc-level=4
|
||||||
%!postproc(html): <TITLE> <meta name = "viewport" content = "width = device-width"><TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
%!postproc(html): "#VSPACE" "<hr>"
|
%!postproc(html): "#VSPACE" "<hr>"
|
||||||
%!postproc(html): "#NORMAL" ""
|
%!postproc(html): "#NORMAL" ""
|
||||||
%!postproc(html): "#TINY" ""
|
%!postproc(html): "#TINY" ""
|
||||||
@@ -107,5 +104,3 @@ To run GF from a //script//, redirection of standard input can be used:
|
|||||||
```
|
```
|
||||||
The file ``script.gfs`` should then contain a sequence of GF commands, one per line.
|
The file ``script.gfs`` should then contain a sequence of GF commands, one per line.
|
||||||
Unrecognized command lines are skipped without terminating GF.
|
Unrecognized command lines are skipped without terminating GF.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
<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>
|
<style>
|
||||||
body { background: #eee; padding-top: 200px; }
|
pre {
|
||||||
|
background-color:#eee;
|
||||||
pre.python {background-color:#ffc; display: none}
|
margin-top: 1em;
|
||||||
pre.haskell {background-color:#ffc; display: block}
|
padding: 0.5em 1em;
|
||||||
pre.java {background-color:#ffc; display: none}
|
}
|
||||||
pre.csharp {background-color:#ffc; display: none}
|
pre.python {display: none}
|
||||||
|
pre.haskell {display: block}
|
||||||
|
pre.java {display: none}
|
||||||
|
pre.csharp {display: none}
|
||||||
span.python {display: none}
|
span.python {display: none}
|
||||||
span.haskell {display: inline}
|
span.haskell {display: inline}
|
||||||
span.java {display: none}
|
span.java {display: none}
|
||||||
span.csharp {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>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
<script lang="javascript">
|
<script lang="javascript">
|
||||||
function change_language(href) {
|
function change_language(href) {
|
||||||
var name = href.split("#")[1];
|
var name = href.split("#")[1];
|
||||||
@@ -50,13 +47,27 @@
|
|||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body onload="change_language(window.location.href); window.addEventListener('hashchange', function(e){change_language(window.location.href);});">
|
<body onload="change_language(window.location.href); window.addEventListener('hashchange', function(e){change_language(window.location.href);});">
|
||||||
<span class="header">
|
<div class="container-fluid" style="max-width: 1200px">
|
||||||
<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>
|
<div class="header sticky-top border-bottom py-3 bg-white">
|
||||||
|
<a href=".." title="Home">
|
||||||
Choose a language: <a href="#haskell">Haskell</a> <a href="#python">Python</a> <a href="#java">Java</a> <a href="#csharp">C#</a>
|
<img src="../doc/Logos/gf1.svg" height="120px" class="float-md-right ml-3 mb-3 bg-white" alt="GF Logo">
|
||||||
</span>
|
</a>
|
||||||
|
<h1>
|
||||||
<h4>Krasimir Angelov, July 2015 - August 2017</h4>
|
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">
|
||||||
|
|
||||||
<h2>Loading the Grammar</h2>
|
<h2>Loading the Grammar</h2>
|
||||||
|
|
||||||
@@ -1289,6 +1300,7 @@ graph {
|
|||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ December 2010 for GF 3.2
|
|||||||
% txt2tags --toc -ttex gf-tutorial.txt
|
% txt2tags --toc -ttex gf-tutorial.txt
|
||||||
|
|
||||||
%!target:html
|
%!target:html
|
||||||
%!encoding: iso-8859-1
|
%!encoding: utf-8
|
||||||
%!options: --toc
|
%!options: --toc
|
||||||
|
|
||||||
%!postproc(tex) : "\\subsection\*" "\\newslide"
|
%!postproc(tex) : "\\subsection\*" "\\newslide"
|
||||||
@@ -618,32 +618,32 @@ and **semantic definitions**.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#NEW
|
% #NEW
|
||||||
|
%
|
||||||
==Slides==
|
% ==Slides==
|
||||||
|
%
|
||||||
You can chop this tutorial into a set of slides by the command
|
% You can chop this tutorial into a set of slides by the command
|
||||||
```
|
% ```
|
||||||
htmls gf-tutorial.html
|
% htmls gf-tutorial.html
|
||||||
```
|
% ```
|
||||||
where the program ``htmls`` is distributed with GF (see below), in
|
% where the program ``htmls`` is distributed with GF (see below), in
|
||||||
|
%
|
||||||
[``GF/src/tools/Htmls.hs`` http://grammaticalframework.org/src/tools/Htmls.hs]
|
% [``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``.
|
% 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
|
% 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.
|
% upper left corner of each slide, and the links behind the "Contents" link.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#NEW
|
#NEW
|
||||||
|
|
||||||
|
#Lchaptwo
|
||||||
|
|
||||||
=Lesson 1: Getting Started with GF=
|
=Lesson 1: Getting Started with GF=
|
||||||
|
|
||||||
|
|
||||||
#Lchaptwo
|
|
||||||
|
|
||||||
Goals:
|
Goals:
|
||||||
- install and run GF
|
- install and run GF
|
||||||
- write the first GF grammar: a "Hello World" grammar in three languages
|
- write the first GF grammar: a "Hello World" grammar in three languages
|
||||||
@@ -836,8 +836,8 @@ Finnish and an Italian concrete syntaxes:
|
|||||||
lin
|
lin
|
||||||
Hello recip = {s = "terve" ++ recip.s} ;
|
Hello recip = {s = "terve" ++ recip.s} ;
|
||||||
World = {s = "maailma"} ;
|
World = {s = "maailma"} ;
|
||||||
Mum = {s = "äiti"} ;
|
Mum = {s = "äiti"} ;
|
||||||
Friends = {s = "ystävät"} ;
|
Friends = {s = "ystävät"} ;
|
||||||
}
|
}
|
||||||
|
|
||||||
concrete HelloIta of Hello = {
|
concrete HelloIta of Hello = {
|
||||||
@@ -925,7 +925,7 @@ Default of the language flag (``-lang``): the last-imported concrete syntax.
|
|||||||
**Multilingual generation**:
|
**Multilingual generation**:
|
||||||
```
|
```
|
||||||
> parse -lang=HelloEng "hello friends" | linearize
|
> parse -lang=HelloEng "hello friends" | linearize
|
||||||
terve ystävät
|
terve ystävät
|
||||||
ciao amici
|
ciao amici
|
||||||
hello friends
|
hello friends
|
||||||
```
|
```
|
||||||
@@ -1037,9 +1037,10 @@ Application programs, using techniques from #Rchapeight:
|
|||||||
|
|
||||||
#NEW
|
#NEW
|
||||||
|
|
||||||
|
#Lchapthree
|
||||||
|
|
||||||
=Lesson 2: Designing a grammar for complex phrases=
|
=Lesson 2: Designing a grammar for complex phrases=
|
||||||
|
|
||||||
#Lchapthree
|
|
||||||
|
|
||||||
Goals:
|
Goals:
|
||||||
- build a larger grammar: phrases about food in English and Italian
|
- build a larger grammar: phrases about food in English and Italian
|
||||||
@@ -1335,7 +1336,7 @@ Just (?) replace English words with their dictionary equivalents:
|
|||||||
Phrase, Item, Kind, Quality = {s : Str} ;
|
Phrase, Item, Kind, Quality = {s : Str} ;
|
||||||
|
|
||||||
lin
|
lin
|
||||||
Is item quality = {s = item.s ++ "č" ++ quality.s} ;
|
Is item quality = {s = item.s ++ "è" ++ quality.s} ;
|
||||||
This kind = {s = "questo" ++ kind.s} ;
|
This kind = {s = "questo" ++ kind.s} ;
|
||||||
That kind = {s = "quel" ++ kind.s} ;
|
That kind = {s = "quel" ++ kind.s} ;
|
||||||
QKind quality kind = {s = kind.s ++ quality.s} ;
|
QKind quality kind = {s = kind.s ++ quality.s} ;
|
||||||
@@ -1446,11 +1447,11 @@ linearizations in different languages:
|
|||||||
> gr -number=2 | l -treebank
|
> gr -number=2 | l -treebank
|
||||||
|
|
||||||
Is (That Cheese) (Very Boring)
|
Is (That Cheese) (Very Boring)
|
||||||
quel formaggio č molto noioso
|
quel formaggio è molto noioso
|
||||||
that cheese is very boring
|
that cheese is very boring
|
||||||
|
|
||||||
Is (That Cheese) Fresh
|
Is (That Cheese) Fresh
|
||||||
quel formaggio č fresco
|
quel formaggio è fresco
|
||||||
that cheese is fresh
|
that cheese is fresh
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1472,14 +1473,14 @@ answer given in another language.
|
|||||||
You can interrupt the quiz by entering a line consisting of a dot ('.').
|
You can interrupt the quiz by entering a line consisting of a dot ('.').
|
||||||
|
|
||||||
this fish is warm
|
this fish is warm
|
||||||
questo pesce č caldo
|
questo pesce è caldo
|
||||||
> Yes.
|
> Yes.
|
||||||
Score 1/1
|
Score 1/1
|
||||||
|
|
||||||
this cheese is Italian
|
this cheese is Italian
|
||||||
questo formaggio č noioso
|
questo formaggio è noioso
|
||||||
> No, not questo formaggio č noioso, but
|
> No, not questo formaggio è noioso, but
|
||||||
questo formaggio č italiano
|
questo formaggio è italiano
|
||||||
|
|
||||||
Score 1/2
|
Score 1/2
|
||||||
this fish is expensive
|
this fish is expensive
|
||||||
@@ -1756,7 +1757,7 @@ Simultaneous extension and opening:
|
|||||||
lincat
|
lincat
|
||||||
Question = SS ;
|
Question = SS ;
|
||||||
lin
|
lin
|
||||||
QIs item quality = ss (item.s ++ "č" ++ quality.s) ;
|
QIs item quality = ss (item.s ++ "è" ++ quality.s) ;
|
||||||
Pizza = ss "pizza" ;
|
Pizza = ss "pizza" ;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -1797,9 +1798,10 @@ where
|
|||||||
|
|
||||||
#NEW
|
#NEW
|
||||||
|
|
||||||
|
#Lchapfour
|
||||||
|
|
||||||
=Lesson 3: Grammars with parameters=
|
=Lesson 3: Grammars with parameters=
|
||||||
|
|
||||||
#Lchapfour
|
|
||||||
|
|
||||||
Goals:
|
Goals:
|
||||||
- implement sophisticated linguistic structures:
|
- implement sophisticated linguistic structures:
|
||||||
@@ -2364,10 +2366,10 @@ in English, with special care taken of variations with the suffix
|
|||||||
|
|
||||||
+ Implement the German **Umlaut** operation on word stems.
|
+ Implement the German **Umlaut** operation on word stems.
|
||||||
The operation changes the vowel of the stressed stem syllable as follows:
|
The operation changes the vowel of the stressed stem syllable as follows:
|
||||||
//a// to //ä//, //au// to //äu//, //o// to //ö//, and //u// to //ü//. You
|
//a// to //ä//, //au// to //äu//, //o// to //ö//, and //u// to //ü//. You
|
||||||
can assume that the operation only takes syllables as arguments. Test the
|
can assume that the operation only takes syllables as arguments. Test the
|
||||||
operation to see whether it correctly changes //Arzt// to //Ärzt//,
|
operation to see whether it correctly changes //Arzt// to //Ärzt//,
|
||||||
//Baum// to //Bäum//, //Topf// to //Töpf//, and //Kuh// to //Küh//.
|
//Baum// to //Bäum//, //Topf// to //Töpf//, and //Kuh// to //Küh//.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -2480,10 +2482,10 @@ The command ``morpho_quiz = mq`` generates inflection exercises.
|
|||||||
Welcome to GF Morphology Quiz.
|
Welcome to GF Morphology Quiz.
|
||||||
...
|
...
|
||||||
|
|
||||||
réapparaître : VFin VCondit Pl P2
|
réapparaître : VFin VCondit Pl P2
|
||||||
réapparaitriez
|
réapparaitriez
|
||||||
> No, not réapparaitriez, but
|
> No, not réapparaitriez, but
|
||||||
réapparaîtriez
|
réapparaîtriez
|
||||||
Score 0/1
|
Score 0/1
|
||||||
```
|
```
|
||||||
To create a list for later use, use the command ``morpho_list = ml``
|
To create a list for later use, use the command ``morpho_list = ml``
|
||||||
@@ -2563,7 +2565,7 @@ We need only number variation for the copula.
|
|||||||
```
|
```
|
||||||
copula : Number -> Str =
|
copula : Number -> Str =
|
||||||
\n -> case n of {
|
\n -> case n of {
|
||||||
Sg => "č" ;
|
Sg => "è" ;
|
||||||
Pl => "sono"
|
Pl => "sono"
|
||||||
} ;
|
} ;
|
||||||
```
|
```
|
||||||
@@ -2772,9 +2774,10 @@ Thus
|
|||||||
|
|
||||||
#NEW
|
#NEW
|
||||||
|
|
||||||
|
#Lchapfive
|
||||||
|
|
||||||
=Lesson 4: Using the resource grammar library=
|
=Lesson 4: Using the resource grammar library=
|
||||||
|
|
||||||
#Lchapfive
|
|
||||||
|
|
||||||
Goals:
|
Goals:
|
||||||
- navigate in the GF resource grammar library and use it in applications
|
- navigate in the GF resource grammar library and use it in applications
|
||||||
@@ -3305,13 +3308,13 @@ we can write a **functor instantiation**,
|
|||||||
oper
|
oper
|
||||||
wine_N = mkN "Wein" ;
|
wine_N = mkN "Wein" ;
|
||||||
pizza_N = mkN "Pizza" "Pizzen" feminine ;
|
pizza_N = mkN "Pizza" "Pizzen" feminine ;
|
||||||
cheese_N = mkN "Käse" "Käsen" masculine ;
|
cheese_N = mkN "Käse" "Käsen" masculine ;
|
||||||
fish_N = mkN "Fisch" ;
|
fish_N = mkN "Fisch" ;
|
||||||
fresh_A = mkA "frisch" ;
|
fresh_A = mkA "frisch" ;
|
||||||
warm_A = mkA "warm" "wärmer" "wärmste" ;
|
warm_A = mkA "warm" "wärmer" "wärmste" ;
|
||||||
italian_A = mkA "italienisch" ;
|
italian_A = mkA "italienisch" ;
|
||||||
expensive_A = mkA "teuer" ;
|
expensive_A = mkA "teuer" ;
|
||||||
delicious_A = mkA "köstlich" ;
|
delicious_A = mkA "köstlich" ;
|
||||||
boring_A = mkA "langweilig" ;
|
boring_A = mkA "langweilig" ;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -3362,11 +3365,11 @@ Lexicon instance
|
|||||||
cheese_N = mkN "juusto" ;
|
cheese_N = mkN "juusto" ;
|
||||||
fish_N = mkN "kala" ;
|
fish_N = mkN "kala" ;
|
||||||
fresh_A = mkA "tuore" ;
|
fresh_A = mkA "tuore" ;
|
||||||
warm_A = mkA "lämmin" ;
|
warm_A = mkA "lämmin" ;
|
||||||
italian_A = mkA "italialainen" ;
|
italian_A = mkA "italialainen" ;
|
||||||
expensive_A = mkA "kallis" ;
|
expensive_A = mkA "kallis" ;
|
||||||
delicious_A = mkA "herkullinen" ;
|
delicious_A = mkA "herkullinen" ;
|
||||||
boring_A = mkA "tylsä" ;
|
boring_A = mkA "tylsä" ;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Functor instantiation
|
Functor instantiation
|
||||||
@@ -3614,9 +3617,10 @@ tenses and moods, e.g. the Romance languages.
|
|||||||
|
|
||||||
#NEW
|
#NEW
|
||||||
|
|
||||||
|
#Lchapsix
|
||||||
|
|
||||||
=Lesson 5: Refining semantics in abstract syntax=
|
=Lesson 5: Refining semantics in abstract syntax=
|
||||||
|
|
||||||
#Lchapsix
|
|
||||||
|
|
||||||
Goals:
|
Goals:
|
||||||
- include semantic conditions in grammars, by using
|
- include semantic conditions in grammars, by using
|
||||||
@@ -3626,7 +3630,7 @@ Goals:
|
|||||||
- semantic definitions
|
- semantic definitions
|
||||||
|
|
||||||
These concepts are inherited from **type theory** (more precisely:
|
These concepts are inherited from **type theory** (more precisely:
|
||||||
constructive type theory, or Martin-Löf type theory).
|
constructive type theory, or Martin-Löf type theory).
|
||||||
|
|
||||||
Type theory is the basis **logical frameworks**.
|
Type theory is the basis **logical frameworks**.
|
||||||
|
|
||||||
@@ -4177,11 +4181,11 @@ Type checking can be invoked with ``put_term -transform=solve``.
|
|||||||
|
|
||||||
#NEW
|
#NEW
|
||||||
|
|
||||||
|
#Lchapseven
|
||||||
|
|
||||||
==Lesson 6: Grammars of formal languages==
|
==Lesson 6: Grammars of formal languages==
|
||||||
|
|
||||||
|
|
||||||
#Lchapseven
|
|
||||||
|
|
||||||
Goals:
|
Goals:
|
||||||
- write grammars for formal languages (mathematical notation, programming languages)
|
- write grammars for formal languages (mathematical notation, programming languages)
|
||||||
- interface between formal and natural langauges
|
- interface between formal and natural langauges
|
||||||
@@ -4516,9 +4520,10 @@ point literals as arguments.
|
|||||||
|
|
||||||
#NEW
|
#NEW
|
||||||
|
|
||||||
|
#Lchapeight
|
||||||
|
|
||||||
=Lesson 7: Embedded grammars=
|
=Lesson 7: Embedded grammars=
|
||||||
|
|
||||||
#Lchapeight
|
|
||||||
|
|
||||||
Goals:
|
Goals:
|
||||||
- use grammars as parts of programs written in Haskell and JavaScript
|
- use grammars as parts of programs written in Haskell and JavaScript
|
||||||
@@ -4639,7 +4644,7 @@ output. Therefore it can be a part of a pipe and read and write files.
|
|||||||
The simplest way to translate is to ``echo`` input to the program:
|
The simplest way to translate is to ``echo`` input to the program:
|
||||||
```
|
```
|
||||||
% echo "this wine is delicious" | ./trans Food.pgf
|
% echo "this wine is delicious" | ./trans Food.pgf
|
||||||
questo vino č delizioso
|
questo vino è delizioso
|
||||||
```
|
```
|
||||||
The result is given in all languages except the input language.
|
The result is given in all languages except the input language.
|
||||||
|
|
||||||
@@ -4958,12 +4963,12 @@ syntax name. This file contains the multilingual grammar as a JavaScript object.
|
|||||||
===Using the JavaScript grammar===
|
===Using the JavaScript grammar===
|
||||||
|
|
||||||
To perform parsing and linearization, the run-time library
|
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
|
some other JavaScript and HTML files; these files can be used
|
||||||
as templates for building applications.
|
as templates for building applications.
|
||||||
|
|
||||||
An example of usage is
|
An example of usage is
|
||||||
[``translator.html`` http://grammaticalframework.org:41296],
|
[``translator.html`` ../../src/runtime/javascript/translator.html],
|
||||||
which is in fact initialized with
|
which is in fact initialized with
|
||||||
a pointer to the Food grammar, so that it provides translation between the English
|
a pointer to the Food grammar, so that it provides translation between the English
|
||||||
and Italian grammars:
|
and Italian grammars:
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
FILES="darcs.txt transfer-reference.txt transfer-tutorial.txt \
|
|
||||||
transfer.txt"
|
|
||||||
|
|
||||||
for f in $FILES; do
|
|
||||||
h=`basename "$f" ".txt"`.html
|
|
||||||
if [ "$f" -nt "$h" ]; then
|
|
||||||
txt2tags $f
|
|
||||||
else
|
|
||||||
echo "$h is newer than $f, skipping"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
GF character encoding changes
|
GF character encoding changes
|
||||||
Thomas Hallgren
|
Thomas Hallgren
|
||||||
%%mtime(%F)
|
2013-12-18
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): <TITLE> <meta charset="UTF-8"><meta name = "viewport" content = "width = device-width"> <TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
==Changes to character encodings in GF grammar files ==
|
==Changes to character encodings in GF grammar files ==
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
Grammatical Framework Download and Installation
|
Grammatical Framework Download and Installation
|
||||||
|
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): <TD><B> <TH>
|
|
||||||
%!postproc(html): </B></TD> </TH>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
**GF 3.2.9** source-only snapshot was released on 12 September 2011.
|
**GF 3.2.9** source-only snapshot was released on 12 September 2011.
|
||||||
|
|
||||||
What's new? Faster grammar compilation!
|
What's new? Faster grammar compilation!
|
||||||
@@ -77,9 +72,3 @@ The above notes for installing from source apply also in this case.
|
|||||||
- [GF 3.2 index-3.2.html] (December 2011).
|
- [GF 3.2 index-3.2.html] (December 2011).
|
||||||
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
||||||
- [GF 3.1 old-index.html] (December 2009).
|
- [GF 3.1 old-index.html] (December 2009).
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
Grammatical Framework Download and Installation
|
Grammatical Framework Download and Installation
|
||||||
|
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): <TD><B> <TH>
|
|
||||||
%!postproc(html): </B></TD> </TH>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
**GF 3.2** was released on 23 December 2010.
|
**GF 3.2** was released on 23 December 2010.
|
||||||
|
|
||||||
What's new? See the [Release notes release-3.2.html].
|
What's new? See the [Release notes release-3.2.html].
|
||||||
@@ -105,8 +100,3 @@ Subsequently:
|
|||||||
```
|
```
|
||||||
|
|
||||||
The above notes for installing from source apply also in this case.
|
The above notes for installing from source apply also in this case.
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
Grammatical Framework Download and Installation
|
Grammatical Framework Download and Installation
|
||||||
|
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): <TITLE> <meta name = "viewport" content = "width = device-width"><TITLE>
|
|
||||||
%!postproc(html): <TD><B> <TH>
|
|
||||||
%!postproc(html): </B></TD> </TH>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
**GF 3.3.3** was released on 3 March 2012.
|
**GF 3.3.3** was released on 3 March 2012.
|
||||||
|
|
||||||
What's new? See the [Release notes release-3.3.3.html].
|
What's new? See the [Release notes release-3.3.3.html].
|
||||||
@@ -127,9 +121,3 @@ For more info, see the [GF Developers Guide ../doc/gf-developers.html].
|
|||||||
- [GF 3.2 index-3.2.html] (December 2010).
|
- [GF 3.2 index-3.2.html] (December 2010).
|
||||||
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
||||||
- [GF 3.1 old-index.html] (December 2009).
|
- [GF 3.1 old-index.html] (December 2009).
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
Grammatical Framework Download and Installation
|
Grammatical Framework Download and Installation
|
||||||
|
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): <TD><B> <TH>
|
|
||||||
%!postproc(html): </B></TD> </TH>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
**GF 3.3** was released on 27 October 2011.
|
**GF 3.3** was released on 27 October 2011.
|
||||||
|
|
||||||
What's new? See the [Release notes release-3.3.html].
|
What's new? See the [Release notes release-3.3.html].
|
||||||
@@ -115,9 +110,3 @@ The above notes for installing from source apply also in this case.
|
|||||||
- [GF 3.2 index-3.2.html] (December 2010).
|
- [GF 3.2 index-3.2.html] (December 2010).
|
||||||
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
||||||
- [GF 3.1 old-index.html] (December 2009).
|
- [GF 3.1 old-index.html] (December 2009).
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,6 @@
|
|||||||
Grammatical Framework Download and Installation
|
Grammatical Framework Download and Installation
|
||||||
|
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): </HEAD> <STYLE>body { color: #333; } li>code,p>code,pre { color: #730; }</STYLE></HEAD>
|
|
||||||
%!postproc(html): <TITLE> <meta name = "viewport" content = "width = device-width"><TITLE>
|
|
||||||
%!postproc(html): <TD><B> <TH>
|
|
||||||
%!postproc(html): </B></TD> </TH>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
**GF 3.4** was released on 31 January 2013.
|
**GF 3.4** was released on 31 January 2013.
|
||||||
|
|
||||||
What's new? See the [Release notes release-3.4.html].
|
What's new? See the [Release notes release-3.4.html].
|
||||||
@@ -20,10 +13,7 @@ What's new? See the [Release notes release-3.4.html].
|
|||||||
| Fedora (32-bit) | [Fedora RPMs /~hallgren/tmp/Fedora/] | ``sudo rpm -i ...``
|
| Fedora (32-bit) | [Fedora RPMs /~hallgren/tmp/Fedora/] | ``sudo rpm -i ...``
|
||||||
| Ubuntu (32-bit) | [gf_3.4-1_i386.deb gf_3.4-1_i386.deb] | ``sudo dpkg -i gf_3.4-1_i386.deb``
|
| Ubuntu (32-bit) | [gf_3.4-1_i386.deb gf_3.4-1_i386.deb] | ``sudo dpkg -i gf_3.4-1_i386.deb``
|
||||||
| Ubuntu (64-bit) | [gf_3.4-1_amd64.deb gf_3.4-1_amd64.deb] | ``sudo dpkg -i gf_3.4-1_amd64.deb``
|
| Ubuntu (64-bit) | [gf_3.4-1_amd64.deb gf_3.4-1_amd64.deb] | ``sudo dpkg -i gf_3.4-1_amd64.deb``
|
||||||
| Windows | [gf-3.4-bin-windows.zip gf-3.4-bin-windows.zip] |
|
| Windows | [gf-3.4-bin-windows.zip gf-3.4-bin-windows.zip] | -
|
||||||
%| ... | ... | ...
|
|
||||||
|
|
||||||
%More binary packages might be added later.
|
|
||||||
|
|
||||||
===Notes===
|
===Notes===
|
||||||
|
|
||||||
@@ -153,8 +143,3 @@ For more info on working with the GF source code, see the
|
|||||||
- [GF 3.2 index-3.2.html] (December 2010).
|
- [GF 3.2 index-3.2.html] (December 2010).
|
||||||
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
||||||
- [GF 3.1 old-index.html] (December 2009).
|
- [GF 3.1 old-index.html] (December 2009).
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
@@ -1,13 +1,6 @@
|
|||||||
Grammatical Framework Download and Installation
|
Grammatical Framework Download and Installation
|
||||||
|
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): </HEAD> <STYLE>body { color: #333; } li>code,p>code,pre { color: #730; }</STYLE></HEAD>
|
|
||||||
%!postproc(html): <TITLE> <meta name = "viewport" content = "width = device-width"><TITLE>
|
|
||||||
%!postproc(html): <TD><B> <TH>
|
|
||||||
%!postproc(html): </B></TD> </TH>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
**GF 3.5** was released on 6 August 2013.
|
**GF 3.5** was released on 6 August 2013.
|
||||||
|
|
||||||
What's new? See the [Release notes release-3.5.html].
|
What's new? See the [Release notes release-3.5.html].
|
||||||
@@ -157,8 +150,3 @@ For more info on working with the GF source code, see the
|
|||||||
- [GF 3.2 index-3.2.html] (December 2010).
|
- [GF 3.2 index-3.2.html] (December 2010).
|
||||||
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
||||||
- [GF 3.1 old-index.html] (December 2009).
|
- [GF 3.1 old-index.html] (December 2009).
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
@@ -1,13 +1,6 @@
|
|||||||
Grammatical Framework Download and Installation
|
Grammatical Framework Download and Installation
|
||||||
|
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): </HEAD> <STYLE>body { color: #333; } li>code,p>code,pre { color: #730; }</STYLE></HEAD>
|
|
||||||
%!postproc(html): <TITLE> <meta name = "viewport" content = "width = device-width"><TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
%!postproc(html): <TD><I> <TD><small>
|
|
||||||
%!postproc(html): </I></TD> </small></TD>
|
|
||||||
|
|
||||||
**GF 3.6** was released on 23 June 2014.
|
**GF 3.6** was released on 23 June 2014.
|
||||||
|
|
||||||
What's new? See the [Release notes release-3.6.html].
|
What's new? See the [Release notes release-3.6.html].
|
||||||
@@ -177,8 +170,3 @@ For more info on working with the GF source code, see the
|
|||||||
- [GF 3.2 index-3.2.html] (December 2010).
|
- [GF 3.2 index-3.2.html] (December 2010).
|
||||||
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
||||||
- [GF 3.1 old-index.html] (December 2009).
|
- [GF 3.1 old-index.html] (December 2009).
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
Grammatical Framework Download and Installation
|
Grammatical Framework Download and Installation
|
||||||
|
|
||||||
|
|
||||||
%!style:../css/notes.css
|
|
||||||
%!postproc(html): <TITLE> <meta name = "viewport" content = "width = device-width"><TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
%!postproc(html): <TD><I> <TD><small>
|
|
||||||
%!postproc(html): </I></TD> </small></TD>
|
|
||||||
|
|
||||||
**GF 3.7.1** was released on 2 October 2015.
|
**GF 3.7.1** was released on 2 October 2015.
|
||||||
|
|
||||||
What's new? See the [Release notes release-3.7.1.html].
|
What's new? See the [Release notes release-3.7.1.html].
|
||||||
@@ -180,8 +174,3 @@ For more info on working with the GF source code, see the
|
|||||||
- [GF 3.2 index-3.2.html] (December 2010).
|
- [GF 3.2 index-3.2.html] (December 2010).
|
||||||
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
||||||
- [GF 3.1 old-index.html] (December 2009).
|
- [GF 3.1 old-index.html] (December 2009).
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
@@ -1,13 +1,6 @@
|
|||||||
Grammatical Framework Download and Installation
|
Grammatical Framework Download and Installation
|
||||||
|
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): </HEAD> <STYLE>body { color: #333; } li>code,p>code,pre { color: #730; }</STYLE></HEAD>
|
|
||||||
%!postproc(html): <TITLE> <meta name = "viewport" content = "width = device-width"><TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
%!postproc(html): <TD><I> <TD><small>
|
|
||||||
%!postproc(html): </I></TD> </small></TD>
|
|
||||||
|
|
||||||
**GF 3.7** was released on 25 June 2015.
|
**GF 3.7** was released on 25 June 2015.
|
||||||
|
|
||||||
What's new? See the [Release notes release-3.7.html].
|
What's new? See the [Release notes release-3.7.html].
|
||||||
@@ -173,8 +166,3 @@ For more info on working with the GF source code, see the
|
|||||||
- [GF 3.2 index-3.2.html] (December 2010).
|
- [GF 3.2 index-3.2.html] (December 2010).
|
||||||
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
||||||
- [GF 3.1 old-index.html] (December 2009).
|
- [GF 3.1 old-index.html] (December 2009).
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
Grammatical Framework Download and Installation
|
Grammatical Framework Download and Installation
|
||||||
|
|
||||||
|
|
||||||
%!style:../css/notes.css
|
|
||||||
%!postproc(html): <TITLE> <meta name = "viewport" content = "width = device-width"><TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
%!postproc(html): <TD><I> <TD><small>
|
|
||||||
%!postproc(html): </I></TD> </small></TD>
|
|
||||||
|
|
||||||
**GF 3.8** was released on 22 June 2016.
|
**GF 3.8** was released on 22 June 2016.
|
||||||
|
|
||||||
What's new? See the [Release notes release-3.8.html].
|
What's new? See the [Release notes release-3.8.html].
|
||||||
@@ -171,8 +165,3 @@ For more info on working with the GF source code, see the
|
|||||||
- [GF 3.2 index-3.2.html] (December 2010).
|
- [GF 3.2 index-3.2.html] (December 2010).
|
||||||
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
||||||
- [GF 3.1 old-index.html] (December 2009).
|
- [GF 3.1 old-index.html] (December 2009).
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
Grammatical Framework Download and Installation
|
Grammatical Framework Download and Installation
|
||||||
|
|
||||||
|
|
||||||
%!style:../css/notes.css
|
|
||||||
%!postproc(html): <TITLE> <meta name = "viewport" content = "width = device-width"><TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
%!postproc(html): <TD><I> <TD><small>
|
|
||||||
%!postproc(html): </I></TD> </small></TD>
|
|
||||||
|
|
||||||
**GF 3.9** was released on 11 August 2017.
|
**GF 3.9** was released on 11 August 2017.
|
||||||
|
|
||||||
What's new? See the [Release notes release-3.9.html].
|
What's new? See the [Release notes release-3.9.html].
|
||||||
@@ -18,10 +12,11 @@ What's new? See the [Release notes release-3.9.html].
|
|||||||
| macOS | [gf-3.9.pkg gf-3.9.pkg] | //GF+S+C+J+P// | Double-click on the package icon
|
| macOS | [gf-3.9.pkg gf-3.9.pkg] | //GF+S+C+J+P// | Double-click on the package icon
|
||||||
| macOS | [gf-3.9-bin-intel-mac.tar.gz gf-3.9-bin-intel-mac.tar.gz] | //GF+S+C+J+P// | ``sudo tar -C /usr/local -zxf gf-3.9-bin-intel-mac.tar.gz``
|
| macOS | [gf-3.9-bin-intel-mac.tar.gz gf-3.9-bin-intel-mac.tar.gz] | //GF+S+C+J+P// | ``sudo tar -C /usr/local -zxf gf-3.9-bin-intel-mac.tar.gz``
|
||||||
%| Fedora (32-bit) | [Fedora RPMs /~hallgren/tmp/Fedora/] | //GF+S+C+J+P// | ``sudo rpm -i ...``
|
%| Fedora (32-bit) | [Fedora RPMs /~hallgren/tmp/Fedora/] | //GF+S+C+J+P// | ``sudo rpm -i ...``
|
||||||
| Raspian 9.1 | [gf_3.9-1_armhf.deb gf_3.9-1_armhf.deb] | //GF+S+C+J+P// | ``sudo dpkg -i gf_3.9-1_armhf.deb``
|
| Raspbian 9.1 | [gf_3.9-1_armhf.deb gf_3.9-1_armhf.deb] | //GF+S+C+J+P// | ``sudo dpkg -i gf_3.9-1_armhf.deb``
|
||||||
| Ubuntu (32-bit) | [gf_3.9-1_i386.deb gf_3.9-1_i386.deb] | //GF+S+C+J+P// | ``sudo dpkg -i gf_3.9-1_i386.deb``
|
| Ubuntu (32-bit) | [gf_3.9-1_i386.deb gf_3.9-1_i386.deb] | //GF+S+C+J+P// | ``sudo dpkg -i gf_3.9-1_i386.deb``
|
||||||
| Ubuntu (64-bit) | [gf_3.9-1_amd64.deb gf_3.9-1_amd64.deb] | //GF+S+C+J+P// | ``sudo dpkg -i gf_3.9-1_amd64.deb``
|
| Ubuntu (64-bit) | [gf_3.9-1_amd64.deb gf_3.9-1_amd64.deb] | //GF+S+C+J+P// | ``sudo dpkg -i gf_3.9-1_amd64.deb``
|
||||||
| Windows | [gf-3.9-bin-windows.zip gf-3.9-bin-windows.zip] | //GF+S// | ``unzip gf-3.9-bin-windows.zip``
|
| Windows | [gf-3.9-bin-windows.zip gf-3.9-bin-windows.zip] | //GF+S// | ``unzip gf-3.9-bin-windows.zip``
|
||||||
|
|
||||||
%| MINGW | [gf-3.9-bin-i686-MINGW32_NT-6.1.tar.gz gf-3.9-bin-i686-MINGW32_NT-6.1.tar.gz] | //GF+S+C// | ``tar -C / gf-3.9-bin-i686-MINGW32_NT-6.1.tar.gz``
|
%| MINGW | [gf-3.9-bin-i686-MINGW32_NT-6.1.tar.gz gf-3.9-bin-i686-MINGW32_NT-6.1.tar.gz] | //GF+S+C// | ``tar -C / gf-3.9-bin-i686-MINGW32_NT-6.1.tar.gz``
|
||||||
%| ... | ... | ... | ...
|
%| ... | ... | ... | ...
|
||||||
|
|
||||||
@@ -195,8 +190,3 @@ with ``stack install`` (assuming you already have Stack set up).
|
|||||||
- [GF 3.2 index-3.2.html] (December 2010).
|
- [GF 3.2 index-3.2.html] (December 2010).
|
||||||
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
- [GF 3.1.6 index-3.1.6.html] (April 2010).
|
||||||
- [GF 3.1 old-index.html] (December 2009).
|
- [GF 3.1 old-index.html] (December 2009).
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
187
download/index.md
Normal file
187
download/index.md
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
---
|
||||||
|
title: Grammatical Framework Download and Installation
|
||||||
|
...
|
||||||
|
|
||||||
|
**GF 3.10** was released on 2 December 2018.
|
||||||
|
|
||||||
|
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 |
|
||||||
|
| Raspbian 10 (buster) | [gf\_3.10-2\_armhf.deb](gf_3.10-2_armhf.deb) | GF,S,C,J,P | `sudo dpkg -i gf_3.10-2_armhf.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` |
|
||||||
|
-->
|
||||||
|
|
||||||
|
**Features**
|
||||||
|
|
||||||
|
- GF = GF shell and grammar compiler
|
||||||
|
- S = `gf -server` mode
|
||||||
|
- C = C run-time system
|
||||||
|
- J/P = Java/Python binding to the C run-time system
|
||||||
|
|
||||||
|
### Notes
|
||||||
|
|
||||||
|
The Windows package is installed by just unpacking it anywhere. You will
|
||||||
|
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. 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
|
||||||
|
similar Linux distributions. -->
|
||||||
|
|
||||||
|
The packages for macOS (Mac OS X) should work on at least 10.13 and
|
||||||
|
10.14 (High Sierra and Mojave)
|
||||||
|
|
||||||
|
<!-- The Mac OS and Linux `.tar.gz` packages are designed to be installed in
|
||||||
|
`/usr/local`. You can install them in other locations, but then you need
|
||||||
|
to set the `GF_LIB_PATH` environment variable:
|
||||||
|
|
||||||
|
```
|
||||||
|
export GF_LIB_PATH=/usr/local/share/gf-3.10/lib
|
||||||
|
```
|
||||||
|
|
||||||
|
where `/usr/local` should be replaced with the path to the location
|
||||||
|
where you unpacked the package. -->
|
||||||
|
|
||||||
|
## Installing the latest release from source
|
||||||
|
|
||||||
|
[GF is on Hackage](http://hackage.haskell.org/package/gf), so under
|
||||||
|
normal circumstances the procedure is fairly simple:
|
||||||
|
|
||||||
|
1. Install a recent version of the [Haskell
|
||||||
|
Platform](http://hackage.haskell.org/platform) (see note below)
|
||||||
|
2. `cabal update`
|
||||||
|
3. On Linux: install some C libraries from your Linux distribution (see note below)
|
||||||
|
4. `cabal install gf`
|
||||||
|
|
||||||
|
This installs the GF executable and Haskell libraries, but **does not include the RGL**.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
**Installation location**
|
||||||
|
|
||||||
|
The above steps installs GF for a single user. The executables are put
|
||||||
|
in `$HOME/.cabal/bin` (or, with recent versions of the Haskell platform
|
||||||
|
on Mac OS X, in `$HOME/Library/Haskell/bin`), so it is a good idea to
|
||||||
|
put a line in your `.bash_profile` or `.profile` to add that directory
|
||||||
|
to you path:
|
||||||
|
|
||||||
|
```
|
||||||
|
PATH=$HOME/.cabal/bin:$PATH
|
||||||
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```
|
||||||
|
PATH=$HOME/Library/Haskell/bin:$PATH
|
||||||
|
```
|
||||||
|
|
||||||
|
**Build tools**
|
||||||
|
|
||||||
|
In order to compile GF you need the build tools **Alex** and **Happy**.
|
||||||
|
These can be installed via Cabal, e.g.:
|
||||||
|
|
||||||
|
```
|
||||||
|
cabal install alex happy
|
||||||
|
```
|
||||||
|
|
||||||
|
or obtained by other means, depending on your OS.
|
||||||
|
|
||||||
|
**Haskeline**
|
||||||
|
|
||||||
|
GF uses [`haskeline`](http://hackage.haskell.org/package/haskeline), which
|
||||||
|
on Linux depends on some non-Haskell libraries that won't be installed
|
||||||
|
automatically by cabal, and therefore need to be installed manually.
|
||||||
|
Here is one way to do this:
|
||||||
|
|
||||||
|
- On Ubuntu: `sudo apt-get install libghc-haskeline-dev`
|
||||||
|
- On Fedora: `sudo yum install ghc-haskeline-devel`
|
||||||
|
|
||||||
|
**GHC version**
|
||||||
|
|
||||||
|
The GF source code has been updated to compile with GHC 8.4.
|
||||||
|
Using older versions of GHC (e.g. 8.2, 8.0 and 7.10) should still work too.
|
||||||
|
|
||||||
|
## Installing from the latest developer source code
|
||||||
|
|
||||||
|
If you haven't already, clone the repository with:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/GrammaticalFramework/gf-core.git
|
||||||
|
```
|
||||||
|
|
||||||
|
If you've already cloned the repository previously, update with:
|
||||||
|
|
||||||
|
```
|
||||||
|
git pull
|
||||||
|
```
|
||||||
|
|
||||||
|
Then install with:
|
||||||
|
|
||||||
|
```
|
||||||
|
cabal install
|
||||||
|
```
|
||||||
|
|
||||||
|
or, if you're a Stack user:
|
||||||
|
|
||||||
|
```
|
||||||
|
stack install
|
||||||
|
```
|
||||||
|
|
||||||
|
The above notes for installing from source apply also in these cases.
|
||||||
|
For more info on working with the GF source code, see the
|
||||||
|
[GF Developers Guide](../doc/gf-developers.html).
|
||||||
|
|
||||||
|
## Installing the RGL from source
|
||||||
|
|
||||||
|
To install the RGL from source,
|
||||||
|
you can download a release from [GitHub](https://github.com/GrammaticalFramework/gf-rgl/releases)
|
||||||
|
or get the latest version by cloning the repository:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/GrammaticalFramework/gf-rgl.git
|
||||||
|
```
|
||||||
|
|
||||||
|
In both cases, once you have the RGL sources you can install them by running:
|
||||||
|
|
||||||
|
```
|
||||||
|
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
|
||||||
|
|
||||||
|
- [GF 3.9](index-3.9.html) (August 2017)
|
||||||
|
- [GF 3.8](index-3.8.html) (June 2016)
|
||||||
|
- [GF 3.7.1](index-3.7.1.html) (October 2015)
|
||||||
|
- [GF 3.7](index-3.7.html) (June 2015)
|
||||||
|
- [GF 3.6](index-3.6.html) (June 2014)
|
||||||
|
- [GF 3.5](index-3.5.html) (August 2013)
|
||||||
|
- [GF 3.4](index-3.4.html) (January 2013)
|
||||||
|
- [GF 3.3.3](index-3.3.3.html) (March 2012)
|
||||||
|
- [GF 3.3](index-3.3.html) (October 2011)
|
||||||
|
- [GF 3.2.9](index-3.2.9.html) source-only snapshot (September 2011)
|
||||||
|
- [GF 3.2](index-3.2.html) (December 2010)
|
||||||
|
- [GF 3.1.6](index-3.1.6.html) (April 2010)
|
||||||
@@ -57,8 +57,3 @@ Internal
|
|||||||
|
|
||||||
Javascript generation is not updated to the new PGF format.
|
Javascript generation is not updated to the new PGF format.
|
||||||
[GF 3.1 old-index.html] should still be used for building Javascript applications.
|
[GF 3.1 old-index.html] should still be used for building Javascript applications.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
66
download/release-3.10.md
Normal file
66
download/release-3.10.md
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
title: GF 3.10 Release Notes
|
||||||
|
date: 2 December 2018
|
||||||
|
...
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
See the [download page](index.html).
|
||||||
|
|
||||||
|
## What's new
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
## 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
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
GF Version 3.2 Release Notes
|
GF Version 3.2 Release Notes
|
||||||
December 2010
|
December 2010
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): <H1> <H1><IMG src="../doc/Logos/gf0.png">
|
|
||||||
|
|
||||||
==Installation==
|
==Installation==
|
||||||
|
|
||||||
See the [download page http://www.grammaticalframework.org/download/index.html].
|
See the [download page http://www.grammaticalframework.org/download/index.html].
|
||||||
@@ -34,8 +31,3 @@ See the [download page http://www.grammaticalframework.org/download/index.html].
|
|||||||
|
|
||||||
- GF compiler: GPL
|
- GF compiler: GPL
|
||||||
- Run-time libraries and Resource Grammar Library: LGPL + BSD
|
- Run-time libraries and Resource Grammar Library: LGPL + BSD
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
GF Version 3.3.3 Release Notes
|
GF Version 3.3.3 Release Notes
|
||||||
March 2012
|
March 2012
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): <TITLE> <meta name = "viewport" content = "width = device-width"><TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><IMG src="../doc/Logos/gf0.png">
|
|
||||||
|
|
||||||
==Installation==
|
==Installation==
|
||||||
|
|
||||||
See the [download page http://www.grammaticalframework.org/download/index.html].
|
See the [download page http://www.grammaticalframework.org/download/index.html].
|
||||||
@@ -25,8 +21,3 @@ See the [download page http://www.grammaticalframework.org/download/index.html].
|
|||||||
- Fix for a bug that prevented the shell commands ``abstract_info``,
|
- Fix for a bug that prevented the shell commands ``abstract_info``,
|
||||||
``generate_random`` and ``generate_trees`` from working properly.
|
``generate_random`` and ``generate_trees`` from working properly.
|
||||||
- Various other small improvements and bug fixes.
|
- Various other small improvements and bug fixes.
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
GF Version 3.3 Release Notes
|
GF Version 3.3 Release Notes
|
||||||
October 2011
|
October 2011
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): <TITLE> <meta name = "viewport" content = "width = device-width"><TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><IMG src="../doc/Logos/gf0.png">
|
|
||||||
|
|
||||||
==Installation==
|
==Installation==
|
||||||
|
|
||||||
See the [download page http://www.grammaticalframework.org/download/index.html].
|
See the [download page http://www.grammaticalframework.org/download/index.html].
|
||||||
@@ -29,8 +25,3 @@ See the [download page http://www.grammaticalframework.org/download/index.html].
|
|||||||
and the web-based grammar editor.
|
and the web-based grammar editor.
|
||||||
- Faster grammar compilation (also included in the GF 3.2.9 source-only
|
- Faster grammar compilation (also included in the GF 3.2.9 source-only
|
||||||
snapshot).
|
snapshot).
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
GF Version 3.4 Release Notes
|
GF Version 3.4 Release Notes
|
||||||
January 2013
|
January 2013
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): <TITLE> <meta charset="UTF-8"><meta name = "viewport" content = "width = device-width"> <TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
==Installation==
|
==Installation==
|
||||||
|
|
||||||
See the [download page http://www.grammaticalframework.org/download/index.html].
|
See the [download page http://www.grammaticalframework.org/download/index.html].
|
||||||
@@ -46,8 +42,3 @@ See the [download page http://www.grammaticalframework.org/download/index.html].
|
|||||||
- Some new functionality in the web-based grammar editor, e.g. preliminary
|
- Some new functionality in the web-based grammar editor, e.g. preliminary
|
||||||
support for public grammars.
|
support for public grammars.
|
||||||
- Various other small improvements and bug fixes.
|
- Various other small improvements and bug fixes.
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
GF 3.5 Release Notes
|
GF 3.5 Release Notes
|
||||||
August 2013
|
August 2013
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): <TITLE> <meta charset="UTF-8"><meta name = "viewport" content = "width = device-width"> <TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
==Installation==
|
==Installation==
|
||||||
|
|
||||||
See the [download page http://www.grammaticalframework.org/download/index.html].
|
See the [download page http://www.grammaticalframework.org/download/index.html].
|
||||||
@@ -70,7 +66,3 @@ of GF 3.4.
|
|||||||
[``network-2.4.1.1`` https://github.com/haskell/network/commit/f2168b1f8978b4ad9c504e545755f0795ac869ce].
|
[``network-2.4.1.1`` https://github.com/haskell/network/commit/f2168b1f8978b4ad9c504e545755f0795ac869ce].
|
||||||
- Various other small improvements and bug fixes.
|
- Various other small improvements and bug fixes.
|
||||||
%- [...]
|
%- [...]
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
GF 3.6 Release Notes
|
GF 3.6 Release Notes
|
||||||
June 2014
|
June 2014
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): <TITLE> <meta charset="UTF-8"><meta name = "viewport" content = "width = device-width"> <TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
==Installation==
|
==Installation==
|
||||||
|
|
||||||
See the [download page http://www.grammaticalframework.org/download/index.html].
|
See the [download page http://www.grammaticalframework.org/download/index.html].
|
||||||
@@ -107,8 +103,3 @@ Closed [issues http://code.google.com/p/grammatical-framework/issues/list]:
|
|||||||
- ``c-wordforword``: this works as ``c-translate`` but does a
|
- ``c-wordforword``: this works as ``c-translate`` but does a
|
||||||
word-for-word lookup to create a (potentially very low quality)
|
word-for-word lookup to create a (potentially very low quality)
|
||||||
translation that can be used if all else fails.
|
translation that can be used if all else fails.
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
GF 3.7.1 Release Notes
|
GF 3.7.1 Release Notes
|
||||||
October 2015
|
October 2015
|
||||||
|
|
||||||
%!style:../css/notes.css
|
|
||||||
%!postproc(html): <TITLE> <meta charset="UTF-8"><meta name = "viewport" content = "width = device-width"> <TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
==Installation==
|
==Installation==
|
||||||
|
|
||||||
See the [download page http://www.grammaticalframework.org/download/index.html].
|
See the [download page http://www.grammaticalframework.org/download/index.html].
|
||||||
@@ -77,8 +73,3 @@ Over 170 changes have been pushed to the source repository since
|
|||||||
you can leave ``&+`` uninterpreted instead of gluing the adjacent tokens.
|
you can leave ``&+`` uninterpreted instead of gluing the adjacent tokens.
|
||||||
This means that the output is left in a format that can be parsed in
|
This means that the output is left in a format that can be parsed in
|
||||||
a subsequent request.
|
a subsequent request.
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
GF 3.7 Release Notes
|
GF 3.7 Release Notes
|
||||||
June 2015
|
June 2015
|
||||||
|
|
||||||
%!style:../css/style.css
|
|
||||||
%!postproc(html): <TITLE> <meta charset="UTF-8"><meta name = "viewport" content = "width = device-width"> <TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
==Installation==
|
==Installation==
|
||||||
|
|
||||||
See the [download page http://www.grammaticalframework.org/download/index.html].
|
See the [download page http://www.grammaticalframework.org/download/index.html].
|
||||||
@@ -103,8 +99,3 @@ Over 800 changes have been pushed to the source repository since
|
|||||||
unused for 24 hours, to keep memory use down in long running servers.
|
unused for 24 hours, to keep memory use down in long running servers.
|
||||||
- PGF service: limit the number of parallel calls to the C run-time parse
|
- PGF service: limit the number of parallel calls to the C run-time parse
|
||||||
function to 4 by default. The limit can be changed with the ``-j`` flag.
|
function to 4 by default. The limit can be changed with the ``-j`` flag.
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
GF 3.8 Release Notes
|
GF 3.8 Release Notes
|
||||||
June 2016
|
June 2016
|
||||||
|
|
||||||
%!style:../css/notes.css
|
|
||||||
%!postproc(html): <TITLE> <meta charset="UTF-8"><meta name = "viewport" content = "width = device-width"> <TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
==Installation==
|
==Installation==
|
||||||
|
|
||||||
See the [download page http://www.grammaticalframework.org/download/index.html].
|
See the [download page http://www.grammaticalframework.org/download/index.html].
|
||||||
@@ -100,7 +96,3 @@ Roughly 400 changes have been pushed to the source repository since
|
|||||||
translations in the domain they cover.
|
translations in the domain they cover.
|
||||||
You can change the order in which the selected grammars are tried
|
You can change the order in which the selected grammars are tried
|
||||||
by dragging them up and down in the list.
|
by dragging them up and down in the list.
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
GF 3.9 Release Notes
|
GF 3.9 Release Notes
|
||||||
August 2017
|
August 2017
|
||||||
|
|
||||||
%!style:../css/notes.css
|
|
||||||
%!postproc(html): <TITLE> <meta charset="UTF-8"><meta name = "viewport" content = "width = device-width"> <TITLE>
|
|
||||||
%!postproc(html): <H1> <H1><a href="../"><IMG src="../doc/Logos/gf0.png"></a>
|
|
||||||
|
|
||||||
==Installation==
|
==Installation==
|
||||||
|
|
||||||
See the [download page http://www.grammaticalframework.org/download/index.html].
|
See the [download page http://www.grammaticalframework.org/download/index.html].
|
||||||
@@ -66,8 +62,3 @@ the full functionality of the C runtime.
|
|||||||
|
|
||||||
- PGF service: support for language-specific depencency configurations in
|
- PGF service: support for language-specific depencency configurations in
|
||||||
``command=deptree``.
|
``command=deptree``.
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
[www.grammaticalframework.org http://www.grammaticalframework.org]
|
|
||||||
|
|||||||
BIN
favicon.ico
Normal file
BIN
favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
154
gf.cabal
154
gf.cabal
@@ -1,5 +1,5 @@
|
|||||||
name: gf
|
name: gf
|
||||||
version: 3.10
|
version: 3.10.3-git
|
||||||
|
|
||||||
cabal-version: >= 1.22
|
cabal-version: >= 1.22
|
||||||
build-type: Custom
|
build-type: Custom
|
||||||
@@ -11,7 +11,7 @@ description: GF, Grammatical Framework, is a programming language for multilingu
|
|||||||
homepage: http://www.grammaticalframework.org/
|
homepage: http://www.grammaticalframework.org/
|
||||||
bug-reports: https://github.com/GrammaticalFramework/gf-core/issues
|
bug-reports: https://github.com/GrammaticalFramework/gf-core/issues
|
||||||
maintainer: Thomas Hallgren
|
maintainer: Thomas Hallgren
|
||||||
tested-with: GHC==7.6.3, GHC==7.8.3, GHC==7.10.3, GHC==8.0.2
|
tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.3
|
||||||
|
|
||||||
data-dir: src
|
data-dir: src
|
||||||
data-files:
|
data-files:
|
||||||
@@ -47,6 +47,10 @@ custom-setup
|
|||||||
filepath,
|
filepath,
|
||||||
process >=1.0.1.1
|
process >=1.0.1.1
|
||||||
|
|
||||||
|
--source-repository head
|
||||||
|
-- type: darcs
|
||||||
|
-- location: http://www.grammaticalframework.org/
|
||||||
|
|
||||||
source-repository head
|
source-repository head
|
||||||
type: git
|
type: git
|
||||||
location: https://github.com/GrammaticalFramework/gf-core.git
|
location: https://github.com/GrammaticalFramework/gf-core.git
|
||||||
@@ -63,17 +67,12 @@ flag network-uri
|
|||||||
description: Get Network.URI from the network-uri package
|
description: Get Network.URI from the network-uri package
|
||||||
default: True
|
default: True
|
||||||
|
|
||||||
--flag new-comp
|
executable gf
|
||||||
-- Description: Make -new-comp the default
|
hs-source-dirs: src/programs
|
||||||
-- Default: True
|
main-is: gf-main.hs
|
||||||
|
|
||||||
flag c-runtime
|
|
||||||
Description: Include functionality from the C run-time library (which must be installed already)
|
|
||||||
Default: False
|
|
||||||
|
|
||||||
Library
|
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
build-depends: base >= 4.6 && <5,
|
build-depends: pgf2,
|
||||||
|
base >= 4.6 && <5,
|
||||||
array,
|
array,
|
||||||
containers,
|
containers,
|
||||||
bytestring,
|
bytestring,
|
||||||
@@ -81,77 +80,28 @@ Library
|
|||||||
random,
|
random,
|
||||||
pretty,
|
pretty,
|
||||||
mtl,
|
mtl,
|
||||||
exceptions
|
exceptions,
|
||||||
hs-source-dirs: src/runtime/haskell
|
ghc-prim,
|
||||||
|
filepath, directory>=1.2, time,
|
||||||
|
process, haskeline, parallel>=3, json
|
||||||
|
ghc-options: -threaded
|
||||||
|
|
||||||
other-modules:
|
if impl(ghc>=7.0)
|
||||||
-- not really part of GF but I have changed the original binary library
|
ghc-options: -rtsopts -with-rtsopts=-I5
|
||||||
-- and we have to keep the copy for now.
|
if impl(ghc<7.8)
|
||||||
Data.Binary
|
ghc-options: -with-rtsopts=-K64M
|
||||||
Data.Binary.Put
|
|
||||||
Data.Binary.Get
|
|
||||||
Data.Binary.Builder
|
|
||||||
Data.Binary.IEEE754
|
|
||||||
|
|
||||||
--ghc-options: -fwarn-unused-imports
|
ghc-prof-options: -auto-all
|
||||||
--if impl(ghc>=7.8)
|
|
||||||
-- ghc-options: +RTS -A20M -RTS
|
|
||||||
ghc-prof-options: -fprof-auto
|
|
||||||
extensions:
|
|
||||||
|
|
||||||
exposed-modules:
|
|
||||||
PGF
|
|
||||||
PGF.Internal
|
|
||||||
PGF.Haskell
|
|
||||||
|
|
||||||
other-modules:
|
|
||||||
PGF.Data
|
|
||||||
PGF.Macros
|
|
||||||
PGF.Binary
|
|
||||||
PGF.Optimize
|
|
||||||
PGF.Printer
|
|
||||||
PGF.CId
|
|
||||||
PGF.Expr
|
|
||||||
PGF.Generate
|
|
||||||
PGF.Linearize
|
|
||||||
PGF.Morphology
|
|
||||||
PGF.Paraphrase
|
|
||||||
PGF.Parse
|
|
||||||
PGF.Probabilistic
|
|
||||||
PGF.SortTop
|
|
||||||
PGF.Tree
|
|
||||||
PGF.Type
|
|
||||||
PGF.TypeCheck
|
|
||||||
PGF.Forest
|
|
||||||
PGF.TrieMap
|
|
||||||
PGF.VisualizeTree
|
|
||||||
PGF.ByteCode
|
|
||||||
PGF.OldBinary
|
|
||||||
PGF.Utilities
|
|
||||||
|
|
||||||
if flag(c-runtime)
|
|
||||||
exposed-modules: PGF2
|
|
||||||
other-modules: PGF2.FFI PGF2.Expr PGF2.Type
|
|
||||||
GF.Interactive2 GF.Command.Commands2
|
|
||||||
hs-source-dirs: src/runtime/haskell-bind
|
|
||||||
build-tools: hsc2hs
|
|
||||||
extra-libraries: pgf gu
|
|
||||||
c-sources: src/runtime/haskell-bind/utils.c
|
|
||||||
cc-options: -std=c99
|
|
||||||
|
|
||||||
---- GF compiler as a library:
|
|
||||||
|
|
||||||
build-depends: filepath, directory, time, time-compat, old-locale,
|
|
||||||
process, haskeline, parallel>=3
|
|
||||||
|
|
||||||
hs-source-dirs: src/compiler
|
hs-source-dirs: src/compiler
|
||||||
exposed-modules:
|
|
||||||
|
other-modules:
|
||||||
GF
|
GF
|
||||||
GF.Support
|
GF.Support
|
||||||
GF.Text.Pretty
|
GF.Text.Pretty
|
||||||
GF.Text.Lexing
|
GF.Text.Lexing
|
||||||
|
GF.Grammar.Canonical
|
||||||
|
|
||||||
other-modules:
|
|
||||||
GF.Main GF.Compiler GF.Interactive
|
GF.Main GF.Compiler GF.Interactive
|
||||||
|
|
||||||
GF.Compile GF.CompileInParallel GF.CompileOne GF.Compile.GetGrammar
|
GF.Compile GF.CompileInParallel GF.CompileOne GF.Compile.GetGrammar
|
||||||
@@ -174,7 +124,6 @@ Library
|
|||||||
GF.Compile.CheckGrammar
|
GF.Compile.CheckGrammar
|
||||||
GF.Compile.Compute.AppPredefined
|
GF.Compile.Compute.AppPredefined
|
||||||
GF.Compile.Compute.ConcreteNew
|
GF.Compile.Compute.ConcreteNew
|
||||||
-- GF.Compile.Compute.ConcreteNew1
|
|
||||||
GF.Compile.Compute.Predef
|
GF.Compile.Compute.Predef
|
||||||
GF.Compile.Compute.Value
|
GF.Compile.Compute.Value
|
||||||
GF.Compile.ExampleBased
|
GF.Compile.ExampleBased
|
||||||
@@ -184,13 +133,14 @@ Library
|
|||||||
GF.Compile.GrammarToPGF
|
GF.Compile.GrammarToPGF
|
||||||
GF.Compile.Multi
|
GF.Compile.Multi
|
||||||
GF.Compile.Optimize
|
GF.Compile.Optimize
|
||||||
|
GF.Compile.OptimizePGF
|
||||||
GF.Compile.PGFtoHaskell
|
GF.Compile.PGFtoHaskell
|
||||||
GF.Compile.PGFtoJava
|
GF.Compile.PGFtoJava
|
||||||
GF.Haskell
|
GF.Haskell
|
||||||
GF.Compile.ConcreteToHaskell
|
GF.Compile.ConcreteToHaskell
|
||||||
GF.Compile.PGFtoJS
|
GF.Compile.GrammarToCanonical
|
||||||
GF.Compile.PGFtoProlog
|
GF.Grammar.CanonicalJSON
|
||||||
GF.Compile.PGFtoPython
|
GF.Compile.PGFtoJSON
|
||||||
GF.Compile.ReadFiles
|
GF.Compile.ReadFiles
|
||||||
GF.Compile.Rename
|
GF.Compile.Rename
|
||||||
GF.Compile.SubExOpt
|
GF.Compile.SubExOpt
|
||||||
@@ -260,14 +210,20 @@ Library
|
|||||||
GF.System.Signal
|
GF.System.Signal
|
||||||
GF.Text.Clitics
|
GF.Text.Clitics
|
||||||
GF.Text.Coding
|
GF.Text.Coding
|
||||||
|
GF.Text.Lexing
|
||||||
GF.Text.Transliterations
|
GF.Text.Transliterations
|
||||||
Paths_gf
|
Paths_gf
|
||||||
|
|
||||||
if flag(c-runtime)
|
-- not really part of GF but I have changed the original binary library
|
||||||
cpp-options: -DC_RUNTIME
|
-- and we have to keep the copy for now.
|
||||||
|
Data.Binary
|
||||||
|
Data.Binary.Put
|
||||||
|
Data.Binary.Get
|
||||||
|
Data.Binary.Builder
|
||||||
|
Data.Binary.IEEE754
|
||||||
|
|
||||||
if flag(server)
|
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
|
cgi>=3001.2.2.0
|
||||||
if flag(network-uri)
|
if flag(network-uri)
|
||||||
build-depends: network-uri>=2.6, network>=2.6
|
build-depends: network-uri>=2.6, network>=2.6
|
||||||
@@ -287,7 +243,7 @@ Library
|
|||||||
CGIUtils
|
CGIUtils
|
||||||
Cache
|
Cache
|
||||||
Fold
|
Fold
|
||||||
hs-source-dirs: src/server src/server/transfer
|
hs-source-dirs: src/server src/server/transfer src/example-based
|
||||||
|
|
||||||
if flag(interrupt)
|
if flag(interrupt)
|
||||||
cpp-options: -DUSE_INTERRUPT
|
cpp-options: -DUSE_INTERRUPT
|
||||||
@@ -297,7 +253,6 @@ Library
|
|||||||
|
|
||||||
if impl(ghc>=7.8)
|
if impl(ghc>=7.8)
|
||||||
build-tools: happy>=1.19, alex>=3.1
|
build-tools: happy>=1.19, alex>=3.1
|
||||||
-- ghc-options: +RTS -A20M -RTS
|
|
||||||
else
|
else
|
||||||
build-tools: happy, alex>=3
|
build-tools: happy, alex>=3
|
||||||
|
|
||||||
@@ -308,36 +263,13 @@ Library
|
|||||||
else
|
else
|
||||||
build-depends: unix, terminfo>=0.4
|
build-depends: unix, terminfo>=0.4
|
||||||
|
|
||||||
if impl(ghc>=8.2)
|
|
||||||
ghc-options: -fhide-source-paths
|
|
||||||
|
|
||||||
Executable gf
|
test-suite rgl-tests
|
||||||
hs-source-dirs: src/programs
|
type: exitcode-stdio-1.0
|
||||||
main-is: gf-main.hs
|
main-is: run.hs
|
||||||
|
hs-source-dirs: lib/tests/
|
||||||
|
build-depends: base, HTF, process, HUnit, filepath, directory
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
build-depends: gf, base
|
|
||||||
ghc-options: -threaded
|
|
||||||
--ghc-options: -fwarn-unused-imports
|
|
||||||
|
|
||||||
if impl(ghc>=7.0)
|
|
||||||
ghc-options: -rtsopts -with-rtsopts=-I5
|
|
||||||
if impl(ghc<7.8)
|
|
||||||
ghc-options: -with-rtsopts=-K64M
|
|
||||||
|
|
||||||
ghc-prof-options: -auto-all
|
|
||||||
|
|
||||||
if impl(ghc>=8.2)
|
|
||||||
ghc-options: -fhide-source-paths
|
|
||||||
|
|
||||||
executable pgf-shell
|
|
||||||
--if !flag(c-runtime)
|
|
||||||
buildable: False
|
|
||||||
main-is: pgf-shell.hs
|
|
||||||
hs-source-dirs: src/runtime/haskell-bind/examples
|
|
||||||
build-depends: gf, base, containers, mtl, lifted-base
|
|
||||||
default-language: Haskell2010
|
|
||||||
if impl(ghc>=7.0)
|
|
||||||
ghc-options: -rtsopts
|
|
||||||
|
|
||||||
test-suite gf-tests
|
test-suite gf-tests
|
||||||
type: exitcode-stdio-1.0
|
type: exitcode-stdio-1.0
|
||||||
|
|||||||
709
index.html
709
index.html
@@ -1,418 +1,390 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<HTML>
|
<html lang="en">
|
||||||
<HEAD>
|
<head>
|
||||||
<TITLE>GF - Grammatical Framework</TITLE>
|
<meta charset="utf-8">
|
||||||
<meta charset="UTF-8">
|
|
||||||
<link rel="stylesheet" href="css/newstyle.css" title="GF">
|
|
||||||
<link rel="alternate" href="https://github.com/GrammaticalFramework/gf-core/" title="GF GitHub repository">
|
|
||||||
<meta name = "viewport" content = "width = device-width">
|
|
||||||
<script type="text/javascript">
|
|
||||||
function sitesearch() {
|
|
||||||
var q=document.forms[0].q.value;
|
|
||||||
var site=" site:www.grammaticalframework.org";
|
|
||||||
var search=encodeURIComponent(q+site)
|
|
||||||
document.location.href="http://www.google.com/search?q="+search
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<meta name="keywords" content="machine translation">
|
|
||||||
</HEAD>
|
|
||||||
|
|
||||||
<body class=new>
|
<title>GF - Grammatical Framework</title>
|
||||||
|
<meta name="keywords" content="machine translation">
|
||||||
|
|
||||||
<div class="header sky blue">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<img class="gflogo" src="doc/Logos/gf1.svg" alt="">
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||||
<H1>Grammatical Framework</H1>
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.2/css/all.css" integrity="sha384-/rXc/GQVaYpyDdyxK+ecHPVYJSN9bmVFBvjA/9eOB+pb3F2w2N6fc5qB9Ew5yIns" crossorigin="anonymous">
|
||||||
<small class=tagline>A programming language for multilingual grammar applications</small>
|
|
||||||
|
<link rel="alternate" href="https://github.com/GrammaticalFramework/gf-core/" title="GF GitHub repository">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container-fluid my-5" style="max-width:1200px">
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<img style="height:250px" src="doc/Logos/gf1.svg" alt="GF Logo">
|
||||||
|
<h1 class="display-4" style="text-shadow: 1px 1px 5px #999;">Grammatical Framework</h1>
|
||||||
|
<h4 class="text-black-50">A programming language for multilingual grammar applications</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class=menu>
|
<div class="row my-4">
|
||||||
|
|
||||||
<div class=links>
|
<div class="col-sm-6 col-md-3">
|
||||||
<h4>Use GF</h4>
|
<h3>Get started</h3>
|
||||||
<ul>
|
<ul class="mb-2">
|
||||||
<li><a href="http://cloud.grammaticalframework.org/">GF Cloud<img class=right src="src/www/P/gf-cloud.png" alt="GF Cloud Service" title="GF Cloud Service"></a>
|
<li><a href="https://www.youtube.com/watch?v=x1LFbDQhbso">Google Tech Talk</a></li>
|
||||||
<li><A HREF="demos/index.html">Other Demos</A>
|
<li>
|
||||||
</ul>
|
<a href="//cloud.grammaticalframework.org/">
|
||||||
<ul>
|
GF Cloud
|
||||||
<li><A HREF="http://www.grammaticalframework.org/download/index.html"><b>Download GF</b></A>
|
<img src="src/www/P/gf-cloud.png" style="height:30px" class="ml-2" alt="Cloud logo">
|
||||||
<li><a href="doc/gf-editor-modes.html">GF Editor Modes</a>
|
</a>
|
||||||
</ul>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="doc/tutorial/gf-tutorial.html">Tutorial</a>
|
||||||
|
/
|
||||||
|
<a href="lib/doc/rgl-tutorial/index.html">RGL Tutorial</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<ul>
|
<a href="download/index.html" class="btn btn-primary ml-3">
|
||||||
<li><A HREF="http://groups.google.com/group/gf-dev">User Group</A>
|
<i class="fas fa-download mr-1"></i>
|
||||||
<li><a href="https://github.com/GrammaticalFramework/gf-core/issues">Bug Reports</a>
|
Download GF
|
||||||
(<a href="http://code.google.com/p/grammatical-framework/issues/list">old</a>)
|
</a>
|
||||||
</ul>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class=links>
|
<div class="col-sm-6 col-md-3">
|
||||||
<h4>Learn GF</h4>
|
<h3>Learn more</h3>
|
||||||
<ul>
|
|
||||||
<li><a href="https://www.youtube.com/watch?v=x1LFbDQhbso">Google Tech Talk</a>
|
|
||||||
<li><A HREF="doc/gf-quickstart.html">QuickStart</A>
|
|
||||||
<li><A HREF="doc/gf-reference.html">QuickRefCard</A>
|
|
||||||
<li><A HREF="doc/gf-shell-reference.html">GF Shell Reference</A>
|
|
||||||
<li><a href="http://school.grammaticalframework.org/"><b>GF Summer School</b></a>
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li><A HREF="gf-book">The GF Book</A>
|
|
||||||
<li><A HREF="doc/tutorial/gf-tutorial.html">GF Tutorial</A>
|
|
||||||
<li><A HREF="doc/gf-refman.html">Reference Manual</A>
|
|
||||||
<li><A HREF="http://www.molto-project.eu/sites/default/files/MOLTO_D2.3.pdf">Best Practices</A> <small>[PDF]</small>
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li><A HREF="lib/doc/synopsis.html">Library Synopsis</A>
|
|
||||||
<li><A HREF="doc/gf-lrec-2010.pdf">Library Tutorial</A> <small>[PDF]</small>
|
|
||||||
<li><A HREF="http://www.postcrashgames.com/gf_world/">Coverage Map</A>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
<ul class="mb-2">
|
||||||
<div class=links>
|
<li><a href="gf-book">The GF Book</a></li>
|
||||||
<h4>Develop GF</h4>
|
<li><a href="doc/gf-refman.html">Reference Manual</a></li>
|
||||||
<ul>
|
<li><a href="doc/gf-shell-reference.html">Shell Reference</a></li>
|
||||||
<li><a href="doc/gf-developers.html">GF Developers Guide</a>
|
<li><a href="http://www.molto-project.eu/sites/default/files/MOLTO_D2.3.pdf">Best Practices</a> <small>[PDF]</small></li>
|
||||||
<li><A HREF="https://github.com/GrammaticalFramework/">GF on GitHub</A>
|
</ul>
|
||||||
<li><a href="/~hallgren/gf-experiment/browse/">Browse Source Code</a>
|
|
||||||
<li><A HREF="doc/gf-people.html">Authors</A>
|
|
||||||
</ul>
|
|
||||||
<h4>Develop Applications</h4>
|
|
||||||
<ul>
|
|
||||||
<li><a href="http://hackage.haskell.org/package/gf-3.9/docs/PGF.html">PGF library API (Old Runtime)</a>
|
|
||||||
<li><a href="doc/runtime-api.html">PGF library API (New Runtime)</a>
|
|
||||||
<li><a href="https://github.com/GrammaticalFramework/gf-offline-translator/tree/master/android">GF on Android (new)</a>
|
|
||||||
<li><A HREF="/android/">GF on Android (old) </A>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class=links>
|
|
||||||
<h4>Related to GF</h4>
|
|
||||||
<ul>
|
|
||||||
<li><A HREF="doc/gf-bibliography.html">Publications</A>
|
|
||||||
<li><A HREF="http://remu.grammaticalframework.org/">The REMU Project</A>
|
|
||||||
<li><A HREF="http://www.molto-project.eu">The MOLTO Project</A>
|
|
||||||
<li><a href="http://en.wikipedia.org/wiki/Grammatical_Framework">GF on Wikipedia</a>
|
|
||||||
<li><p><a href="Http://www.digitalgrammars.com/">Digital Grammars AB</a>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<a href="lib/doc/synopsis/index.html" class="btn btn-primary ml-3">
|
||||||
|
<i class="fab fa-readme mr-1"></i>
|
||||||
|
RGL Synopsis
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<div class="col-sm-6 col-md-3">
|
||||||
document.write('<div style="float: right; margin-top: 3ex;"> <form onsubmit="return sitesearch()" method=get action="http://www.google.com/search"> <input type=search name="q" placeholder="site search"> <input type=submit value="Search"> </form></div>')
|
<h3>Develop</h3>
|
||||||
</script>
|
<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>
|
||||||
|
<li><a href="doc/runtime-api.html">PGF library API (C runtime)</a></li>
|
||||||
|
<li><a href="http://hackage.haskell.org/package/gf/docs/GF.html">GF compiler API</a></li>
|
||||||
|
<!-- <li><a href="src/ui/android/README">GF on Android (new)</a></li>
|
||||||
|
<li><a href="/android/">GF on Android (old) </a></li> -->
|
||||||
|
<li><a href="doc/gf-editor-modes.html">Text Editor Support</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<H2 class=noclear>News</H2>
|
<div class="col-sm-6 col-md-3">
|
||||||
|
<h3>Contribute</h3>
|
||||||
<div class=news2>
|
<ul class="mb-2">
|
||||||
|
<li><a href="http://groups.google.com/group/gf-dev">Mailing List</a></li>
|
||||||
<table class=news>
|
<li><a href="https://github.com/GrammaticalFramework/gf-core/issues">Issue Tracker</a></li>
|
||||||
<tr><td>2018-07-25:<td>The GF repository has been split in two:
|
<li><a href="doc/gf-people.html">Authors</a></li>
|
||||||
<a href="https://github.com/GrammaticalFramework/gf-core">gf-core</a> and
|
<li><a href="//school.grammaticalframework.org/2018/">Summer School</a></li>
|
||||||
<a href="https://github.com/GrammaticalFramework/gf-rgl">gf-rgl</a>.
|
</ul>
|
||||||
The original <a href="https://github.com/GrammaticalFramework/GF">GF</a> repository is now archived.
|
<a href="https://github.com/GrammaticalFramework/" class="btn btn-primary ml-3">
|
||||||
<tr><td>2017-08-11:<td><strong>GF 3.9 released!</strong>
|
<i class="fab fa-github mr-1"></i>
|
||||||
<a href="download/release-3.9.html">Release notes</a>.
|
GF on GitHub
|
||||||
<tr><td>2017-06-29:<td>GF is moving to <a href="https://github.com/GrammaticalFramework/GF/">GitHub</a>!
|
</a>
|
||||||
<tr><td>2017-03-13:<td><strong>GF Summer School in Riga (Latvia), 14-25 August 2017</strong>
|
</div>
|
||||||
<a href="http://school.grammaticalframework.org/2017/">Summer
|
|
||||||
School web page</a>.
|
|
||||||
<tr><td>2016-09-07:<td><strong>Google Tech Talk on GF</strong> <a
|
|
||||||
href="https://www.youtube.com/watch?v=x1LFbDQhbso">on Youtube</a>.
|
|
||||||
<tr><td>2016-07-05:<td>GitHub mirror temporarily not updated, due to server migration.
|
|
||||||
<tr><td>2016-06-22:<td><strong>GF 3.8 released!</strong>
|
|
||||||
<a href="download/release-3.8.html">Release notes</a>.
|
|
||||||
<tr><td>2015-06-21:<td><strong>Summer School in Rule-Based Machine
|
|
||||||
Translation in Alacant/Alicante (Spain), 11-21 July 2016</strong>
|
|
||||||
featuring GF, Apertium, Matxin, and TectoMT.
|
|
||||||
<a href="http://xixona.dlsi.ua.es/rbmt-summer-school/2016/">Summer
|
|
||||||
School web page</a>.
|
|
||||||
<tr><td>2016-06-14:<td>New resource grammar language: Nynorsk.
|
|
||||||
<tr><td>2015-10-02:<td><strong>GF 3.7.1 released!</strong>
|
|
||||||
<a href="download/release-3.7.1.html">Release notes</a>.
|
|
||||||
<tr><td>2015-06-25:<td><strong>GF 3.7 released!</strong>
|
|
||||||
<a href="download/release-3.7.html">Release notes</a>.
|
|
||||||
<tr><td>2015-03-13:<td>New resource grammar language: Mongolian.
|
|
||||||
See <a href="lib/doc/synopsis.html">library synopsis</a>.
|
|
||||||
<tr><td>2015-02-09:<td><strong>GF Summer School in Gozo (Malta), 13-24 July 2015</strong>
|
|
||||||
<a href="http://school.grammaticalframework.org/2015/">Summer
|
|
||||||
School web page</a>.
|
|
||||||
<tr><td>2014-06-23:<td><strong>GF 3.6 released!</strong>
|
|
||||||
<a href="download/release-3.6.html">Release notes</a>.
|
|
||||||
<tr><td>2014-03-11:
|
|
||||||
<td>A company for commercial applications of GF has been founded:
|
|
||||||
<a href="http://www.digitalgrammars.com/">Digital Grammars</a>.
|
|
||||||
<tr><td>2013-11-25:
|
|
||||||
<td>The default character encoding in GF grammar files will be changed
|
|
||||||
from Latin-1 to UTF-8. See
|
|
||||||
<a href="download/encoding-change.html">GF character encoding changes</a>
|
|
||||||
for details.
|
|
||||||
<tr><td>2013-10-18:<td>New resource grammar language: Estonian.
|
|
||||||
See <a href="lib/doc/synopsis.html">library synopsis</a>.
|
|
||||||
<tr><td>2013-09-18:<td>New <a href="https://github.com/GrammaticalFramework/gf-contrib">GF contributions repository</a>, hosted on GitHub.
|
|
||||||
<tr><td>2013-08-06:<td><strong>GF 3.5 released!</strong>
|
|
||||||
<a href="download/release-3.5.html">Release notes</a>.
|
|
||||||
<tr><td>2013-07-26:<td>Started a page with <A HREF="lib/doc/rgl-publications.html">RGL Documentation and Publications</A>.
|
|
||||||
<tr><td>2013-06-24:<td>We are now running the IRC channel <a href="https://webchat.freenode.net/?channels=gf"><strong><code>#gf</code></strong></a> on the Freenode network.
|
|
||||||
<tr><td>2013-06-19:<td>New resource grammar language: Maltese.
|
|
||||||
See <a href="lib/doc/synopsis.html">library synopsis</a>.
|
|
||||||
<tr><td>2013-04-25:<td>New resource grammar language: Greek.
|
|
||||||
See <a href="lib/doc/synopsis.html">library synopsis</a>.
|
|
||||||
<tr><td>2013-01-31:<td><strong>GF 3.4 released!</strong>
|
|
||||||
<a href="download/release-3.4.html">Release notes</a>.
|
|
||||||
<tr><td>2012-12-10:<td>
|
|
||||||
<a href="http://www.postcrashgames.com/gf_world/">Resource Grammar Library
|
|
||||||
coverage map</a>, created by Tommi Nieminen.
|
|
||||||
<!--
|
|
||||||
<tr><td>2012-11-18:<td>
|
|
||||||
<A HREF="http://school.grammaticalframework.org/2013">GF Summer School</A>
|
|
||||||
in Frauenchiemsee, 18-30 August 2013.
|
|
||||||
<tr><td>2012-11-18:<td>New resource grammar language: Chinese.
|
|
||||||
See <a href="lib/doc/synopsis.html">library synopsis</a>.
|
|
||||||
Complete but not yet perfect.
|
|
||||||
<tr><td>2012-06-29:<td>GF sources now mirrored in GitHub, with change
|
|
||||||
statistics and other browsing features.
|
|
||||||
See <a href="https://github.com/GrammaticalFramework/GF/"><tt>github.com/GrammaticalFramework/GF</tt></a>
|
|
||||||
<tr><td>2012-05-07:<td>New resource grammar language: Japanese.
|
|
||||||
See <a href="lib/doc/synopsis.html">library synopsis</a>.
|
|
||||||
<tr><td>2012-03-23:<td>There will be a
|
|
||||||
<a href="gf-tutorial-icfp-2012/">GF tutorial at ICFP 2012</a>
|
|
||||||
in Copenhagen.
|
|
||||||
<tr><td>2012-03-03:<td><strong>GF 3.3.3 released!</strong>
|
|
||||||
<a href="download/release-3.3.3.html">Release notes</a>.
|
|
||||||
<tr><td>2012-02-24:<td>New resource grammar languages: Hindi, Sindhi.
|
|
||||||
See <a href="lib/doc/synopsis.html">library synopsis</a>.
|
|
||||||
<tr><td>2011-12-29:<td>New resource grammar languages: Latvian, Thai.
|
|
||||||
See <a href="lib/doc/synopsis.html">library synopsis</a>.
|
|
||||||
<tr><td>2011-10-27:<td><strong>GF 3.3 released!</strong>
|
|
||||||
<a href="download/release-3.3.html">Release notes</a>.
|
|
||||||
<tr><td>2011-09-20:<td>There is now a page collecting
|
|
||||||
<a href="doc/gf-editor-modes.html">editor modes for GF</a>.
|
|
||||||
Contributions are welcome!
|
|
||||||
<tr><td>2011-09-12:<td><strong>GF 3.2.9</strong> source snapshot with faster grammar compilation available. See <a href="download/index.html">Downloads</a>.
|
|
||||||
<tr><td>2011-04-22:<td><a href="android/tutorial/">JPGF Android Tutorial</a> added.
|
|
||||||
<tr><td>2011-04-15:<td>The <a href="gf-book">GF Book</a> is available.
|
|
||||||
<tr><td>2011-01-13:<td><a href="http://www.molto-project.eu/node/1177">Phrasedroid
|
|
||||||
available on the Android Market</a>.
|
|
||||||
<tr><td>2011-01-04:<td>GF is part of the
|
|
||||||
<a href="http://www.clt.gu.se/clt-toolkit">CLT Toolkit</a>.
|
|
||||||
<tr><td>2010-12-23:<td><strong>GF 3.2 released!</strong>
|
|
||||||
<a href="download/release-3.2.html">Release notes</a>.
|
|
||||||
-->
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<H2>What is GF</H2>
|
<h2>What is GF?</h2>
|
||||||
<P>
|
<p>
|
||||||
GF, Grammatical Framework, is a programming language for
|
GF, Grammatical Framework, is a programming language for
|
||||||
<B>multilingual grammar applications</B>. It is
|
<strong>multilingual grammar applications</strong>. It is
|
||||||
</P>
|
</p>
|
||||||
<UL>
|
<ul>
|
||||||
<LI>a <B>special-purpose language for grammars</B>, like
|
<li>a <strong>special-purpose language for grammars</strong>, like
|
||||||
<a href="http://dinosaur.compilertools.net/yacc/">YACC</a>,
|
<a href="http://dinosaur.compilertools.net/yacc/">YACC</a>,
|
||||||
<a href="http://www.gnu.org/software/bison/">Bison</a>,
|
<a href="http://www.gnu.org/software/bison/">Bison</a>,
|
||||||
<a href="http://www.haskell.org/happy/">Happy</a>,
|
<a href="http://www.haskell.org/happy/">Happy</a>,
|
||||||
<a href="http://bnfc.digitalgrammars.com/">BNFC</a>,
|
<a href="http://bnfc.digitalgrammars.com/">BNFC</a>,
|
||||||
but not restricted to programming languages
|
but not restricted to programming languages
|
||||||
<LI>a <B>functional programming language</B>, like
|
</li>
|
||||||
|
<li>a <strong>functional programming language</strong>, like
|
||||||
<a href="http://www.haskell.org/">Haskell</a>,
|
<a href="http://www.haskell.org/">Haskell</a>,
|
||||||
<a href="http://en.wikipedia.org/wiki/Lisp_(programming_language)">Lisp</a>,
|
<a href="http://en.wikipedia.org/wiki/Lisp_(programming_language)">Lisp</a>,
|
||||||
<a href="http://ocaml.org/">OCaml</a>,
|
<a href="http://ocaml.org/">OCaml</a>,
|
||||||
<a href="http://www.smlnj.org/">SML</a>,
|
<a href="http://www.smlnj.org/">SML</a>,
|
||||||
<a href="http://schemers.org/">Scheme</a>,
|
<a href="http://schemers.org/">Scheme</a>,
|
||||||
but specialized to grammar writing
|
but specialized to grammar writing
|
||||||
<LI>a <B>development platform for natural language grammars</B>, like
|
</li>
|
||||||
|
<li>a <strong>development platform for natural language grammars</strong>, like
|
||||||
<a href="http://moin.delph-in.net/LkbTop">LKB</a>,
|
<a href="http://moin.delph-in.net/LkbTop">LKB</a>,
|
||||||
<a href="http://www2.parc.com/isl/groups/nltt/xle/">XLE</a>,
|
<a href="http://www2.parc.com/isl/groups/nltt/xle/">XLE</a>,
|
||||||
<a href="http://www.issco.unige.ch/en/research/projects/regulus/news.shtml">Regulus</a>,
|
<a href="http://www.issco.unige.ch/en/research/projects/regulus/news.shtml">Regulus</a>,
|
||||||
but based on functional programming and type theory
|
but based on functional programming and type theory
|
||||||
<LI>a <B>categorial grammar formalism</B>, like
|
</li>
|
||||||
|
<li>a <strong>categorial grammar formalism</strong>, like
|
||||||
<a href="http://www.loria.fr/equipes/calligramme/acg/">ACG</a>,
|
<a href="http://www.loria.fr/equipes/calligramme/acg/">ACG</a>,
|
||||||
<a href="http://openccg.sourceforge.net/">CCG</a>,
|
<a href="http://openccg.sourceforge.net/">CCG</a>,
|
||||||
but specialized for multilingual grammars,
|
but specialized for multilingual grammars,
|
||||||
<LI>a <B>logical framework</B>, like
|
</li>
|
||||||
|
<li>a <strong>logical framework</strong>, like
|
||||||
<a href="http://wiki.portal.chalmers.se/agda/pmwiki.php">Agda</a>,
|
<a href="http://wiki.portal.chalmers.se/agda/pmwiki.php">Agda</a>,
|
||||||
<a href="http://coq.inria.fr/">Coq</a>,
|
<a href="http://coq.inria.fr/">Coq</a>,
|
||||||
<a href="http://www.cl.cam.ac.uk/research/hvg/Isabelle/">Isabelle</a>,
|
<a href="http://www.cl.cam.ac.uk/research/hvg/Isabelle/">Isabelle</a>,
|
||||||
but equipped with concrete syntax in addition to logic
|
but equipped with concrete syntax in addition to logic
|
||||||
<li>a <b>platform for machine translation</b>, like
|
</li>
|
||||||
|
<li>a <strong>platform for machine translation</strong>, like
|
||||||
<a href="http://www.statmt.org/moses/">Moses</a>,
|
<a href="http://www.statmt.org/moses/">Moses</a>,
|
||||||
<a href="http://www.apertium.org/">Apertium</a>,
|
<a href="http://www.apertium.org/">Apertium</a>,
|
||||||
but based on deep structural analysis (and usually applied for
|
but based on deep structural analysis (and usually applied for
|
||||||
limited fragments of language).
|
limited fragments of language).
|
||||||
</UL>
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<P>
|
<p>
|
||||||
Don't worry if you don't know most of the references above - but if you do know at
|
Don't worry if you don't know most of the references above - but if you do know at
|
||||||
least one, it may help you to get a first idea of what GF is.
|
least one, it may help you to get a first idea of what GF is.
|
||||||
</P>
|
|
||||||
<H2>Applications</H2>
|
|
||||||
<P>
|
|
||||||
GF can be used for building
|
|
||||||
</P>
|
|
||||||
<UL>
|
|
||||||
<LI><A HREF="http://cloud.grammaticalframework.org/translator/">translation systems</A>
|
|
||||||
<LI><A HREF="http://cloud.grammaticalframework.org/minibar/minibar.html">multilingual web gadgets</A>
|
|
||||||
<LI><A HREF="http://www.cs.chalmers.se/~hallgren/Alfa/Tutorial/GFplugin.html">natural-language interfaces</A>
|
|
||||||
<LI><A HREF="http://www.youtube.com/watch?v=1bfaYHWS6zU">dialogue systems</A>
|
|
||||||
<LI><A HREF="lib/doc/synopsis.html">natural language resources</A>
|
|
||||||
</UL>
|
|
||||||
|
|
||||||
<H2>Availability</H2>
|
|
||||||
<P>
|
|
||||||
GF is <B>open-source</B>, licensed under <A HREF="LICENSE">GPL</A> (the program) and
|
|
||||||
<A HREF="./LICENSE">LGPL</A> and <A HREF="./LICENSE">BSD</A> (the libraries). It
|
|
||||||
is available for
|
|
||||||
</P>
|
|
||||||
<UL>
|
|
||||||
<LI>Linux
|
|
||||||
<LI>Mac OS X
|
|
||||||
<LI>Windows
|
|
||||||
<li>Android mobile platform (via Java; runtime)
|
|
||||||
<LI>via compilation to JavaScript, almost any platform that has a web browser (runtime)
|
|
||||||
</UL>
|
|
||||||
|
|
||||||
<H2>Projects</H2>
|
|
||||||
<P>
|
|
||||||
GF was first created in 1998 at
|
|
||||||
<A HREF="http://www.xrce.xerox.com/">Xerox Research Centre Europe</A>,
|
|
||||||
Grenoble, in the project
|
|
||||||
Multilingual Document Authoring. At Xerox, it was used for prototypes including
|
|
||||||
a restaurant phrase book,
|
|
||||||
a database query system,
|
|
||||||
a formalization of an alarm system instructions with translations to 5 languages, and
|
|
||||||
an authoring system for medical drug descriptions.
|
|
||||||
</P>
|
|
||||||
<P>
|
|
||||||
Later projects using GF and involving third parties include, in chronological order,
|
|
||||||
</P>
|
|
||||||
<UL>
|
|
||||||
<LI><A HREF="http://www.cs.chalmers.se/~hallgren/Alfa/Tutorial/GFplugin.html">GF-Alfa</A>:
|
|
||||||
natural language interface to formal proofs
|
|
||||||
<LI><A HREF="http://efficient.citi.tudor.lu/index_noframe.html">Efficient</A>:
|
|
||||||
authoring tool for business models.
|
|
||||||
<LI><A HREF="http://www.key-project.org/">GF-KeY</A>:
|
|
||||||
authoring and translation of software specifications
|
|
||||||
<LI><A HREF="http://www.talk-project.org">TALK</A>:
|
|
||||||
multilingual and multimodal spoken dialogue systems
|
|
||||||
<LI><A HREF="http://webalt.math.helsinki.fi/">WebALT</A>:
|
|
||||||
multilingual generation of mathematical exercises (commercial project)
|
|
||||||
<LI><A HREF="http://spraakbanken.gu.se/sal/">SALDO</A>:
|
|
||||||
Swedish morphological dictionary based on rules developed for GF and
|
|
||||||
<A HREF="http://www.cse.chalmers.se/alumni/markus/FM/">Functional Morphology</A>
|
|
||||||
<LI><a href="http://www.molto-project.eu">MOLTO</a>:
|
|
||||||
multilingual online translation
|
|
||||||
<LI><a href="http://remu.grammaticalframework.org">REMU</a>:
|
|
||||||
reliable multilingual digital communication.
|
|
||||||
</UL>
|
|
||||||
<p>
|
|
||||||
Here is a <a
|
|
||||||
href="http://videos.xrce.xerox.com/index.php/videos/index/618">talk
|
|
||||||
about GF at XRCE</a>,
|
|
||||||
14 years later.
|
|
||||||
|
|
||||||
<P>
|
|
||||||
Academically, GF has been used in at least ten PhD theses and resulted
|
|
||||||
in more than a hundred
|
|
||||||
scientific publications (see <A HREF="doc/gf-bibliography.html">GF publication list</A>).
|
|
||||||
</P>
|
|
||||||
<H2>Programming in GF</H2>
|
|
||||||
<P>
|
|
||||||
GF is easy to learn by following the <A HREF="doc/tutorial/gf-tutorial.html">tutorial</A>.
|
|
||||||
You can write your first translator in 15 minutes.
|
|
||||||
</P>
|
|
||||||
<P>
|
|
||||||
GF has an interactive command interpreter, as well as a batch compiler.
|
|
||||||
Grammars can be compiled to parser and translator code in many different
|
|
||||||
formats. These components can then be embedded in applications written
|
|
||||||
in other programming languages. The formats currently supported are:
|
|
||||||
</P>
|
|
||||||
<UL>
|
|
||||||
<LI>Haskell
|
|
||||||
<li>Java, in particular the Android platform
|
|
||||||
<LI>JavaScript
|
|
||||||
<LI>Speech recognition: HTK/ATK, Nuance, JSGF
|
|
||||||
</UL>
|
|
||||||
|
|
||||||
<P>
|
|
||||||
The GF programming language is high-level and advanced, featuring
|
|
||||||
</P>
|
|
||||||
<UL>
|
|
||||||
<LI>static type checking
|
|
||||||
<LI>higher-order functions
|
|
||||||
<LI>dependent types
|
|
||||||
<LI>pattern matching with data constructors and regular expressions
|
|
||||||
<LI>module system with multiple inheritance and parametrized modules
|
|
||||||
</UL>
|
|
||||||
|
|
||||||
<h3>Getting help</h3>
|
|
||||||
<p>
|
|
||||||
If you need some help with GF, the first places to start are the <a href="doc/tutorial/gf-tutorial.html">Tutorial</a> and <a href="doc/gf-refman.html">Reference</a> pages.
|
|
||||||
The printed <a href="gf-book">book</a> contains all the material in the tutorial and some extra bits, and is the recommended reference for GF.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<hr>
|
||||||
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="irc/">here</a>.
|
|
||||||
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>
|
|
||||||
|
|
||||||
<H2>Libraries</H2>
|
<div class="row">
|
||||||
<P>
|
|
||||||
Libraries are at the heart of modern software engineering. In natural language
|
|
||||||
applications, libraries are a way to cope with thousands of details involved in
|
|
||||||
syntax, lexicon, and inflection. The
|
|
||||||
<A HREF="lib/doc/synopsis.html">GF resource grammar library</A> has
|
|
||||||
support for an increasing number of languages, currently including
|
|
||||||
</P>
|
|
||||||
<ol class=languages>
|
|
||||||
<LI>Afrikaans
|
|
||||||
<LI>Amharic (partial)
|
|
||||||
<LI>Arabic (partial)
|
|
||||||
<LI>Bulgarian
|
|
||||||
<LI>Catalan
|
|
||||||
<LI>Chinese
|
|
||||||
<LI>Danish
|
|
||||||
<LI>Dutch
|
|
||||||
<LI>English
|
|
||||||
<LI>Estonian
|
|
||||||
<LI>Finnish
|
|
||||||
<LI>French
|
|
||||||
<LI>German
|
|
||||||
<li>Greek ancient (partial)
|
|
||||||
<li>Greek modern
|
|
||||||
<li>Hebrew (fragments)
|
|
||||||
<LI>Hindi
|
|
||||||
<LI><A HREF="http://www.interlingua.com/">Interlingua</A>
|
|
||||||
<LI>Japanese
|
|
||||||
<LI>Italian
|
|
||||||
<LI>Latin (fragments)
|
|
||||||
<LI>Latvian
|
|
||||||
<li>Maltese
|
|
||||||
<li>Mongolian
|
|
||||||
<LI>Nepali
|
|
||||||
<LI>Norwegian bokmål
|
|
||||||
<LI>Norwegian nynorsk
|
|
||||||
<LI>Persian
|
|
||||||
<LI>Polish
|
|
||||||
<li>Punjabi
|
|
||||||
<LI>Romanian
|
|
||||||
<LI>Russian
|
|
||||||
<LI>Sindhi
|
|
||||||
<LI>Slovene (partial)
|
|
||||||
<LI>Spanish
|
|
||||||
<li>Swahili (fragments)
|
|
||||||
<LI>Swedish
|
|
||||||
<LI>Thai
|
|
||||||
<LI>Turkish (fragments)
|
|
||||||
<LI>Urdu
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
<P>
|
<div class="col-md-6">
|
||||||
Adding a language to the resource library takes 3 to 9
|
<h2>Applications & Availability</h2>
|
||||||
months - contributions
|
<p>
|
||||||
are welcome! You can start with the <A HREF="doc/gf-lrec-2010.pdf">resource grammarian's tutorial</A>.
|
GF can be used for building
|
||||||
|
<a href="//cloud.grammaticalframework.org/translator/">translation systems</a>,
|
||||||
|
<a href="//cloud.grammaticalframework.org/minibar/minibar.html">multilingual web gadgets</a>,
|
||||||
|
<a href="http://www.cse.chalmers.se/~hallgren/Alfa/Tutorial/GFplugin.html">natural-language interfaces</a>,
|
||||||
|
<a href="http://www.youtube.com/watch?v=1bfaYHWS6zU">dialogue systems</a>, and
|
||||||
|
<a href="lib/doc/synopsis/index.html">natural language resources</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
GF is <strong>open-source</strong>, licensed under <a href="LICENSE">GPL</a> (the program) and
|
||||||
|
<a href="LICENSE">LGPL</a> and <a href="LICENSE">BSD</a> (the libraries). It
|
||||||
|
is available for
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Linux</li>
|
||||||
|
<li>macOS</li>
|
||||||
|
<li>Windows</li>
|
||||||
|
<li>Android mobile platform (via Java; runtime)</li>
|
||||||
|
<li>via compilation to JavaScript, almost any platform that has a web browser (runtime)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Programming in GF</h2>
|
||||||
|
<p>
|
||||||
|
GF is easy to learn by following the <a href="doc/tutorial/gf-tutorial.html">tutorial</a>.
|
||||||
|
You can write your first translator in 15 minutes.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
GF has an interactive command interpreter, as well as a batch compiler.
|
||||||
|
Grammars can be compiled to parser and translator code in many different
|
||||||
|
formats. These components can then be embedded in applications written
|
||||||
|
in other programming languages. The formats currently supported are:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Haskell</li>
|
||||||
|
<li>Java, in particular the Android platform</li>
|
||||||
|
<li>JavaScript</li>
|
||||||
|
<li>Speech recognition: HTK/ATK, Nuance, JSGF</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The GF programming language is high-level and advanced, featuring:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>static type checking</li>
|
||||||
|
<li>higher-order functions</li>
|
||||||
|
<li>dependent types</li>
|
||||||
|
<li>pattern matching with data constructors and regular expressions</li>
|
||||||
|
<li>module system with multiple inheritance and parametrized modules</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>Getting help</h3>
|
||||||
|
<p>
|
||||||
|
If you need some help with GF, the first places to start are the <a href="doc/tutorial/gf-tutorial.html">Tutorial</a> and <a href="doc/gf-refman.html">Reference</a> pages.
|
||||||
|
The printed <a href="gf-book">book</a> contains all the material in the tutorial and some extra bits, and is the recommended reference for GF.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<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.
|
||||||
|
You can <a href="https://webchat.freenode.net/?channels=gf">open a web chat</a>
|
||||||
|
or <a href="/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>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h2>News</h2>
|
||||||
|
|
||||||
|
<dl class="row">
|
||||||
|
<dt class="col-sm-3 text-center text-nowrap">2018-12-03</dt>
|
||||||
|
<dd class="col-sm-9">
|
||||||
|
<a href="//school.grammaticalframework.org/2018/">Sixth GF Summer School</a> in Stellenbosch (South Africa), 3–14 December 2018
|
||||||
|
</dd>
|
||||||
|
<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>
|
||||||
|
</dd>
|
||||||
|
<dt class="col-sm-3 text-center text-nowrap">2018-07-25</dt>
|
||||||
|
<dd class="col-sm-9">
|
||||||
|
The GF repository has been split in two:
|
||||||
|
<a href="https://github.com/GrammaticalFramework/gf-core">gf-core</a> and
|
||||||
|
<a href="https://github.com/GrammaticalFramework/gf-rgl">gf-rgl</a>.
|
||||||
|
The original <a href="https://github.com/GrammaticalFramework/GF">GF</a> repository is now archived.
|
||||||
|
</dd>
|
||||||
|
<dt class="col-sm-3 text-center text-nowrap">2017-08-11</dt>
|
||||||
|
<dd class="col-sm-9">
|
||||||
|
<strong>GF 3.9 released.</strong>
|
||||||
|
<a href="download/release-3.9.html">Release notes</a>
|
||||||
|
</dd>
|
||||||
|
<dt class="col-sm-3 text-center text-nowrap">2017-06-29</dt>
|
||||||
|
<dd class="col-sm-9">
|
||||||
|
GF is moving to <a href="https://github.com/GrammaticalFramework/GF/">GitHub</a>.</dd>
|
||||||
|
<dt class="col-sm-3 text-center text-nowrap">2017-03-13</dt>
|
||||||
|
<dd class="col-sm-9">
|
||||||
|
<a href="//school.grammaticalframework.org/2017/">GF Summer School</a> in Riga (Latvia), 14-25 August 2017
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<h2>Projects</h2>
|
||||||
|
<p>
|
||||||
|
GF was first created in 1998 at
|
||||||
|
<a href="http://www.xrce.xerox.com/">Xerox Research Centre Europe</a>,
|
||||||
|
Grenoble, in the project
|
||||||
|
Multilingual Document Authoring. At Xerox, it was used for prototypes including
|
||||||
|
a restaurant phrase book,
|
||||||
|
a database query system,
|
||||||
|
a formalization of an alarm system instructions with translations to 5 languages, and
|
||||||
|
an authoring system for medical drug descriptions.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Later projects using GF and involving third parties include, in chronological order:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="http://www.cse.chalmers.se/~hallgren/Alfa/Tutorial/GFplugin.html">GF-Alfa</a>:
|
||||||
|
natural language interface to formal proofs
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="http://efficient.citi.tudor.lu/index_noframe.html">Efficient</a>:
|
||||||
|
authoring tool for business models.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="http://www.key-project.org/">GF-KeY</a>:
|
||||||
|
authoring and translation of software specifications
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="http://www.talk-project.org">TALK</a>:
|
||||||
|
multilingual and multimodal spoken dialogue systems
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="http://webalt.math.helsinki.fi/">WebALT</a>:
|
||||||
|
multilingual generation of mathematical exercises (commercial project)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="http://spraakbanken.gu.se/sal/">SALDO</a>:
|
||||||
|
Swedish morphological dictionary based on rules developed for GF and
|
||||||
|
<a href="http://www.cse.chalmers.se/alumni/markus/FM/">Functional Morphology</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="//www.molto-project.eu">MOLTO</a>:
|
||||||
|
multilingual online translation
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="//remu.grammaticalframework.org">REMU</a>:
|
||||||
|
reliable multilingual digital communication
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<!-- <p>
|
||||||
|
Here is a <a
|
||||||
|
href="http://videos.xrce.xerox.com/index.php/videos/index/618">talk
|
||||||
|
about GF at XRCE</a>,
|
||||||
|
14 years later.
|
||||||
|
</p> -->
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Academically, GF has been used in at least ten PhD theses and resulted
|
||||||
|
in more than a hundred scientific publications.
|
||||||
|
<!-- (see <a href="doc/gf-bibliography.html">GF publication list</a>). -->
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Libraries</h2>
|
||||||
|
<p>
|
||||||
|
Libraries are at the heart of modern software engineering. In natural language
|
||||||
|
applications, libraries are a way to cope with thousands of details involved in
|
||||||
|
syntax, lexicon, and inflection. The
|
||||||
|
<a href="lib/doc/synopsis/index.html">GF resource grammar library</a> has
|
||||||
|
support for an increasing number of languages, currently including
|
||||||
|
Afrikaans,
|
||||||
|
Amharic (partial),
|
||||||
|
Arabic (partial),
|
||||||
|
Bulgarian,
|
||||||
|
Catalan,
|
||||||
|
Chinese,
|
||||||
|
Danish,
|
||||||
|
Dutch,
|
||||||
|
English,
|
||||||
|
Estonian,
|
||||||
|
Finnish,
|
||||||
|
French,
|
||||||
|
German,
|
||||||
|
Greek ancient (partial),
|
||||||
|
Greek modern,
|
||||||
|
Hebrew (fragments),
|
||||||
|
Hindi,
|
||||||
|
Interlingua,
|
||||||
|
Japanese,
|
||||||
|
Italian,
|
||||||
|
Latin (fragments),
|
||||||
|
Latvian,
|
||||||
|
Maltese,
|
||||||
|
Mongolian,
|
||||||
|
Nepali,
|
||||||
|
Norwegian bokmål,
|
||||||
|
Norwegian nynorsk,
|
||||||
|
Persian,
|
||||||
|
Polish,
|
||||||
|
Punjabi,
|
||||||
|
Romanian,
|
||||||
|
Russian,
|
||||||
|
Sindhi,
|
||||||
|
Slovene (partial),
|
||||||
|
Spanish,
|
||||||
|
Swahili (fragments),
|
||||||
|
Swedish,
|
||||||
|
Thai,
|
||||||
|
Turkish (fragments),
|
||||||
|
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="lib/doc/rgl-tutorial/index.html">resource grammarian's tutorial</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div><!-- .col-6 -->
|
||||||
|
|
||||||
|
</div><!-- .row -->
|
||||||
|
|
||||||
|
</div><!-- .container -->
|
||||||
|
|
||||||
|
<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">
|
<script type="text/javascript">
|
||||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||||
@@ -423,5 +395,6 @@ try {
|
|||||||
var pageTracker = _gat._getTracker("UA-7811807-3");
|
var pageTracker = _gat._getTracker("UA-7811807-3");
|
||||||
pageTracker._trackPageview();
|
pageTracker._trackPageview();
|
||||||
} catch(err) {}</script>
|
} catch(err) {}</script>
|
||||||
</BODY>
|
|
||||||
</HTML>
|
</body>
|
||||||
|
</html>
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ module GF(
|
|||||||
module GF.Grammar.Printer,
|
module GF.Grammar.Printer,
|
||||||
module GF.Infra.Ident,
|
module GF.Infra.Ident,
|
||||||
-- ** Binary serialisation
|
-- ** Binary serialisation
|
||||||
module GF.Grammar.Binary
|
module GF.Grammar.Binary,
|
||||||
|
-- * Canonical GF
|
||||||
|
module GF.Compile.GrammarToCanonical
|
||||||
) where
|
) where
|
||||||
import GF.Main
|
import GF.Main
|
||||||
import GF.Compiler
|
import GF.Compiler
|
||||||
@@ -36,3 +38,5 @@ import GF.Grammar.Macros
|
|||||||
import GF.Grammar.Printer
|
import GF.Grammar.Printer
|
||||||
import GF.Infra.Ident
|
import GF.Infra.Ident
|
||||||
import GF.Grammar.Binary
|
import GF.Grammar.Binary
|
||||||
|
|
||||||
|
import GF.Compile.GrammarToCanonical
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module GF.Command.Abstract(module GF.Command.Abstract,Expr,showExpr,Term) where
|
module GF.Command.Abstract(module GF.Command.Abstract,Expr,showExpr,Term) where
|
||||||
|
|
||||||
import PGF(CId,mkCId,Expr,showExpr)
|
import PGF2(Expr,showExpr)
|
||||||
import GF.Grammar.Grammar(Term)
|
import GF.Grammar.Grammar(Term)
|
||||||
|
|
||||||
type Ident = String
|
type Ident = String
|
||||||
@@ -11,7 +11,7 @@ type Pipe = [Command]
|
|||||||
|
|
||||||
data Command
|
data Command
|
||||||
= Command Ident [Option] Argument
|
= Command Ident [Option] Argument
|
||||||
deriving (Eq,Ord,Show)
|
deriving Show
|
||||||
|
|
||||||
data Option
|
data Option
|
||||||
= OOpt Ident
|
= OOpt Ident
|
||||||
@@ -29,13 +29,7 @@ data Argument
|
|||||||
| ATerm Term
|
| ATerm Term
|
||||||
| ANoArg
|
| ANoArg
|
||||||
| AMacro Ident
|
| AMacro Ident
|
||||||
deriving (Eq,Ord,Show)
|
deriving Show
|
||||||
|
|
||||||
valCIdOpts :: String -> CId -> [Option] -> CId
|
|
||||||
valCIdOpts flag def opts =
|
|
||||||
case [v | OFlag f (VId v) <- opts, f == flag] of
|
|
||||||
(v:_) -> mkCId v
|
|
||||||
_ -> def
|
|
||||||
|
|
||||||
valIntOpts :: String -> Int -> [Option] -> Int
|
valIntOpts :: String -> Int -> [Option] -> Int
|
||||||
valIntOpts flag def opts =
|
valIntOpts flag def opts =
|
||||||
@@ -49,6 +43,18 @@ valStrOpts flag def opts =
|
|||||||
v:_ -> valueString v
|
v:_ -> valueString v
|
||||||
_ -> def
|
_ -> def
|
||||||
|
|
||||||
|
maybeIntOpts :: String -> a -> (Int -> a) -> [Option] -> a
|
||||||
|
maybeIntOpts flag def fn opts =
|
||||||
|
case [v | OFlag f (VInt v) <- opts, f == flag] of
|
||||||
|
(v:_) -> fn v
|
||||||
|
_ -> def
|
||||||
|
|
||||||
|
maybeStrOpts :: String -> a -> (String -> a) -> [Option] -> a
|
||||||
|
maybeStrOpts flag def fn opts =
|
||||||
|
case listFlags flag opts of
|
||||||
|
v:_ -> fn (valueString v)
|
||||||
|
_ -> def
|
||||||
|
|
||||||
listFlags flag opts = [v | OFlag f v <- opts, f == flag]
|
listFlags flag opts = [v | OFlag f v <- opts, f == flag]
|
||||||
|
|
||||||
valueString v =
|
valueString v =
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ import GF.Command.Abstract(Option,Expr,Term)
|
|||||||
import GF.Text.Pretty(render)
|
import GF.Text.Pretty(render)
|
||||||
import GF.Grammar.Printer() -- instance Pretty Term
|
import GF.Grammar.Printer() -- instance Pretty Term
|
||||||
import GF.Grammar.Macros(string2term)
|
import GF.Grammar.Macros(string2term)
|
||||||
import qualified PGF as H(showExpr)
|
import PGF2(mkStr,unStr,showExpr)
|
||||||
import qualified PGF.Internal as H(Literal(LStr),Expr(ELit)) ----
|
|
||||||
|
|
||||||
data CommandInfo m = CommandInfo {
|
data CommandInfo m = CommandInfo {
|
||||||
exec :: [Option] -> CommandArguments -> m CommandOutput,
|
exec :: [Option] -> CommandArguments -> m CommandOutput,
|
||||||
@@ -38,21 +37,19 @@ class Monad m => TypeCheckArg m where typeCheckArg :: Expr -> m Expr
|
|||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
data CommandArguments = Exprs [Expr] | Strings [String] | Term Term
|
data CommandArguments = Exprs [(Expr,Float)] | Strings [String] | Term Term
|
||||||
|
|
||||||
newtype CommandOutput = Piped (CommandArguments,String) ---- errors, etc
|
newtype CommandOutput = Piped (CommandArguments,String) ---- errors, etc
|
||||||
|
|
||||||
-- ** Converting command output
|
-- ** Converting command output
|
||||||
fromStrings ss = Piped (Strings ss, unlines ss)
|
fromStrings ss = Piped (Strings ss, unlines ss)
|
||||||
fromExprs es = Piped (Exprs es,unlines (map (H.showExpr []) es))
|
fromExprs show_p es = Piped (Exprs es,unlines (map (\(e,p) -> (if show_p then (++) ("["++show p++"] ") else id) (showExpr [] e)) es))
|
||||||
fromString s = Piped (Strings [s], s)
|
fromString s = Piped (Strings [s], s)
|
||||||
pipeWithMessage es msg = Piped (Exprs es,msg)
|
pipeWithMessage es msg = Piped (Exprs es,msg)
|
||||||
pipeMessage msg = Piped (Exprs [],msg)
|
pipeMessage msg = Piped (Exprs [],msg)
|
||||||
pipeExprs es = Piped (Exprs es,[]) -- only used in emptyCommandInfo
|
pipeExprs es = Piped (Exprs es,[]) -- only used in emptyCommandInfo
|
||||||
void = Piped (Exprs [],"")
|
void = Piped (Exprs [],"")
|
||||||
|
|
||||||
stringAsExpr = H.ELit . H.LStr -- should be a pattern macro
|
|
||||||
|
|
||||||
-- ** Converting command input
|
-- ** Converting command input
|
||||||
|
|
||||||
toStrings args =
|
toStrings args =
|
||||||
@@ -61,23 +58,23 @@ toStrings args =
|
|||||||
Exprs es -> zipWith showAsString (True:repeat False) es
|
Exprs es -> zipWith showAsString (True:repeat False) es
|
||||||
Term t -> [render t]
|
Term t -> [render t]
|
||||||
where
|
where
|
||||||
showAsString first t =
|
showAsString first (e,p) =
|
||||||
case t of
|
case unStr e of
|
||||||
H.ELit (H.LStr s) -> s
|
Just s -> s
|
||||||
_ -> ['\n'|not first] ++
|
Nothing -> ['\n'|not first] ++
|
||||||
H.showExpr [] t ---newline needed in other cases than the first
|
showExpr [] e ---newline needed in other cases than the first
|
||||||
|
|
||||||
toExprs args =
|
toExprs args =
|
||||||
case args of
|
case args of
|
||||||
Exprs es -> es
|
Exprs es -> map fst es
|
||||||
Strings ss -> map stringAsExpr ss
|
Strings ss -> map mkStr ss
|
||||||
Term t -> [stringAsExpr (render t)]
|
Term t -> [mkStr (render t)]
|
||||||
|
|
||||||
toTerm args =
|
toTerm args =
|
||||||
case args of
|
case args of
|
||||||
Term t -> t
|
Term t -> t
|
||||||
Strings ss -> string2term $ unwords ss -- hmm
|
Strings ss -> string2term $ unwords ss -- hmm
|
||||||
Exprs es -> string2term $ unwords $ map (H.showExpr []) es -- hmm
|
Exprs es -> string2term $ unwords $ map (showExpr [] . fst) es -- hmm
|
||||||
|
|
||||||
-- ** Creating documentation
|
-- ** Creating documentation
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
|
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
|
||||||
module GF.Command.Commands (
|
module GF.Command.Commands (
|
||||||
PGFEnv,HasPGFEnv(..),pgf,mos,pgfEnv,pgfCommands,
|
HasPGF(..),pgfCommands,
|
||||||
options,flags,
|
options,flags,
|
||||||
) where
|
) where
|
||||||
import Prelude hiding (putStrLn,(<>)) -- GHC 8.4.1 clash with Text.PrettyPrint
|
import Prelude hiding (putStrLn)
|
||||||
|
|
||||||
import PGF
|
import PGF2
|
||||||
|
import PGF2.Internal(writePGF)
|
||||||
import PGF.Internal(lookStartCat,functionsToCat,lookValCat,restrictPGF,hasLin)
|
|
||||||
import PGF.Internal(abstract,funs,cats,Expr(EFun)) ----
|
|
||||||
import PGF.Internal(ppFun,ppCat)
|
|
||||||
import PGF.Internal(optimizePGF)
|
|
||||||
|
|
||||||
import GF.Compile.Export
|
import GF.Compile.Export
|
||||||
import GF.Compile.ToAPI
|
import GF.Compile.ToAPI
|
||||||
@@ -28,27 +24,25 @@ import GF.Command.TreeOperations ---- temporary place for typecheck and compute
|
|||||||
|
|
||||||
import GF.Data.Operations
|
import GF.Data.Operations
|
||||||
|
|
||||||
import PGF.Internal (encodeFile)
|
import Data.Char
|
||||||
import Data.List(intersperse,nub)
|
import Data.List(intersperse,nub)
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import GF.Text.Pretty
|
import GF.Text.Pretty
|
||||||
import Data.List (sort)
|
import Data.List (sort)
|
||||||
--import Debug.Trace
|
import Control.Monad(mplus)
|
||||||
|
|
||||||
|
class (Functor m,Monad m,MonadSIO m) => HasPGF m where getPGF :: m (Maybe PGF)
|
||||||
|
|
||||||
data PGFEnv = Env {pgf::PGF,mos::Map.Map Language Morpho}
|
instance (Monad m,HasPGF m) => TypeCheckArg m where
|
||||||
|
typeCheckArg e = do mb_pgf <- getPGF
|
||||||
|
case mb_pgf of
|
||||||
|
Just pgf -> either fail
|
||||||
|
(return . fst)
|
||||||
|
(inferExpr pgf e)
|
||||||
|
Nothing -> fail "Import a grammar before using this command"
|
||||||
|
|
||||||
pgfEnv pgf = Env pgf mos
|
pgfCommands :: HasPGF m => Map.Map String (CommandInfo m)
|
||||||
where mos = Map.fromList [(la,buildMorpho pgf la) | la <- languages pgf]
|
|
||||||
|
|
||||||
class (Functor m,Monad m,MonadSIO m) => HasPGFEnv m where getPGFEnv :: m PGFEnv
|
|
||||||
|
|
||||||
instance (Monad m,HasPGFEnv m) => TypeCheckArg m where
|
|
||||||
typeCheckArg e = (either (fail . render . ppTcError) (return . fst)
|
|
||||||
. flip inferExpr e . pgf) =<< getPGFEnv
|
|
||||||
|
|
||||||
pgfCommands :: HasPGFEnv m => Map.Map String (CommandInfo m)
|
|
||||||
pgfCommands = Map.fromList [
|
pgfCommands = Map.fromList [
|
||||||
("aw", emptyCommandInfo {
|
("aw", emptyCommandInfo {
|
||||||
longname = "align_words",
|
longname = "align_words",
|
||||||
@@ -61,7 +55,7 @@ pgfCommands = Map.fromList [
|
|||||||
"by the view flag. The target format is png, unless overridden by the",
|
"by the view flag. The target format is png, unless overridden by the",
|
||||||
"flag -format. Results from multiple trees are combined to pdf with convert (ImageMagick)."
|
"flag -format. Results from multiple trees are combined to pdf with convert (ImageMagick)."
|
||||||
],
|
],
|
||||||
exec = getEnv $ \ opts arg (Env pgf mos) -> do
|
exec = needPGF $ \ opts arg pgf -> do
|
||||||
let es = toExprs arg
|
let es = toExprs arg
|
||||||
let langs = optLangs pgf opts
|
let langs = optLangs pgf opts
|
||||||
if isOpt "giza" opts
|
if isOpt "giza" opts
|
||||||
@@ -73,7 +67,7 @@ pgfCommands = Map.fromList [
|
|||||||
let grph = if null es then [] else lsrc ++ "\n--end_source--\n\n"++ltrg++"\n-end_target--\n\n"++align
|
let grph = if null es then [] else lsrc ++ "\n--end_source--\n\n"++ltrg++"\n-end_target--\n\n"++align
|
||||||
return $ fromString grph
|
return $ fromString grph
|
||||||
else do
|
else do
|
||||||
let grphs = map (graphvizAlignment pgf langs) es
|
let grphs = map (graphvizWordAlignment langs graphvizDefaults) es
|
||||||
if isFlag "view" opts || isFlag "format" opts
|
if isFlag "view" opts || isFlag "format" opts
|
||||||
then do
|
then do
|
||||||
let view = optViewGraph opts
|
let view = optViewGraph opts
|
||||||
@@ -95,6 +89,7 @@ pgfCommands = Map.fromList [
|
|||||||
("view", "program to open the resulting file")
|
("view", "program to open the resulting file")
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
|
|
||||||
("ca", emptyCommandInfo {
|
("ca", emptyCommandInfo {
|
||||||
longname = "clitic_analyse",
|
longname = "clitic_analyse",
|
||||||
synopsis = "print the analyses of all words into stems and clitics",
|
synopsis = "print the analyses of all words into stems and clitics",
|
||||||
@@ -105,16 +100,17 @@ pgfCommands = Map.fromList [
|
|||||||
"by the flag '-clitics'. The list of stems is given as the list of words",
|
"by the flag '-clitics'. The list of stems is given as the list of words",
|
||||||
"of the language given by the '-lang' flag."
|
"of the language given by the '-lang' flag."
|
||||||
],
|
],
|
||||||
exec = getEnv $ \opts ts env -> case opts of
|
exec = needPGF $ \opts ts pgf -> do
|
||||||
_ | isOpt "raw" opts ->
|
concr <- optLang pgf opts
|
||||||
return . fromString .
|
case opts of
|
||||||
unlines . map (unwords . map (concat . intersperse "+")) .
|
_ | isOpt "raw" opts ->
|
||||||
map (getClitics (isInMorpho (optMorpho env opts)) (optClitics opts)) .
|
return . fromString .
|
||||||
concatMap words $ toStrings ts
|
unlines . map (unwords . map (concat . intersperse "+")) .
|
||||||
_ ->
|
map (getClitics (not . null . lookupMorpho concr) (optClitics opts)) .
|
||||||
return . fromStrings .
|
concatMap words $ toStrings ts
|
||||||
getCliticsText (isInMorpho (optMorpho env opts)) (optClitics opts) .
|
_ -> return . fromStrings .
|
||||||
concatMap words $ toStrings ts,
|
getCliticsText (not . null . lookupMorpho concr) (optClitics opts) .
|
||||||
|
concatMap words $ toStrings ts,
|
||||||
flags = [
|
flags = [
|
||||||
("clitics","the list of possible clitics (comma-separated, no spaces)"),
|
("clitics","the list of possible clitics (comma-separated, no spaces)"),
|
||||||
("lang", "the language of analysis")
|
("lang", "the language of analysis")
|
||||||
@@ -146,19 +142,19 @@ pgfCommands = Map.fromList [
|
|||||||
],
|
],
|
||||||
flags = [
|
flags = [
|
||||||
("file","the file to be converted (suffix .gfe must be given)"),
|
("file","the file to be converted (suffix .gfe must be given)"),
|
||||||
("lang","the language in which to parse"),
|
("lang","the language in which to parse")
|
||||||
("probs","file with probabilities to rank the parses")
|
|
||||||
],
|
],
|
||||||
exec = getEnv $ \ opts _ env@(Env pgf mos) -> do
|
exec = needPGF $ \opts _ pgf -> do
|
||||||
let file = optFile opts
|
let file = optFile opts
|
||||||
pgf <- optProbs opts pgf
|
|
||||||
let printer = if (isOpt "api" opts) then exprToAPI else (showExpr [])
|
let printer = if (isOpt "api" opts) then exprToAPI else (showExpr [])
|
||||||
let conf = configureExBased pgf (optMorpho env opts) (optLang pgf opts) printer
|
concr <- optLang pgf opts
|
||||||
|
let conf = configureExBased pgf concr printer
|
||||||
(file',ws) <- restricted $ parseExamplesInGrammar conf file
|
(file',ws) <- restricted $ parseExamplesInGrammar conf file
|
||||||
if null ws then return () else putStrLn ("unknown words: " ++ unwords ws)
|
if null ws then return () else putStrLn ("unknown words: " ++ unwords ws)
|
||||||
return (fromString ("wrote " ++ file')),
|
return (fromString ("wrote " ++ file')),
|
||||||
needsTypeCheck = False
|
needsTypeCheck = False
|
||||||
}),
|
}),
|
||||||
|
|
||||||
("gr", emptyCommandInfo {
|
("gr", emptyCommandInfo {
|
||||||
longname = "generate_random",
|
longname = "generate_random",
|
||||||
synopsis = "generate random trees in the current abstract syntax",
|
synopsis = "generate random trees in the current abstract syntax",
|
||||||
@@ -173,54 +169,53 @@ pgfCommands = Map.fromList [
|
|||||||
explanation = unlines [
|
explanation = unlines [
|
||||||
"Generates a list of random trees, by default one tree.",
|
"Generates a list of random trees, by default one tree.",
|
||||||
"If a tree argument is given, the command completes the Tree with values to",
|
"If a tree argument is given, the command completes the Tree with values to",
|
||||||
"all metavariables in the tree. The generation can be biased by probabilities,",
|
"all metavariables in the tree. The generation can be biased by probabilities",
|
||||||
"given in a file in the -probs flag."
|
"if the grammar was compiled with option -probs"
|
||||||
|
],
|
||||||
|
options = [
|
||||||
|
("show_probs", "show the probability of each result")
|
||||||
],
|
],
|
||||||
flags = [
|
flags = [
|
||||||
("cat","generation category"),
|
("cat","generation category"),
|
||||||
("lang","uses only functions that have linearizations in all these languages"),
|
("lang","uses only functions that have linearizations in all these languages"),
|
||||||
("number","number of trees generated"),
|
("number","number of trees generated")
|
||||||
("depth","the maximum generation depth"),
|
|
||||||
("probs", "file with biased probabilities (format 'f 0.4' one by line)")
|
|
||||||
],
|
],
|
||||||
exec = getEnv $ \ opts arg (Env pgf mos) -> do
|
exec = needPGF $ \opts arg pgf -> do
|
||||||
pgf <- optProbs opts (optRestricted opts pgf)
|
|
||||||
gen <- newStdGen
|
gen <- newStdGen
|
||||||
let dp = valIntOpts "depth" 4 opts
|
|
||||||
let ts = case mexp (toExprs arg) of
|
let ts = case mexp (toExprs arg) of
|
||||||
Just ex -> generateRandomFromDepth gen pgf ex (Just dp)
|
Just ex -> generateRandomFrom gen pgf ex
|
||||||
Nothing -> generateRandomDepth gen pgf (optType pgf opts) (Just dp)
|
Nothing -> generateRandom gen pgf (optType pgf opts)
|
||||||
returnFromExprs $ take (optNum opts) ts
|
returnFromExprs (isOpt "show_probs" opts) $ take (optNum opts) ts
|
||||||
}),
|
}),
|
||||||
|
|
||||||
("gt", emptyCommandInfo {
|
("gt", emptyCommandInfo {
|
||||||
longname = "generate_trees",
|
longname = "generate_trees",
|
||||||
synopsis = "generates a list of trees, by default exhaustive",
|
synopsis = "generates a list of trees, by default exhaustive",
|
||||||
explanation = unlines [
|
explanation = unlines [
|
||||||
"Generates all trees of a given category. By default, ",
|
"Generates all trees of a given category.",
|
||||||
"the depth is limited to 4, but this can be changed by a flag.",
|
|
||||||
"If a Tree argument is given, the command completes the Tree with values",
|
"If a Tree argument is given, the command completes the Tree with values",
|
||||||
"to all metavariables in the tree."
|
"to all metavariables in the tree."
|
||||||
],
|
],
|
||||||
|
options = [
|
||||||
|
("show_probs", "show the probability of each result")
|
||||||
|
],
|
||||||
flags = [
|
flags = [
|
||||||
("cat","the generation category"),
|
("cat","the generation category"),
|
||||||
("depth","the maximum generation depth"),
|
|
||||||
("lang","excludes functions that have no linearization in this language"),
|
("lang","excludes functions that have no linearization in this language"),
|
||||||
("number","the number of trees generated")
|
("number","the number of trees generated")
|
||||||
],
|
],
|
||||||
examples = [
|
examples = [
|
||||||
mkEx "gt -- all trees in the startcat, to depth 4",
|
mkEx "gt -- all trees in the startcat",
|
||||||
mkEx "gt -cat=NP -number=16 -- 16 trees in the category NP",
|
mkEx "gt -cat=NP -number=16 -- 16 trees in the category NP",
|
||||||
mkEx "gt -cat=NP -depth=2 -- trees in the category NP to depth 2",
|
|
||||||
mkEx "gt (AdjCN ? (UseN ?)) -- trees of form (AdjCN ? (UseN ?))"
|
mkEx "gt (AdjCN ? (UseN ?)) -- trees of form (AdjCN ? (UseN ?))"
|
||||||
],
|
],
|
||||||
exec = getEnv $ \ opts arg (Env pgf mos) -> do
|
exec = needPGF $ \opts arg pgf -> do
|
||||||
let pgfr = optRestricted opts pgf
|
let es = case mexp (toExprs arg) of
|
||||||
let dp = valIntOpts "depth" 4 opts
|
Just ex -> generateAllFrom pgf ex
|
||||||
let ts = case mexp (toExprs arg) of
|
Nothing -> generateAll pgf (optType pgf opts)
|
||||||
Just ex -> generateFromDepth pgfr ex (Just dp)
|
returnFromExprs (isOpt "show_probs" opts) $ takeOptNum opts es
|
||||||
Nothing -> generateAllDepth pgfr (optType pgf opts) (Just dp)
|
|
||||||
returnFromExprs $ take (optNumInf opts) ts
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
("i", emptyCommandInfo {
|
("i", emptyCommandInfo {
|
||||||
longname = "import",
|
longname = "import",
|
||||||
synopsis = "import a grammar from source code or compiled .pgf file",
|
synopsis = "import a grammar from source code or compiled .pgf file",
|
||||||
@@ -241,33 +236,28 @@ pgfCommands = Map.fromList [
|
|||||||
("probs","file with biased probabilities for generation")
|
("probs","file with biased probabilities for generation")
|
||||||
],
|
],
|
||||||
options = [
|
options = [
|
||||||
-- ["gfo", "src", "no-cpu", "cpu", "quiet", "verbose"]
|
|
||||||
("retain","retain operations (used for cc command)"),
|
("retain","retain operations (used for cc command)"),
|
||||||
("src", "force compilation from source"),
|
("src", "force compilation from source"),
|
||||||
("v", "be verbose - show intermediate status information")
|
("v", "be verbose - show intermediate status information")
|
||||||
],
|
],
|
||||||
needsTypeCheck = False
|
needsTypeCheck = False
|
||||||
}),
|
}),
|
||||||
|
|
||||||
("l", emptyCommandInfo {
|
("l", emptyCommandInfo {
|
||||||
longname = "linearize",
|
longname = "linearize",
|
||||||
synopsis = "convert an abstract syntax expression to string",
|
synopsis = "convert an abstract syntax expression to string",
|
||||||
explanation = unlines [
|
explanation = unlines [
|
||||||
"Shows the linearization of a Tree by the grammars in scope.",
|
"Shows the linearization of a tree by the grammars in scope.",
|
||||||
"The -lang flag can be used to restrict this to fewer languages.",
|
"The -lang flag can be used to restrict this to fewer languages.",
|
||||||
"A sequence of string operations (see command ps) can be given",
|
"A sequence of string operations (see command ps) can be given",
|
||||||
"as options, and works then like a pipe to the ps command, except",
|
"as options, and works then like a pipe to the ps command, except",
|
||||||
"that it only affect the strings, not e.g. the table labels.",
|
"that it only affect the strings, not e.g. the table labels."
|
||||||
"These can be given separately to each language with the unlexer flag",
|
|
||||||
"whose results are prepended to the other lexer flags. The value of the",
|
|
||||||
"unlexer flag is a space-separated list of comma-separated string operation",
|
|
||||||
"sequences; see example."
|
|
||||||
],
|
],
|
||||||
examples = [
|
examples = [
|
||||||
mkEx "l -lang=LangSwe,LangNor no_Utt -- linearize tree to LangSwe and LangNor",
|
mkEx "l -lang=LangSwe,LangNor no_Utt -- linearize tree to LangSwe and LangNor",
|
||||||
mkEx "gr -lang=LangHin -cat=Cl | l -table -to_devanagari -- hindi table",
|
mkEx "gr -lang=LangHin -cat=Cl | l -table -to_devanagari -- hindi table"
|
||||||
mkEx "l -unlexer=\"LangAra=to_arabic LangHin=to_devanagari\" -- different unlexers"
|
|
||||||
],
|
],
|
||||||
exec = getEnv $ \ opts ts (Env pgf mos) -> return . fromStrings . optLins pgf opts $ toExprs ts,
|
exec = needPGF $ \ opts ts pgf -> return . fromStrings . optLins pgf opts $ toExprs ts,
|
||||||
options = [
|
options = [
|
||||||
("all", "show all forms and variants, one by line (cf. l -list)"),
|
("all", "show all forms and variants, one by line (cf. l -list)"),
|
||||||
("bracket","show tree structure with brackets and paths to nodes"),
|
("bracket","show tree structure with brackets and paths to nodes"),
|
||||||
@@ -275,33 +265,13 @@ pgfCommands = Map.fromList [
|
|||||||
("list","show all forms and variants, comma-separated on one line (cf. l -all)"),
|
("list","show all forms and variants, comma-separated on one line (cf. l -all)"),
|
||||||
("multi","linearize to all languages (default)"),
|
("multi","linearize to all languages (default)"),
|
||||||
("table","show all forms labelled by parameters"),
|
("table","show all forms labelled by parameters"),
|
||||||
("tabtreebank","show the tree and its linearizations on a tab-separated line"),
|
|
||||||
("treebank","show the tree and tag linearizations with language names")
|
|
||||||
] ++ stringOpOptions,
|
|
||||||
flags = [
|
|
||||||
("lang","the languages of linearization (comma-separated, no spaces)"),
|
|
||||||
("unlexer","set unlexers separately to each language (space-separated)")
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
("lc", emptyCommandInfo {
|
|
||||||
longname = "linearize_chunks",
|
|
||||||
synopsis = "linearize a tree that has metavariables in maximal chunks without them",
|
|
||||||
explanation = unlines [
|
|
||||||
"A hopefully temporary command, intended to work around the type checker that fails",
|
|
||||||
"trees where a function node is a metavariable."
|
|
||||||
],
|
|
||||||
examples = [
|
|
||||||
mkEx "l -lang=LangSwe,LangNor -chunks ? a b (? c d)"
|
|
||||||
],
|
|
||||||
exec = getEnv $ \ opts ts (Env pgf mos) -> return . fromStrings $ optLins pgf (opts ++ [OOpt "chunks"]) (toExprs ts),
|
|
||||||
options = [
|
|
||||||
("treebank","show the tree and tag linearizations with language names")
|
("treebank","show the tree and tag linearizations with language names")
|
||||||
] ++ stringOpOptions,
|
] ++ stringOpOptions,
|
||||||
flags = [
|
flags = [
|
||||||
("lang","the languages of linearization (comma-separated, no spaces)")
|
("lang","the languages of linearization (comma-separated, no spaces)")
|
||||||
],
|
]
|
||||||
needsTypeCheck = False
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
("ma", emptyCommandInfo {
|
("ma", emptyCommandInfo {
|
||||||
longname = "morpho_analyse",
|
longname = "morpho_analyse",
|
||||||
synopsis = "print the morphological analyses of all words in the string",
|
synopsis = "print the morphological analyses of all words in the string",
|
||||||
@@ -309,18 +279,20 @@ pgfCommands = Map.fromList [
|
|||||||
"Prints all the analyses of space-separated words in the input string,",
|
"Prints all the analyses of space-separated words in the input string,",
|
||||||
"using the morphological analyser of the actual grammar (see command pg)"
|
"using the morphological analyser of the actual grammar (see command pg)"
|
||||||
],
|
],
|
||||||
exec = getEnv $ \opts ts env -> case opts of
|
exec = needPGF $ \opts ts pgf -> do
|
||||||
_ | isOpt "missing" opts ->
|
concr <- optLang pgf opts
|
||||||
return . fromString . unwords .
|
case opts of
|
||||||
morphoMissing (optMorpho env opts) .
|
_ | isOpt "missing" opts ->
|
||||||
concatMap words $ toStrings ts
|
return . fromString . unwords .
|
||||||
_ | isOpt "known" opts ->
|
morphoMissing concr .
|
||||||
return . fromString . unwords .
|
concatMap words $ toStrings ts
|
||||||
morphoKnown (optMorpho env opts) .
|
_ | isOpt "known" opts ->
|
||||||
concatMap words $ toStrings ts
|
return . fromString . unwords .
|
||||||
_ -> return . fromString . unlines .
|
morphoKnown concr .
|
||||||
map prMorphoAnalysis . concatMap (morphos env opts) .
|
concatMap words $ toStrings ts
|
||||||
concatMap words $ toStrings ts,
|
_ -> return . fromString . unlines .
|
||||||
|
map prMorphoAnalysis . concatMap (morphos pgf opts) .
|
||||||
|
concatMap words $ toStrings ts,
|
||||||
flags = [
|
flags = [
|
||||||
("lang","the languages of analysis (comma-separated, no spaces)")
|
("lang","the languages of analysis (comma-separated, no spaces)")
|
||||||
],
|
],
|
||||||
@@ -334,18 +306,16 @@ pgfCommands = Map.fromList [
|
|||||||
longname = "morpho_quiz",
|
longname = "morpho_quiz",
|
||||||
synopsis = "start a morphology quiz",
|
synopsis = "start a morphology quiz",
|
||||||
syntax = "mq (-cat=CAT)? (-probs=FILE)? TREE?",
|
syntax = "mq (-cat=CAT)? (-probs=FILE)? TREE?",
|
||||||
exec = getEnv $ \ opts arg (Env pgf mos) -> do
|
exec = needPGF $ \ opts arg pgf -> do
|
||||||
let lang = optLang pgf opts
|
lang <- optLang pgf opts
|
||||||
let typ = optType pgf opts
|
let typ = optType pgf opts
|
||||||
pgf <- optProbs opts pgf
|
|
||||||
let mt = mexp (toExprs arg)
|
let mt = mexp (toExprs arg)
|
||||||
restricted $ morphologyQuiz mt pgf lang typ
|
restricted $ morphologyQuiz mt pgf lang typ
|
||||||
return void,
|
return void,
|
||||||
flags = [
|
flags = [
|
||||||
("lang","language of the quiz"),
|
("lang","language of the quiz"),
|
||||||
("cat","category of the quiz"),
|
("cat","category of the quiz"),
|
||||||
("number","maximum number of questions"),
|
("number","maximum number of questions")
|
||||||
("probs","file with biased probabilities for generation")
|
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@@ -356,24 +326,25 @@ pgfCommands = Map.fromList [
|
|||||||
"Shows all trees returned by parsing a string in the grammars in scope.",
|
"Shows all trees returned by parsing a string in the grammars in scope.",
|
||||||
"The -lang flag can be used to restrict this to fewer languages.",
|
"The -lang flag can be used to restrict this to fewer languages.",
|
||||||
"The default start category can be overridden by the -cat flag.",
|
"The default start category can be overridden by the -cat flag.",
|
||||||
"See also the ps command for lexing and character encoding.",
|
"See also the ps command for lexing and character encoding."
|
||||||
"",
|
],
|
||||||
"The -openclass flag is experimental and allows some robustness in ",
|
exec = needPGF $ \opts ts pgf ->
|
||||||
"the parser. For example if -openclass=\"A,N,V\" is given, the parser",
|
return $
|
||||||
"will accept unknown adjectives, nouns and verbs with the resource grammar."
|
foldr (joinPiped . fromParse1 opts) void
|
||||||
|
(concat [
|
||||||
|
[(s,parse concr (optType pgf opts) s) |
|
||||||
|
concr <- optLangs pgf opts]
|
||||||
|
| s <- toStrings ts]),
|
||||||
|
options = [
|
||||||
|
("show_probs", "show the probability of each result")
|
||||||
],
|
],
|
||||||
exec = getEnv $ \ opts ts (Env pgf mos) ->
|
|
||||||
return $ fromParse opts (concat [map ((,) s) (par pgf opts s) | s <- toStrings ts]),
|
|
||||||
flags = [
|
flags = [
|
||||||
("cat","target category of parsing"),
|
("cat","target category of parsing"),
|
||||||
("lang","the languages of parsing (comma-separated, no spaces)"),
|
("lang","the languages of parsing (comma-separated, no spaces)"),
|
||||||
("openclass","list of open-class categories for robust parsing"),
|
("number","limit the results to the top N trees")
|
||||||
("depth","maximal depth for proof search if the abstract syntax tree has meta variables")
|
|
||||||
],
|
|
||||||
options = [
|
|
||||||
("bracket","prints the bracketed string from the parser")
|
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
|
|
||||||
("pg", emptyCommandInfo { -----
|
("pg", emptyCommandInfo { -----
|
||||||
longname = "print_grammar",
|
longname = "print_grammar",
|
||||||
synopsis = "print the actual grammar with the given printer",
|
synopsis = "print the actual grammar with the given printer",
|
||||||
@@ -393,9 +364,8 @@ pgfCommands = Map.fromList [
|
|||||||
" " ++ opt ++ "\t\t" ++ expl |
|
" " ++ opt ++ "\t\t" ++ expl |
|
||||||
((opt,_),expl) <- outputFormatsExpl, take 1 expl /= "*"
|
((opt,_),expl) <- outputFormatsExpl, take 1 expl /= "*"
|
||||||
]),
|
]),
|
||||||
exec = getEnv $ \opts _ env -> prGrammar env opts,
|
exec = needPGF $ \opts _ pgf -> prGrammar pgf opts,
|
||||||
flags = [
|
flags = [
|
||||||
--"cat",
|
|
||||||
("file", "set the file name when printing with -pgf option"),
|
("file", "set the file name when printing with -pgf option"),
|
||||||
("lang", "select languages for the some options (default all languages)"),
|
("lang", "select languages for the some options (default all languages)"),
|
||||||
("printer","select the printing format (see flag values above)")
|
("printer","select the printing format (see flag values above)")
|
||||||
@@ -415,6 +385,7 @@ pgfCommands = Map.fromList [
|
|||||||
mkEx ("pg -funs | ? grep \" S ;\" -- show functions with value cat S")
|
mkEx ("pg -funs | ? grep \" S ;\" -- show functions with value cat S")
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
|
|
||||||
("pt", emptyCommandInfo {
|
("pt", emptyCommandInfo {
|
||||||
longname = "put_tree",
|
longname = "put_tree",
|
||||||
syntax = "pt OPT? TREE",
|
syntax = "pt OPT? TREE",
|
||||||
@@ -428,11 +399,12 @@ pgfCommands = Map.fromList [
|
|||||||
examples = [
|
examples = [
|
||||||
mkEx "pt -compute (plus one two) -- compute value"
|
mkEx "pt -compute (plus one two) -- compute value"
|
||||||
],
|
],
|
||||||
exec = getEnv $ \ opts arg (Env pgf mos) ->
|
exec = needPGF $ \opts arg pgf ->
|
||||||
returnFromExprs . takeOptNum opts . treeOps pgf opts $ toExprs arg,
|
returnFromExprs False . takeOptNum opts . map (flip (,) 0) . treeOps pgf opts $ toExprs arg,
|
||||||
options = treeOpOptions undefined{-pgf-},
|
options = treeOpOptions undefined{-pgf-},
|
||||||
flags = [("number","take at most this many trees")] ++ treeOpFlags undefined{-pgf-}
|
flags = [("number","take at most this many trees")] ++ treeOpFlags undefined{-pgf-}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
("rf", emptyCommandInfo {
|
("rf", emptyCommandInfo {
|
||||||
longname = "read_file",
|
longname = "read_file",
|
||||||
synopsis = "read string or tree input from a file",
|
synopsis = "read string or tree input from a file",
|
||||||
@@ -445,10 +417,9 @@ pgfCommands = Map.fromList [
|
|||||||
],
|
],
|
||||||
options = [
|
options = [
|
||||||
("lines","return the list of lines, instead of the singleton of all contents"),
|
("lines","return the list of lines, instead of the singleton of all contents"),
|
||||||
("paragraphs","return the list of paragraphs, as separated by empty lines"),
|
|
||||||
("tree","convert strings into trees")
|
("tree","convert strings into trees")
|
||||||
],
|
],
|
||||||
exec = getEnv $ \ opts _ (Env pgf mos) -> do
|
exec = needPGF $ \ opts _ pgf -> do
|
||||||
let file = valStrOpts "file" "_gftmp" opts
|
let file = valStrOpts "file" "_gftmp" opts
|
||||||
let exprs [] = ([],empty)
|
let exprs [] = ([],empty)
|
||||||
exprs ((n,s):ls) | null s
|
exprs ((n,s):ls) | null s
|
||||||
@@ -457,12 +428,12 @@ pgfCommands = Map.fromList [
|
|||||||
Just e -> let (es,err) = exprs ls
|
Just e -> let (es,err) = exprs ls
|
||||||
in case inferExpr pgf e of
|
in case inferExpr pgf e of
|
||||||
Right (e,t) -> (e:es,err)
|
Right (e,t) -> (e:es,err)
|
||||||
Left tcerr -> (es,"on line" <+> n <> ':' $$ nest 2 (ppTcError tcerr) $$ err)
|
Left err -> (es,"on line" <+> n <> ':' $$ nest 2 err $$ err)
|
||||||
Nothing -> let (es,err) = exprs ls
|
Nothing -> let (es,err) = exprs ls
|
||||||
in (es,"on line" <+> n <> ':' <+> "parse error" $$ err)
|
in (es,"on line" <+> n <> ':' <+> "parse error" $$ err)
|
||||||
returnFromLines ls = case exprs ls of
|
returnFromLines ls = case exprs ls of
|
||||||
(es, err) | null es -> return $ pipeMessage $ render (err $$ "no trees found")
|
(es, err) | null es -> return $ pipeMessage $ render (err $$ "no trees found")
|
||||||
| otherwise -> return $ pipeWithMessage es (render err)
|
| otherwise -> return $ pipeWithMessage (map (flip (,) 0) es) (render err)
|
||||||
|
|
||||||
s <- restricted $ readFile file
|
s <- restricted $ readFile file
|
||||||
case opts of
|
case opts of
|
||||||
@@ -471,56 +442,26 @@ pgfCommands = Map.fromList [
|
|||||||
_ | isOpt "tree" opts ->
|
_ | isOpt "tree" opts ->
|
||||||
returnFromLines [(1::Int,s)]
|
returnFromLines [(1::Int,s)]
|
||||||
_ | isOpt "lines" opts -> return (fromStrings $ lines s)
|
_ | isOpt "lines" opts -> return (fromStrings $ lines s)
|
||||||
_ | isOpt "paragraphs" opts -> return (fromStrings $ toParagraphs $ lines s)
|
|
||||||
_ -> return (fromString s),
|
_ -> return (fromString s),
|
||||||
flags = [("file","the input file name")]
|
flags = [("file","the input file name")]
|
||||||
}),
|
}),
|
||||||
("rt", emptyCommandInfo {
|
|
||||||
longname = "rank_trees",
|
|
||||||
synopsis = "show trees in an order of decreasing probability",
|
|
||||||
explanation = unlines [
|
|
||||||
"Order trees from the most to the least probable, using either",
|
|
||||||
"even distribution in each category (default) or biased as specified",
|
|
||||||
"by the file given by flag -probs=FILE, where each line has the form",
|
|
||||||
"'function probability', e.g. 'youPol_Pron 0.01'."
|
|
||||||
],
|
|
||||||
exec = getEnv $ \ opts arg (Env pgf mos) -> do
|
|
||||||
let ts = toExprs arg
|
|
||||||
pgf <- optProbs opts pgf
|
|
||||||
let tds = rankTreesByProbs pgf ts
|
|
||||||
if isOpt "v" opts
|
|
||||||
then putStrLn $
|
|
||||||
unlines [showExpr [] t ++ "\t--" ++ show d | (t,d) <- tds]
|
|
||||||
else return ()
|
|
||||||
returnFromExprs $ map fst tds,
|
|
||||||
flags = [
|
|
||||||
("probs","probabilities from this file (format 'f 0.6' per line)")
|
|
||||||
],
|
|
||||||
options = [
|
|
||||||
("v","show all trees with their probability scores")
|
|
||||||
],
|
|
||||||
examples = [
|
|
||||||
mkEx "p \"you are here\" | rt -probs=probs | pt -number=1 -- most probable result"
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
("tq", emptyCommandInfo {
|
("tq", emptyCommandInfo {
|
||||||
longname = "translation_quiz",
|
longname = "translation_quiz",
|
||||||
syntax = "tq -from=LANG -to=LANG (-cat=CAT)? (-probs=FILE)? TREE?",
|
syntax = "tq -from=LANG -to=LANG (-cat=CAT)? (-probs=FILE)? TREE?",
|
||||||
synopsis = "start a translation quiz",
|
synopsis = "start a translation quiz",
|
||||||
exec = getEnv $ \ opts arg (Env pgf mos) -> do
|
exec = needPGF $ \ opts arg pgf -> do
|
||||||
let from = optLangFlag "from" pgf opts
|
from <- optLangFlag "from" pgf opts
|
||||||
let to = optLangFlag "to" pgf opts
|
to <- optLangFlag "to" pgf opts
|
||||||
let typ = optType pgf opts
|
let typ = optType pgf opts
|
||||||
let mt = mexp (toExprs arg)
|
let mt = mexp (toExprs arg)
|
||||||
pgf <- optProbs opts pgf
|
|
||||||
restricted $ translationQuiz mt pgf from to typ
|
restricted $ translationQuiz mt pgf from to typ
|
||||||
return void,
|
return void,
|
||||||
flags = [
|
flags = [
|
||||||
("from","translate from this language"),
|
("from","translate from this language"),
|
||||||
("to","translate to this language"),
|
("to","translate to this language"),
|
||||||
("cat","translate in this category"),
|
("cat","translate in this category"),
|
||||||
("number","the maximum number of questions"),
|
("number","the maximum number of questions")
|
||||||
("probs","file with biased probabilities for generation")
|
|
||||||
],
|
],
|
||||||
examples = [
|
examples = [
|
||||||
mkEx ("tq -from=Eng -to=Swe -- any trees in startcat"),
|
mkEx ("tq -from=Eng -to=Swe -- any trees in startcat"),
|
||||||
@@ -528,7 +469,6 @@ pgfCommands = Map.fromList [
|
|||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
||||||
("vd", emptyCommandInfo {
|
("vd", emptyCommandInfo {
|
||||||
longname = "visualize_dependency",
|
longname = "visualize_dependency",
|
||||||
synopsis = "show word dependency tree graphically",
|
synopsis = "show word dependency tree graphically",
|
||||||
@@ -546,7 +486,7 @@ pgfCommands = Map.fromList [
|
|||||||
"flag -format. Results from multiple trees are combined to pdf with convert (ImageMagick).",
|
"flag -format. Results from multiple trees are combined to pdf with convert (ImageMagick).",
|
||||||
"See also 'vp -showdep' for another visualization of dependencies."
|
"See also 'vp -showdep' for another visualization of dependencies."
|
||||||
],
|
],
|
||||||
exec = getEnv $ \ opts arg (Env pgf mos) -> do
|
exec = needPGF $ \ opts arg pgf -> do
|
||||||
let absname = abstractName pgf
|
let absname = abstractName pgf
|
||||||
let es = toExprs arg
|
let es = toExprs arg
|
||||||
let debug = isOpt "v" opts
|
let debug = isOpt "v" opts
|
||||||
@@ -559,8 +499,8 @@ pgfCommands = Map.fromList [
|
|||||||
mclab <- case cnclabels of
|
mclab <- case cnclabels of
|
||||||
"" -> return Nothing
|
"" -> return Nothing
|
||||||
_ -> (Just . getCncDepLabels) `fmap` restricted (readFile cnclabels)
|
_ -> (Just . getCncDepLabels) `fmap` restricted (readFile cnclabels)
|
||||||
let lang = optLang pgf opts
|
concr <- optLang pgf opts
|
||||||
let grphs = map (graphvizDependencyTree outp debug mlab mclab pgf lang) es
|
let grphs = map (graphvizDependencyTree outp debug mlab mclab concr) es
|
||||||
if isOpt "conll2latex" opts
|
if isOpt "conll2latex" opts
|
||||||
then return $ fromString $ conlls2latexDoc $ stanzas $ unlines $ toStrings arg
|
then return $ fromString $ conlls2latexDoc $ stanzas $ unlines $ toStrings arg
|
||||||
else if isFlag "view" opts && valStrOpts "output" "" opts == "latex"
|
else if isFlag "view" opts && valStrOpts "output" "" opts == "latex"
|
||||||
@@ -595,7 +535,6 @@ pgfCommands = Map.fromList [
|
|||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
||||||
("vp", emptyCommandInfo {
|
("vp", emptyCommandInfo {
|
||||||
longname = "visualize_parse",
|
longname = "visualize_parse",
|
||||||
synopsis = "show parse tree graphically",
|
synopsis = "show parse tree graphically",
|
||||||
@@ -607,9 +546,8 @@ pgfCommands = Map.fromList [
|
|||||||
"by the view flag. The target format is png, unless overridden by the",
|
"by the view flag. The target format is png, unless overridden by the",
|
||||||
"flag -format. Results from multiple trees are combined to pdf with convert (ImageMagick)."
|
"flag -format. Results from multiple trees are combined to pdf with convert (ImageMagick)."
|
||||||
],
|
],
|
||||||
exec = getEnv $ \ opts arg (Env pgf mos) -> do
|
exec = needPGF $ \opts arg pgf -> do
|
||||||
let es = toExprs arg
|
let es = toExprs arg
|
||||||
let lang = optLang pgf opts
|
|
||||||
let gvOptions = GraphvizOptions {noLeaves = isOpt "noleaves" opts && not (isOpt "showleaves" opts),
|
let gvOptions = GraphvizOptions {noLeaves = isOpt "noleaves" opts && not (isOpt "showleaves" opts),
|
||||||
noFun = isOpt "nofun" opts || not (isOpt "showfun" opts),
|
noFun = isOpt "nofun" opts || not (isOpt "showfun" opts),
|
||||||
noCat = isOpt "nocat" opts && not (isOpt "showcat" opts),
|
noCat = isOpt "nocat" opts && not (isOpt "showcat" opts),
|
||||||
@@ -622,10 +560,11 @@ pgfCommands = Map.fromList [
|
|||||||
leafEdgeStyle = valStrOpts "leafedgestyle" "dashed" opts
|
leafEdgeStyle = valStrOpts "leafedgestyle" "dashed" opts
|
||||||
}
|
}
|
||||||
let depfile = valStrOpts "file" "" opts
|
let depfile = valStrOpts "file" "" opts
|
||||||
|
concr <- optLang pgf opts
|
||||||
mlab <- case depfile of
|
mlab <- case depfile of
|
||||||
"" -> return Nothing
|
"" -> return Nothing
|
||||||
_ -> (Just . getDepLabels) `fmap` restricted (readFile depfile)
|
_ -> (Just . getDepLabels) `fmap` restricted (readFile depfile)
|
||||||
let grphs = map (graphvizParseTreeDep mlab pgf lang gvOptions) es
|
let grphs = map (graphvizDependencyTree "dot" False mlab Nothing concr) es
|
||||||
if isFlag "view" opts || isFlag "format" opts
|
if isFlag "view" opts || isFlag "format" opts
|
||||||
then do
|
then do
|
||||||
let view = optViewGraph opts
|
let view = optViewGraph opts
|
||||||
@@ -660,7 +599,6 @@ pgfCommands = Map.fromList [
|
|||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
||||||
("vt", emptyCommandInfo {
|
("vt", emptyCommandInfo {
|
||||||
longname = "visualize_tree",
|
longname = "visualize_tree",
|
||||||
synopsis = "show a set of trees graphically",
|
synopsis = "show a set of trees graphically",
|
||||||
@@ -673,7 +611,7 @@ pgfCommands = Map.fromList [
|
|||||||
"flag -format. Results from multiple trees are combined to pdf with convert (ImageMagick).",
|
"flag -format. Results from multiple trees are combined to pdf with convert (ImageMagick).",
|
||||||
"With option -mk, use for showing library style function names of form 'mkC'."
|
"With option -mk, use for showing library style function names of form 'mkC'."
|
||||||
],
|
],
|
||||||
exec = getEnv $ \ opts arg (Env pgf mos) ->
|
exec = needPGF $ \opts arg pgf ->
|
||||||
let es = toExprs arg in
|
let es = toExprs arg in
|
||||||
if isOpt "mk" opts
|
if isOpt "mk" opts
|
||||||
then return $ fromString $ unlines $ map (tree2mk pgf) es
|
then return $ fromString $ unlines $ map (tree2mk pgf) es
|
||||||
@@ -685,7 +623,7 @@ pgfCommands = Map.fromList [
|
|||||||
else do
|
else do
|
||||||
let funs = not (isOpt "nofun" opts)
|
let funs = not (isOpt "nofun" opts)
|
||||||
let cats = not (isOpt "nocat" opts)
|
let cats = not (isOpt "nocat" opts)
|
||||||
let grphs = map (graphvizAbstractTree pgf (funs,cats)) es
|
let grphs = map (graphvizAbstractTree pgf (graphvizDefaults{noFun=funs,noCat=cats})) es
|
||||||
if isFlag "view" opts || isFlag "format" opts
|
if isFlag "view" opts || isFlag "format" opts
|
||||||
then do
|
then do
|
||||||
let view = optViewGraph opts
|
let view = optViewGraph opts
|
||||||
@@ -707,6 +645,7 @@ pgfCommands = Map.fromList [
|
|||||||
("view","program to open the resulting file (default \"open\")")
|
("view","program to open the resulting file (default \"open\")")
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
|
|
||||||
("ai", emptyCommandInfo {
|
("ai", emptyCommandInfo {
|
||||||
longname = "abstract_info",
|
longname = "abstract_info",
|
||||||
syntax = "ai IDENTIFIER or ai EXPR",
|
syntax = "ai IDENTIFIER or ai EXPR",
|
||||||
@@ -719,205 +658,156 @@ pgfCommands = Map.fromList [
|
|||||||
"If a whole expression is given it prints the expression with refined",
|
"If a whole expression is given it prints the expression with refined",
|
||||||
"metavariables and the type of the expression."
|
"metavariables and the type of the expression."
|
||||||
],
|
],
|
||||||
exec = getEnv $ \ opts arg (Env pgf mos) -> do
|
exec = needPGF $ \opts arg pgf -> do
|
||||||
case toExprs arg of
|
case toExprs arg of
|
||||||
[EFun id] -> case Map.lookup id (funs (abstract pgf)) of
|
[e] -> case unApp e of
|
||||||
Just fd -> do putStrLn $ render (ppFun id fd)
|
Just (id, []) -> case functionType pgf id of
|
||||||
let (_,_,_,prob) = fd
|
Just ty -> do putStrLn (showFun pgf id ty)
|
||||||
putStrLn ("Probability: "++show prob)
|
putStrLn ("Probability: "++show (treeProbability pgf e))
|
||||||
return void
|
return void
|
||||||
Nothing -> case Map.lookup id (cats (abstract pgf)) of
|
Nothing -> case categoryContext pgf id of
|
||||||
Just cd -> do putStrLn $
|
Just hypos -> do putStrLn ("cat "++id++if null hypos then "" else ' ':showContext [] hypos)
|
||||||
render (ppCat id cd $$
|
let ls = [showFun pgf fn ty | fn <- functionsByCat pgf id, Just ty <- [functionType pgf fn]]
|
||||||
if null (functionsToCat pgf id)
|
if null ls
|
||||||
then empty
|
then return ()
|
||||||
else ' ' $$
|
else putStrLn (unlines ("":ls))
|
||||||
vcat [ppFun fid (ty,0,Just ([],[]),0) | (fid,ty) <- functionsToCat pgf id] $$
|
putStrLn ("Probability: "++show (categoryProbability pgf id))
|
||||||
' ')
|
return void
|
||||||
let (_,_,prob) = cd
|
Nothing -> do putStrLn ("unknown category of function identifier "++show id)
|
||||||
putStrLn ("Probability: "++show prob)
|
return void
|
||||||
return void
|
_ -> case inferExpr pgf e of
|
||||||
Nothing -> do putStrLn ("unknown category of function identifier "++show id)
|
Left err -> error err
|
||||||
return void
|
Right (e,ty) -> do putStrLn ("Expression: "++showExpr [] e)
|
||||||
[e] -> case inferExpr pgf e of
|
putStrLn ("Type: "++showType [] ty)
|
||||||
Left tcErr -> error $ render (ppTcError tcErr)
|
putStrLn ("Probability: "++show (treeProbability pgf e))
|
||||||
Right (e,ty) -> do putStrLn ("Expression: "++showExpr [] e)
|
return void
|
||||||
putStrLn ("Type: "++showType [] ty)
|
|
||||||
putStrLn ("Probability: "++show (probTree pgf e))
|
|
||||||
return void
|
|
||||||
_ -> do putStrLn "a single identifier or expression is expected from the command"
|
_ -> do putStrLn "a single identifier or expression is expected from the command"
|
||||||
return void,
|
return void,
|
||||||
needsTypeCheck = False
|
needsTypeCheck = False
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
getEnv exec opts ts = liftSIO . exec opts ts =<< getPGFEnv
|
needPGF exec opts ts = do
|
||||||
|
mb_pgf <- getPGF
|
||||||
par pgf opts s = case optOpenTypes opts of
|
case mb_pgf of
|
||||||
[] -> [parse_ pgf lang (optType pgf opts) (Just dp) s | lang <- optLangs pgf opts]
|
Just pgf -> liftSIO $ exec opts ts pgf
|
||||||
open_typs -> [parseWithRecovery pgf lang (optType pgf opts) open_typs (Just dp) s | lang <- optLangs pgf opts]
|
_ -> fail "Import a grammar before using this command"
|
||||||
where
|
|
||||||
dp = valIntOpts "depth" 4 opts
|
|
||||||
|
|
||||||
fromParse opts = foldr (joinPiped . fromParse1 opts) void
|
|
||||||
|
|
||||||
joinPiped (Piped (es1,ms1)) (Piped (es2,ms2)) = Piped (jA es1 es2,ms1+++-ms2)
|
joinPiped (Piped (es1,ms1)) (Piped (es2,ms2)) = Piped (jA es1 es2,ms1+++-ms2)
|
||||||
where
|
where
|
||||||
jA (Exprs es1) (Exprs es2) = Exprs (es1++es2)
|
jA (Exprs es1) (Exprs es2) = Exprs (es1++es2)
|
||||||
-- ^ fromParse1 always output Exprs
|
|
||||||
|
|
||||||
fromParse1 opts (s,(po,bs))
|
fromParse1 opts (s,po) =
|
||||||
| isOpt "bracket" opts = pipeMessage (showBracketedString bs)
|
case po of
|
||||||
| otherwise =
|
ParseOk ts -> fromExprs (isOpt "show_probs" opts) (takeOptNum opts ts)
|
||||||
case po of
|
ParseFailed i t -> pipeMessage $ "The parser failed at token "
|
||||||
ParseOk ts -> fromExprs ts
|
++ show i ++": "
|
||||||
ParseFailed i -> pipeMessage $ "The parser failed at token "
|
++ show t
|
||||||
++ show i ++": "
|
ParseIncomplete -> pipeMessage "The sentence is not complete"
|
||||||
++ show (words s !! max 0 (i-1))
|
|
||||||
-- ++ " in " ++ show s
|
|
||||||
ParseIncomplete -> pipeMessage "The sentence is not complete"
|
|
||||||
TypeError errs ->
|
|
||||||
pipeMessage . render $
|
|
||||||
"The parsing is successful but the type checking failed with error(s):"
|
|
||||||
$$ nest 2 (vcat (map (ppTcError . snd) errs))
|
|
||||||
|
|
||||||
optLins pgf opts ts = case opts of
|
optLins pgf opts ts = concatMap (optLin pgf opts) ts
|
||||||
_ | isOpt "groups" opts ->
|
|
||||||
concatMap snd $ groupResults
|
|
||||||
[[(lang, s) | lang <- optLangs pgf opts,s <- linear pgf opts lang t] | t <- ts]
|
|
||||||
_ -> concatMap (optLin pgf opts) ts
|
|
||||||
optLin pgf opts t =
|
optLin pgf opts t =
|
||||||
case opts of
|
case opts of
|
||||||
_ | isOpt "treebank" opts && isOpt "chunks" opts ->
|
_ | isOpt "treebank" opts && isOpt "chunks" opts ->
|
||||||
(showCId (abstractName pgf) ++ ": " ++ showExpr [] t) :
|
(abstractName pgf ++ ": " ++ showExpr [] t) :
|
||||||
[showCId lang ++ ": " ++ li | (lang,li) <- linChunks pgf opts t] --linear pgf opts lang t | lang <- optLangs pgf opts]
|
[lang ++ ": " ++ li | (lang,li) <- linChunks pgf opts t] --linear pgf opts lang t | lang <- optLangs pgf opts]
|
||||||
_ | isOpt "treebank" opts ->
|
_ | isOpt "treebank" opts ->
|
||||||
(showCId (abstractName pgf) ++ ": " ++ showExpr [] t) :
|
(abstractName pgf ++ ": " ++ showExpr [] t) :
|
||||||
[showCId lang ++ ": " ++ s | lang <- optLangs pgf opts, s<-linear pgf opts lang t]
|
[concreteName concr ++ ": " ++ s | concr <- optLangs pgf opts, s<-linear opts concr t]
|
||||||
_ | isOpt "tabtreebank" opts ->
|
|
||||||
return $ concat $ intersperse "\t" $ (showExpr [] t) :
|
|
||||||
[s | lang <- optLangs pgf opts, s <- linear pgf opts lang t]
|
|
||||||
_ | isOpt "chunks" opts -> map snd $ linChunks pgf opts t
|
_ | isOpt "chunks" opts -> map snd $ linChunks pgf opts t
|
||||||
_ -> [s | lang <- optLangs pgf opts, s<-linear pgf opts lang t]
|
_ -> [s | concr <- optLangs pgf opts, s <- linear opts concr t]
|
||||||
linChunks pgf opts t =
|
linChunks pgf opts t =
|
||||||
[(lang, unwords (intersperse "<+>" (map (unlines . linear pgf opts lang) (treeChunks t)))) | lang <- optLangs pgf opts]
|
[(concreteName concr, unwords (intersperse "<+>" (map (unlines . linear opts concr) (treeChunks t)))) | concr <- optLangs pgf opts]
|
||||||
|
|
||||||
linear :: PGF -> [Option] -> CId -> Expr -> [String]
|
linear :: [Option] -> Concr -> Expr -> [String]
|
||||||
linear pgf opts lang = let unl = unlex opts lang in case opts of
|
linear opts concr = case opts of
|
||||||
_ | isOpt "all" opts -> concat . -- intersperse [[]] .
|
_ | isOpt "all" opts -> concat .
|
||||||
map (map (unl . snd)) . tabularLinearizes pgf lang
|
map (map snd) . tabularLinearizeAll concr
|
||||||
_ | isOpt "list" opts -> (:[]) . commaList . concat .
|
_ | isOpt "list" opts -> (:[]) . commaList . concat .
|
||||||
map (map (unl . snd)) . tabularLinearizes pgf lang
|
map (map snd) . tabularLinearizeAll concr
|
||||||
_ | isOpt "table" opts -> concat . -- intersperse [[]] .
|
_ | isOpt "table" opts -> concat .
|
||||||
map (map (\(p,v) -> p+++":"+++unl v)) . tabularLinearizes pgf lang
|
map (map (\(p,v) -> p+++":"+++v)) . tabularLinearizeAll concr
|
||||||
_ | isOpt "bracket" opts -> (:[]) . unwords . map showBracketedString . bracketedLinearize pgf lang
|
_ | isOpt "bracket" opts -> (:[]) . unwords . map showBracketedString . bracketedLinearize concr
|
||||||
_ -> (:[]) . unl . linearize pgf lang
|
_ -> (:[]) . linearize concr
|
||||||
|
|
||||||
-- replace each non-atomic constructor with mkC, where C is the val cat
|
-- replace each non-atomic constructor with mkC, where C is the val cat
|
||||||
tree2mk pgf = showExpr [] . t2m where
|
tree2mk pgf = showExpr [] . t2m where
|
||||||
t2m t = case unApp t of
|
t2m t = case unApp t of
|
||||||
Just (cid,ts@(_:_)) -> mkApp (mk cid) (map t2m ts)
|
Just (cid,ts@(_:_)) -> mkApp (mk cid) (map t2m ts)
|
||||||
_ -> t
|
_ -> t
|
||||||
mk = mkCId . ("mk" ++) . showCId . lookValCat (abstract pgf)
|
mk f = case functionType pgf f of
|
||||||
|
Just ty -> let (_,cat,_) = unType ty
|
||||||
unlex opts lang = stringOps Nothing (getUnlex opts lang ++ map prOpt opts) ----
|
in "mk" ++ cat
|
||||||
|
Nothing -> f
|
||||||
getUnlex opts lang = case words (valStrOpts "unlexer" "" opts) of
|
|
||||||
lexs -> case lookup lang
|
|
||||||
[(mkCId la,tail le) | lex <- lexs, let (la,le) = span (/='=') lex, not (null le)] of
|
|
||||||
Just le -> chunks ',' le
|
|
||||||
_ -> []
|
|
||||||
|
|
||||||
commaList [] = []
|
commaList [] = []
|
||||||
commaList ws = concat $ head ws : map (", " ++) (tail ws)
|
commaList ws = concat $ head ws : map (", " ++) (tail ws)
|
||||||
|
|
||||||
-- Proposed logic of coding in unlexing:
|
|
||||||
-- - If lang has no coding flag, or -to_utf8 is not in opts, just opts are used.
|
|
||||||
-- - If lang has flag coding=utf8, -to_utf8 is ignored.
|
|
||||||
-- - If lang has coding=other, and -to_utf8 is in opts, from_other is applied first.
|
|
||||||
-- THIS DOES NOT WORK UNFORTUNATELY - can't use the grammar flag properly
|
|
||||||
{-
|
|
||||||
unlexx pgf opts lang = {- trace (unwords optsC) $ -} stringOps Nothing optsC where ----
|
|
||||||
optsC = case lookConcrFlag pgf (mkCId lang) (mkCId "coding") of
|
|
||||||
Just (LStr "utf8") -> filter (/="to_utf8") $ map prOpt opts
|
|
||||||
Just (LStr other) | isOpt "to_utf8" opts ->
|
|
||||||
let cod = ("from_" ++ other)
|
|
||||||
in cod : filter (/=cod) (map prOpt opts)
|
|
||||||
_ -> map prOpt opts
|
|
||||||
-}
|
|
||||||
optRestricted opts pgf =
|
|
||||||
restrictPGF (\f -> and [hasLin pgf la f | la <- optLangs pgf opts]) pgf
|
|
||||||
|
|
||||||
optLang = optLangFlag "lang"
|
optLang = optLangFlag "lang"
|
||||||
optLangs = optLangsFlag "lang"
|
optLangs = optLangsFlag "lang"
|
||||||
|
|
||||||
optLangsFlag f pgf opts = case valStrOpts f "" opts of
|
optLangFlag flag pgf opts =
|
||||||
"" -> languages pgf
|
case optLangsFlag flag pgf opts of
|
||||||
lang -> map (completeLang pgf) (chunks ',' lang)
|
[] -> fail "no language specified"
|
||||||
completeLang pgf la = let cla = (mkCId la) in
|
(l:ls) -> return l
|
||||||
if elem cla (languages pgf)
|
|
||||||
then cla
|
|
||||||
else (mkCId (showCId (abstractName pgf) ++ la))
|
|
||||||
|
|
||||||
optLangFlag f pgf opts = head $ optLangsFlag f pgf opts ++ [wildCId]
|
optLangsFlag flag pgf opts =
|
||||||
|
case valStrOpts flag "" opts of
|
||||||
|
"" -> Map.elems langs
|
||||||
|
str -> mapMaybe (completeLang pgf) (chunks ',' str)
|
||||||
|
where
|
||||||
|
langs = languages pgf
|
||||||
|
|
||||||
optOpenTypes opts = case valStrOpts "openclass" "" opts of
|
completeLang pgf la =
|
||||||
"" -> []
|
mplus (Map.lookup la langs)
|
||||||
cats -> mapMaybe readType (chunks ',' cats)
|
(Map.lookup (abstractName pgf ++ la) langs)
|
||||||
|
|
||||||
optProbs opts pgf = case valStrOpts "probs" "" opts of
|
|
||||||
"" -> return pgf
|
|
||||||
file -> do
|
|
||||||
probs <- restricted $ readProbabilitiesFromFile file pgf
|
|
||||||
return (setProbabilities probs pgf)
|
|
||||||
|
|
||||||
optFile opts = valStrOpts "file" "_gftmp" opts
|
optFile opts = valStrOpts "file" "_gftmp" opts
|
||||||
|
|
||||||
optType pgf opts =
|
optType pgf opts =
|
||||||
let str = valStrOpts "cat" (showCId $ lookStartCat pgf) opts
|
let readOpt str = case readType str of
|
||||||
in case readType str of
|
Just ty -> case checkType pgf ty of
|
||||||
Just ty -> case checkType pgf ty of
|
Left err -> error err
|
||||||
Left tcErr -> error $ render (ppTcError tcErr)
|
Right ty -> ty
|
||||||
Right ty -> ty
|
Nothing -> error ("Can't parse '"++str++"' as a type")
|
||||||
Nothing -> error ("Can't parse '"++str++"' as a type")
|
in maybeStrOpts "cat" (startCat pgf) readOpt opts
|
||||||
optViewFormat opts = valStrOpts "format" "png" opts
|
optViewFormat opts = valStrOpts "format" "png" opts
|
||||||
optViewGraph opts = valStrOpts "view" "open" opts
|
optViewGraph opts = valStrOpts "view" "open" opts
|
||||||
optNum opts = valIntOpts "number" 1 opts
|
optNum opts = valIntOpts "number" 1 opts
|
||||||
optNumInf opts = valIntOpts "number" 1000000000 opts ---- 10^9
|
optNumInf opts = valIntOpts "number" 1000000000 opts ---- 10^9
|
||||||
takeOptNum opts = take (optNumInf opts)
|
takeOptNum opts = take (optNumInf opts)
|
||||||
|
|
||||||
returnFromExprs es = return $ case es of
|
returnFromExprs show_p es =
|
||||||
[] -> pipeMessage "no trees found"
|
return $
|
||||||
_ -> fromExprs es
|
case es of
|
||||||
|
[] -> pipeMessage "no trees found"
|
||||||
|
_ -> fromExprs show_p es
|
||||||
|
|
||||||
prGrammar (Env pgf mos) opts
|
prGrammar pgf opts
|
||||||
| isOpt "pgf" opts = do
|
| isOpt "pgf" opts = do
|
||||||
let pgf1 = if isOpt "opt" opts then optimizePGF pgf else pgf
|
let outfile = valStrOpts "file" (abstractName pgf ++ ".pgf") opts
|
||||||
let outfile = valStrOpts "file" (showCId (abstractName pgf) ++ ".pgf") opts
|
restricted $ writePGF outfile pgf
|
||||||
restricted $ encodeFile outfile pgf1
|
|
||||||
putStrLn $ "wrote file " ++ outfile
|
putStrLn $ "wrote file " ++ outfile
|
||||||
return void
|
return void
|
||||||
| isOpt "cats" opts = return $ fromString $ unwords $ map showCId $ categories pgf
|
| isOpt "cats" opts = return $ fromString $ unwords $ categories pgf
|
||||||
| isOpt "funs" opts = return $ fromString $ unlines $ map showFun $ funsigs pgf
|
| isOpt "funs" opts = return $ fromString $ unlines [showFun pgf f ty | f <- functions pgf, Just ty <- [functionType pgf f]]
|
||||||
| isOpt "fullform" opts = return $ fromString $ concatMap (morpho mos "" prFullFormLexicon) $ optLangs pgf opts
|
| isOpt "fullform" opts = return $ fromString $ concatMap prFullFormLexicon $ optLangs pgf opts
|
||||||
| isOpt "langs" opts = return $ fromString $ unwords $ map showCId $ languages pgf
|
| isOpt "langs" opts = return $ fromString $ unwords $ Map.keys $ languages pgf
|
||||||
|
|
||||||
| isOpt "lexc" opts = return $ fromString $ concatMap (morpho mos "" prLexcLexicon) $ optLangs pgf opts
|
| isOpt "lexc" opts = return $ fromString $ concatMap prLexcLexicon $ optLangs pgf opts
|
||||||
| isOpt "missing" opts = return $ fromString $ unlines $ [unwords (showCId la:":": map showCId cs) |
|
| isOpt "missing" opts = return $ fromString $ unlines $ [unwords (concreteName concr:":":[f | f <- functions pgf, not (hasLinearization concr f)]) |
|
||||||
la <- optLangs pgf opts, let cs = missingLins pgf la]
|
concr <- optLangs pgf opts]
|
||||||
| isOpt "words" opts = return $ fromString $ concatMap (morpho mos "" prAllWords) $ optLangs pgf opts
|
| isOpt "words" opts = return $ fromString $ concatMap prAllWords $ optLangs pgf opts
|
||||||
| otherwise = do fmt <- readOutputFormat (valStrOpts "printer" "pgf_pretty" opts)
|
| otherwise = do fmt <- readOutputFormat (valStrOpts "printer" "pgf_pretty" opts)
|
||||||
return $ fromString $ concatMap snd $ exportPGF noOptions fmt pgf
|
return $ fromString $ concatMap snd $ exportPGF noOptions fmt pgf
|
||||||
|
|
||||||
funsigs pgf = [(f,ty) | (f,(ty,_,_,_)) <- Map.assocs (funs (abstract pgf))]
|
showFun pgf id ty = kwd++" "++ id ++ " : " ++ showType [] ty
|
||||||
showFun (f,ty) = showCId f ++ " : " ++ showType [] ty ++ " ;"
|
where
|
||||||
|
kwd | functionIsDataCon pgf id = "data"
|
||||||
|
| otherwise = "fun"
|
||||||
|
|
||||||
morphos (Env pgf mos) opts s =
|
morphos pgf opts s =
|
||||||
[(s,morpho mos [] (\mo -> lookupMorpho mo s) la) | la <- optLangs pgf opts]
|
[(s,lookupMorpho concr s) | concr <- optLangs pgf opts]
|
||||||
|
|
||||||
morpho mos z f la = maybe z f $ Map.lookup la mos
|
|
||||||
|
|
||||||
optMorpho (Env pgf mos) opts = morpho mos (error "no morpho") id (head (optLangs pgf opts))
|
|
||||||
|
|
||||||
optClitics opts = case valStrOpts "clitics" "" opts of
|
optClitics opts = case valStrOpts "clitics" "" opts of
|
||||||
"" -> []
|
"" -> []
|
||||||
@@ -930,18 +820,28 @@ pgfCommands = Map.fromList [
|
|||||||
-- ps -f -g s returns g (f s)
|
-- ps -f -g s returns g (f s)
|
||||||
treeOps pgf opts s = foldr app s (reverse opts) where
|
treeOps pgf opts s = foldr app s (reverse opts) where
|
||||||
app (OOpt op) | Just (Left f) <- treeOp pgf op = f
|
app (OOpt op) | Just (Left f) <- treeOp pgf op = f
|
||||||
app (OFlag op (VId x)) | Just (Right f) <- treeOp pgf op = f (mkCId x)
|
app (OFlag op (VId x)) | Just (Right f) <- treeOp pgf op = f x
|
||||||
app _ = id
|
app _ = id
|
||||||
|
|
||||||
|
morphoMissing :: Concr -> [String] -> [String]
|
||||||
|
morphoMissing = morphoClassify False
|
||||||
|
|
||||||
|
morphoKnown :: Concr -> [String] -> [String]
|
||||||
|
morphoKnown = morphoClassify True
|
||||||
|
|
||||||
|
morphoClassify :: Bool -> Concr -> [String] -> [String]
|
||||||
|
morphoClassify k concr ws = [w | w <- ws, k /= null (lookupMorpho concr w), notLiteral w] where
|
||||||
|
notLiteral w = not (all isDigit w)
|
||||||
|
|
||||||
treeOpOptions pgf = [(op,expl) | (op,(expl,Left _)) <- allTreeOps pgf]
|
treeOpOptions pgf = [(op,expl) | (op,(expl,Left _)) <- allTreeOps pgf]
|
||||||
treeOpFlags pgf = [(op,expl) | (op,(expl,Right _)) <- allTreeOps pgf]
|
treeOpFlags pgf = [(op,expl) | (op,(expl,Right _)) <- allTreeOps pgf]
|
||||||
|
|
||||||
translationQuiz :: Maybe Expr -> PGF -> Language -> Language -> Type -> IO ()
|
translationQuiz :: Maybe Expr -> PGF -> Concr -> Concr -> Type -> IO ()
|
||||||
translationQuiz mex pgf ig og typ = do
|
translationQuiz mex pgf ig og typ = do
|
||||||
tts <- translationList mex pgf ig og typ infinity
|
tts <- translationList mex pgf ig og typ infinity
|
||||||
mkQuiz "Welcome to GF Translation Quiz." tts
|
mkQuiz "Welcome to GF Translation Quiz." tts
|
||||||
|
|
||||||
morphologyQuiz :: Maybe Expr -> PGF -> Language -> Type -> IO ()
|
morphologyQuiz :: Maybe Expr -> PGF -> Concr -> Type -> IO ()
|
||||||
morphologyQuiz mex pgf ig typ = do
|
morphologyQuiz mex pgf ig typ = do
|
||||||
tts <- morphologyList mex pgf ig typ infinity
|
tts <- morphologyList mex pgf ig typ infinity
|
||||||
mkQuiz "Welcome to GF Morphology Quiz." tts
|
mkQuiz "Welcome to GF Morphology Quiz." tts
|
||||||
@@ -950,30 +850,28 @@ morphologyQuiz mex pgf ig typ = do
|
|||||||
infinity :: Int
|
infinity :: Int
|
||||||
infinity = 256
|
infinity = 256
|
||||||
|
|
||||||
prLexcLexicon :: Morpho -> String
|
prLexcLexicon :: Concr -> String
|
||||||
prLexcLexicon mo =
|
prLexcLexicon concr =
|
||||||
unlines $ "Multichar_Symbols":multichars:"":"LEXICON Root" : [prLexc l p ++ ":" ++ w ++ " # ;" | (w,lps) <- morpho, (l,p) <- lps] ++ ["END"]
|
unlines $ "Multichar_Symbols":multichars:"":"LEXICON Root" : [prLexc l p ++ ":" ++ w ++ " # ;" | (w,lps) <- morpho, (l,p,_) <- lps] ++ ["END"]
|
||||||
where
|
where
|
||||||
morpho = fullFormLexicon mo
|
morpho = fullFormLexicon concr
|
||||||
prLexc l p = showCId l ++ concat (mkTags (words p))
|
prLexc l p = l ++ concat (mkTags (words p))
|
||||||
mkTags p = case p of
|
mkTags p = case p of
|
||||||
"s":ws -> mkTags ws --- remove record field
|
"s":ws -> mkTags ws --- remove record field
|
||||||
ws -> map ('+':) ws
|
ws -> map ('+':) ws
|
||||||
|
|
||||||
multichars = unwords $ nub $ concat [mkTags (words p) | (w,lps) <- morpho, (l,p) <- lps]
|
multichars = unwords $ nub $ concat [mkTags (words p) | (w,lps) <- morpho, (l,p,_) <- lps]
|
||||||
-- thick_A+(AAdj+Posit+Gen):thick's # ;
|
|
||||||
|
|
||||||
prFullFormLexicon :: Morpho -> String
|
prFullFormLexicon :: Concr -> String
|
||||||
prFullFormLexicon mo =
|
prFullFormLexicon concr =
|
||||||
unlines (map prMorphoAnalysis (fullFormLexicon mo))
|
unlines (map prMorphoAnalysis (fullFormLexicon concr))
|
||||||
|
|
||||||
prAllWords :: Morpho -> String
|
prAllWords :: Concr -> String
|
||||||
prAllWords mo =
|
prAllWords concr =
|
||||||
unwords [w | (w,_) <- fullFormLexicon mo]
|
unwords [w | (w,_) <- fullFormLexicon concr]
|
||||||
|
|
||||||
prMorphoAnalysis :: (String,[(Lemma,Analysis)]) -> String
|
|
||||||
prMorphoAnalysis (w,lps) =
|
prMorphoAnalysis (w,lps) =
|
||||||
unlines (w:[showCId l ++ " : " ++ p | (l,p) <- lps])
|
unlines (w:[l ++ " : " ++ p ++ show prob | (l,p,prob) <- lps])
|
||||||
|
|
||||||
viewGraphviz :: String -> String -> String -> [String] -> SIO CommandOutput
|
viewGraphviz :: String -> String -> String -> [String] -> SIO CommandOutput
|
||||||
viewGraphviz view format name grphs = do
|
viewGraphviz view format name grphs = do
|
||||||
|
|||||||
@@ -1,822 +0,0 @@
|
|||||||
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
|
|
||||||
module GF.Command.Commands2 (
|
|
||||||
PGFEnv,HasPGFEnv(..),pgf,concs,pgfEnv,emptyPGFEnv,pgfCommands,
|
|
||||||
options, flags,
|
|
||||||
) where
|
|
||||||
import Prelude hiding (putStrLn,(<>)) -- GHC 8.4.1 clash with Text.PrettyPrint
|
|
||||||
|
|
||||||
import PGF2
|
|
||||||
import qualified PGF as H
|
|
||||||
import GF.Compile.ToAPI(exprToAPI)
|
|
||||||
import GF.Infra.UseIO(writeUTF8File)
|
|
||||||
import GF.Infra.SIO(MonadSIO,liftSIO,putStrLn,restricted,restrictedSystem)
|
|
||||||
import GF.Command.Abstract
|
|
||||||
import GF.Command.CommandInfo
|
|
||||||
import GF.Data.Operations
|
|
||||||
import Data.List(intersperse,intersect,nub,sortBy)
|
|
||||||
import Data.Maybe
|
|
||||||
import qualified Data.Map as Map
|
|
||||||
import GF.Text.Pretty
|
|
||||||
import Control.Monad(mplus)
|
|
||||||
|
|
||||||
|
|
||||||
data PGFEnv = Env {pgf::Maybe PGF,concs::Map.Map ConcName Concr}
|
|
||||||
|
|
||||||
pgfEnv pgf = Env (Just pgf) (languages pgf)
|
|
||||||
emptyPGFEnv = Env Nothing Map.empty
|
|
||||||
|
|
||||||
class (Monad m,MonadSIO m) => HasPGFEnv m where getPGFEnv :: m PGFEnv
|
|
||||||
|
|
||||||
instance (Monad m,HasPGFEnv m) => TypeCheckArg m where
|
|
||||||
typeCheckArg e = do env <- getPGFEnv
|
|
||||||
case pgf env of
|
|
||||||
Just gr -> either fail
|
|
||||||
(return . hsExpr . fst)
|
|
||||||
(inferExpr gr (cExpr e))
|
|
||||||
Nothing -> fail "Import a grammar before using this command"
|
|
||||||
|
|
||||||
pgfCommands :: HasPGFEnv m => Map.Map String (CommandInfo m)
|
|
||||||
pgfCommands = Map.fromList [
|
|
||||||
("aw", emptyCommandInfo {
|
|
||||||
longname = "align_words",
|
|
||||||
synopsis = "show word alignments between languages graphically",
|
|
||||||
explanation = unlines [
|
|
||||||
"Prints a set of strings in the .dot format (the graphviz format).",
|
|
||||||
"The graph can be saved in a file by the wf command as usual.",
|
|
||||||
"If the -view flag is defined, the graph is saved in a temporary file",
|
|
||||||
"which is processed by graphviz and displayed by the program indicated",
|
|
||||||
"by the flag. The target format is postscript, unless overridden by the",
|
|
||||||
"flag -format."
|
|
||||||
],
|
|
||||||
exec = needPGF $ \opts es env -> do
|
|
||||||
let cncs = optConcs env opts
|
|
||||||
if isOpt "giza" opts
|
|
||||||
then if length cncs == 2
|
|
||||||
then let giz = map (gizaAlignment pgf (snd (cncs !! 0)) (snd (cncs !! 1)) . cExpr) (toExprs es)
|
|
||||||
lsrc = unlines $ map (\(x,_,_) -> x) giz
|
|
||||||
ltrg = unlines $ map (\(_,x,_) -> x) giz
|
|
||||||
align = unlines $ map (\(_,_,x) -> x) giz
|
|
||||||
grph = if null (toExprs es) then [] else lsrc ++ "\n--end_source--\n\n"++ltrg++"\n-end_target--\n\n"++align
|
|
||||||
in return (fromString grph)
|
|
||||||
else error "For giza alignment you need exactly two languages"
|
|
||||||
else let gvOptions=graphvizDefaults{leafFont = valStrOpts "font" "" opts,
|
|
||||||
leafColor = valStrOpts "color" "" opts,
|
|
||||||
leafEdgeStyle = valStrOpts "edgestyle" "" opts
|
|
||||||
}
|
|
||||||
grph = if null (toExprs es) then [] else graphvizWordAlignment (map snd cncs) gvOptions (cExpr (head (toExprs es)))
|
|
||||||
in if isFlag "view" opts || isFlag "format" opts
|
|
||||||
then do let file s = "_grph." ++ s
|
|
||||||
let view = optViewGraph opts
|
|
||||||
let format = optViewFormat opts
|
|
||||||
restricted $ writeUTF8File (file "dot") grph
|
|
||||||
restrictedSystem $ "dot -T" ++ format ++ " " ++ file "dot" ++ " > " ++ file format
|
|
||||||
restrictedSystem $ view ++ " " ++ file format
|
|
||||||
return void
|
|
||||||
else return (fromString grph),
|
|
||||||
examples = [
|
|
||||||
("gr | aw" , "generate a tree and show word alignment as graph script"),
|
|
||||||
("gr | aw -view=\"open\"" , "generate a tree and display alignment on Mac"),
|
|
||||||
("gr | aw -view=\"eog\"" , "generate a tree and display alignment on Ubuntu"),
|
|
||||||
("gt | aw -giza | wf -file=aligns" , "generate trees, send giza alignments to file")
|
|
||||||
],
|
|
||||||
options = [
|
|
||||||
("giza", "show alignments in the Giza format; the first two languages")
|
|
||||||
],
|
|
||||||
flags = [
|
|
||||||
("format","format of the visualization file (default \"png\")"),
|
|
||||||
("lang", "alignments for this list of languages (default: all)"),
|
|
||||||
("view", "program to open the resulting file"),
|
|
||||||
("font", "font for the words"),
|
|
||||||
("color", "color for the words"),
|
|
||||||
("edgestyle", "the style for links between words")
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
{-
|
|
||||||
("eb", emptyCommandInfo {
|
|
||||||
longname = "example_based",
|
|
||||||
syntax = "eb (-probs=FILE | -lang=LANG)* -file=FILE.gfe",
|
|
||||||
synopsis = "converts .gfe files to .gf files by parsing examples to trees",
|
|
||||||
explanation = unlines [
|
|
||||||
"Reads FILE.gfe and writes FILE.gf. Each expression of form",
|
|
||||||
"'%ex CAT QUOTEDSTRING' in FILE.gfe is replaced by a syntax tree.",
|
|
||||||
"This tree is the first one returned by the parser; a biased ranking",
|
|
||||||
"can be used to regulate the order. If there are more than one parses",
|
|
||||||
"the rest are shown in comments, with probabilities if the order is biased.",
|
|
||||||
"The probabilities flag and configuration file is similar to the commands",
|
|
||||||
"gr and rt. Notice that the command doesn't change the environment,",
|
|
||||||
"but the resulting .gf file must be imported separately."
|
|
||||||
],
|
|
||||||
options = [
|
|
||||||
("api","convert trees to overloaded API expressions (using Syntax not Lang)")
|
|
||||||
],
|
|
||||||
flags = [
|
|
||||||
("file","the file to be converted (suffix .gfe must be given)"),
|
|
||||||
("lang","the language in which to parse"),
|
|
||||||
("probs","file with probabilities to rank the parses")
|
|
||||||
],
|
|
||||||
exec = \env@(pgf, mos) opts _ -> do
|
|
||||||
let file = optFile opts
|
|
||||||
pgf <- optProbs opts pgf
|
|
||||||
let printer = if (isOpt "api" opts) then exprToAPI else (H.showExpr [])
|
|
||||||
let conf = configureExBased pgf (optMorpho env opts) (optLang pgf opts) printer
|
|
||||||
(file',ws) <- restricted $ parseExamplesInGrammar conf file
|
|
||||||
if null ws then return () else putStrLn ("unknown words: " ++ unwords ws)
|
|
||||||
return (fromString ("wrote " ++ file')),
|
|
||||||
needsTypeCheck = False
|
|
||||||
}),
|
|
||||||
-}
|
|
||||||
{-
|
|
||||||
("gr", emptyCommandInfo {
|
|
||||||
longname = "generate_random",
|
|
||||||
synopsis = "generate random trees in the current abstract syntax",
|
|
||||||
syntax = "gr [-cat=CAT] [-number=INT]",
|
|
||||||
examples = [
|
|
||||||
mkEx "gr -- one tree in the startcat of the current grammar",
|
|
||||||
mkEx "gr -cat=NP -number=16 -- 16 trees in the category NP",
|
|
||||||
mkEx "gr -lang=LangHin,LangTha -cat=Cl -- Cl, both in LangHin and LangTha",
|
|
||||||
mkEx "gr -probs=FILE -- generate with bias",
|
|
||||||
mkEx "gr (AdjCN ? (UseN ?)) -- generate trees of form (AdjCN ? (UseN ?))"
|
|
||||||
],
|
|
||||||
explanation = unlines [
|
|
||||||
"Generates a list of random trees, by default one tree.",
|
|
||||||
"If a tree argument is given, the command completes the Tree with values to",
|
|
||||||
"all metavariables in the tree. The generation can be biased by probabilities,",
|
|
||||||
"given in a file in the -probs flag."
|
|
||||||
],
|
|
||||||
flags = [
|
|
||||||
("cat","generation category"),
|
|
||||||
("lang","uses only functions that have linearizations in all these languages"),
|
|
||||||
("number","number of trees generated"),
|
|
||||||
("depth","the maximum generation depth"),
|
|
||||||
("probs", "file with biased probabilities (format 'f 0.4' one by line)")
|
|
||||||
],
|
|
||||||
exec = \env@(pgf, mos) opts xs -> do
|
|
||||||
pgf <- optProbs opts (optRestricted opts pgf)
|
|
||||||
gen <- newStdGen
|
|
||||||
let dp = valIntOpts "depth" 4 opts
|
|
||||||
let ts = case mexp xs of
|
|
||||||
Just ex -> H.generateRandomFromDepth gen pgf ex (Just dp)
|
|
||||||
Nothing -> H.generateRandomDepth gen pgf (optType pgf opts) (Just dp)
|
|
||||||
returnFromExprs $ take (optNum opts) ts
|
|
||||||
}),
|
|
||||||
-}
|
|
||||||
("gt", emptyCommandInfo {
|
|
||||||
longname = "generate_trees",
|
|
||||||
synopsis = "generates a list of trees, by default exhaustive",
|
|
||||||
flags = [("cat","the generation category"),
|
|
||||||
("number","the number of trees generated")],
|
|
||||||
examples = [
|
|
||||||
mkEx "gt -- all trees in the startcat",
|
|
||||||
mkEx "gt -cat=NP -number=16 -- 16 trees in the category NP"],
|
|
||||||
exec = needPGF $ \ opts _ env@(pgf,_) ->
|
|
||||||
let ts = map fst (generateAll pgf cat)
|
|
||||||
cat = optType pgf opts
|
|
||||||
in returnFromCExprs (takeOptNum opts ts),
|
|
||||||
needsTypeCheck = False
|
|
||||||
}),
|
|
||||||
("i", emptyCommandInfo {
|
|
||||||
longname = "import",
|
|
||||||
synopsis = "import a grammar from a compiled .pgf file",
|
|
||||||
explanation = unlines [
|
|
||||||
"Reads a grammar from a compiled .pgf file.",
|
|
||||||
"Old modules are discarded.",
|
|
||||||
{-
|
|
||||||
"The grammar parser depends on the file name suffix:",
|
|
||||||
|
|
||||||
" .cf context-free (labelled BNF) source",
|
|
||||||
" .ebnf extended BNF source",
|
|
||||||
" .gfm multi-module GF source",
|
|
||||||
" .gf normal GF source",
|
|
||||||
" .gfo compiled GF source",
|
|
||||||
-}
|
|
||||||
" .pgf precompiled grammar in Portable Grammar Format"
|
|
||||||
],
|
|
||||||
flags = [
|
|
||||||
-- ("probs","file with biased probabilities for generation")
|
|
||||||
],
|
|
||||||
options = [
|
|
||||||
-- ["gfo", "src", "no-cpu", "cpu", "quiet", "verbose"]
|
|
||||||
-- ("retain","retain operations (used for cc command)"),
|
|
||||||
-- ("src", "force compilation from source"),
|
|
||||||
-- ("v", "be verbose - show intermediate status information")
|
|
||||||
],
|
|
||||||
needsTypeCheck = False
|
|
||||||
}),
|
|
||||||
("l", emptyCommandInfo {
|
|
||||||
longname = "linearize",
|
|
||||||
synopsis = "convert an abstract syntax expression to string",
|
|
||||||
explanation = unlines [
|
|
||||||
"Shows the linearization of a Tree by the grammars in scope.",
|
|
||||||
"The -lang flag can be used to restrict this to fewer languages.",
|
|
||||||
"A sequence of string operations (see command ps) can be given",
|
|
||||||
"as options, and works then like a pipe to the ps command, except",
|
|
||||||
"that it only affect the strings, not e.g. the table labels.",
|
|
||||||
"These can be given separately to each language with the unlexer flag",
|
|
||||||
"whose results are prepended to the other lexer flags. The value of the",
|
|
||||||
"unlexer flag is a space-separated list of comma-separated string operation",
|
|
||||||
"sequences; see example."
|
|
||||||
],
|
|
||||||
examples = [
|
|
||||||
mkEx "l -lang=LangSwe,LangNor no_Utt -- linearize a tree to LangSwe and LangNor",
|
|
||||||
mkEx "gr -lang=LangHin -cat=Cl | l -table -to_devanagari -- hindi table",
|
|
||||||
mkEx "l -unlexer=\"LangAra=to_arabic LangHin=to_devanagari\" -- different unlexers"
|
|
||||||
],
|
|
||||||
exec = needPGF $ \ opts arg env ->
|
|
||||||
return . fromStrings . optLins env opts . map cExpr $ toExprs arg,
|
|
||||||
options = [
|
|
||||||
("all", "show all forms and variants, one by line (cf. l -list)"),
|
|
||||||
("bracket","show tree structure with brackets and paths to nodes"),
|
|
||||||
("groups", "all languages, grouped by lang, remove duplicate strings"),
|
|
||||||
("list","show all forms and variants, comma-separated on one line (cf. l -all)"),
|
|
||||||
("multi","linearize to all languages (default)"),
|
|
||||||
("table","show all forms labelled by parameters"),
|
|
||||||
("treebank","show the tree and tag linearizations with language names")
|
|
||||||
],
|
|
||||||
flags = [
|
|
||||||
("lang","the languages of linearization (comma-separated, no spaces)")
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
("ma", emptyCommandInfo {
|
|
||||||
longname = "morpho_analyse",
|
|
||||||
synopsis = "print the morphological analyses of the (multiword) expression in the string",
|
|
||||||
explanation = unlines [
|
|
||||||
"Prints all the analyses of the (multiword) expression in the input string,",
|
|
||||||
"using the morphological analyser of the actual grammar (see command pg)"
|
|
||||||
],
|
|
||||||
exec = needPGF $ \opts args env ->
|
|
||||||
return ((fromString . unlines .
|
|
||||||
map prMorphoAnalysis . concatMap (morphos env opts) . toStrings) args),
|
|
||||||
flags = [
|
|
||||||
("lang","the languages of analysis (comma-separated, no spaces)")
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
{-
|
|
||||||
("mq", emptyCommandInfo {
|
|
||||||
longname = "morpho_quiz",
|
|
||||||
synopsis = "start a morphology quiz",
|
|
||||||
syntax = "mq (-cat=CAT)? (-probs=FILE)? TREE?",
|
|
||||||
exec = \env@(pgf, mos) opts xs -> do
|
|
||||||
let lang = optLang pgf opts
|
|
||||||
let typ = optType pgf opts
|
|
||||||
pgf <- optProbs opts pgf
|
|
||||||
let mt = mexp xs
|
|
||||||
restricted $ morphologyQuiz mt pgf lang typ
|
|
||||||
return void,
|
|
||||||
flags = [
|
|
||||||
("lang","language of the quiz"),
|
|
||||||
("cat","category of the quiz"),
|
|
||||||
("number","maximum number of questions"),
|
|
||||||
("probs","file with biased probabilities for generation")
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
-}
|
|
||||||
("p", emptyCommandInfo {
|
|
||||||
longname = "parse",
|
|
||||||
synopsis = "parse a string to abstract syntax expression",
|
|
||||||
explanation = unlines [
|
|
||||||
"Shows all trees returned by parsing a string in the grammars in scope.",
|
|
||||||
"The -lang flag can be used to restrict this to fewer languages.",
|
|
||||||
"The default start category can be overridden by the -cat flag.",
|
|
||||||
"See also the ps command for lexing and character encoding."
|
|
||||||
],
|
|
||||||
flags = [
|
|
||||||
("cat","target category of parsing"),
|
|
||||||
("lang","the languages of parsing (comma-separated, no spaces)"),
|
|
||||||
("number","maximum number of trees returned")
|
|
||||||
],
|
|
||||||
examples = [
|
|
||||||
mkEx "p \"this fish is fresh\" | l -lang=Swe -- try parsing with all languages and translate the successful parses to Swedish"
|
|
||||||
],
|
|
||||||
exec = needPGF $ \ opts ts env -> return . cParse env opts $ toStrings ts
|
|
||||||
}),
|
|
||||||
("pg", emptyCommandInfo {
|
|
||||||
longname = "print_grammar",
|
|
||||||
synopsis = "prints different information about the grammar",
|
|
||||||
exec = needPGF $ \opts _ env -> prGrammar env opts,
|
|
||||||
options = [
|
|
||||||
("cats", "show just the names of abstract syntax categories"),
|
|
||||||
("fullform", "print the fullform lexicon"),
|
|
||||||
("funs", "show just the names and types of abstract syntax functions"),
|
|
||||||
("langs", "show just the names of top concrete syntax modules"),
|
|
||||||
("lexc", "print the lexicon in Xerox LEXC format"),
|
|
||||||
("missing","show just the names of functions that have no linearization"),
|
|
||||||
("words", "print the list of words")
|
|
||||||
],
|
|
||||||
flags = [
|
|
||||||
("lang","the languages that need to be printed")
|
|
||||||
],
|
|
||||||
examples = [
|
|
||||||
mkEx "pg -langs -- show the names of top concrete syntax modules",
|
|
||||||
mkEx "pg -funs | ? grep \" S ;\" -- show functions with value cat S"
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
|
|
||||||
{-
|
|
||||||
("pt", emptyCommandInfo {
|
|
||||||
longname = "put_tree",
|
|
||||||
syntax = "pt OPT? TREE",
|
|
||||||
synopsis = "return a tree, possibly processed with a function",
|
|
||||||
explanation = unlines [
|
|
||||||
"Returns a tree obtained from its argument tree by applying",
|
|
||||||
"tree processing functions in the order given in the command line",
|
|
||||||
"option list. Thus 'pt -f -g s' returns g (f s). Typical tree processors",
|
|
||||||
"are type checking and semantic computation."
|
|
||||||
],
|
|
||||||
examples = [
|
|
||||||
mkEx "pt -compute (plus one two) -- compute value",
|
|
||||||
mkEx "p \"4 dogs love 5 cats\" | pt -transfer=digits2numeral | l -- four...five..."
|
|
||||||
],
|
|
||||||
exec = \env@(pgf, mos) opts ->
|
|
||||||
returnFromExprs . takeOptNum opts . treeOps pgf opts,
|
|
||||||
options = treeOpOptions undefined{-pgf-},
|
|
||||||
flags = [("number","take at most this many trees")] ++ treeOpFlags undefined{-pgf-}
|
|
||||||
}),
|
|
||||||
-}
|
|
||||||
("rf", emptyCommandInfo {
|
|
||||||
longname = "read_file",
|
|
||||||
synopsis = "read string or tree input from a file",
|
|
||||||
explanation = unlines [
|
|
||||||
"Reads input from file. The filename must be in double quotes.",
|
|
||||||
"The input is interpreted as a string by default, and can hence be",
|
|
||||||
"piped e.g. to the parse command. The option -tree interprets the",
|
|
||||||
"input as a tree, which can be given e.g. to the linearize command.",
|
|
||||||
"The option -lines will result in a list of strings or trees, one by line."
|
|
||||||
],
|
|
||||||
options = [
|
|
||||||
("lines","return the list of lines, instead of the singleton of all contents"),
|
|
||||||
("tree","convert strings into trees")
|
|
||||||
],
|
|
||||||
exec = needPGF $ \opts _ env@(pgf, mos) -> do
|
|
||||||
let file = optFile opts
|
|
||||||
let exprs [] = ([],empty)
|
|
||||||
exprs ((n,s):ls) | null s
|
|
||||||
= exprs ls
|
|
||||||
exprs ((n,s):ls) = case readExpr s of
|
|
||||||
Just e -> let (es,err) = exprs ls
|
|
||||||
in case inferExpr pgf e of
|
|
||||||
Right (e,t) -> (e:es,err)
|
|
||||||
Left msg -> (es,"on line" <+> n <> ':' $$ msg $$ err)
|
|
||||||
Nothing -> let (es,err) = exprs ls
|
|
||||||
in (es,"on line" <+> n <> ':' <+> "parse error" $$ err)
|
|
||||||
returnFromLines ls = case exprs ls of
|
|
||||||
(es, err) | null es -> return $ pipeMessage $ render (err $$ "no trees found")
|
|
||||||
| otherwise -> return $ pipeWithMessage (map hsExpr es) (render err)
|
|
||||||
|
|
||||||
s <- restricted $ readFile file
|
|
||||||
case opts of
|
|
||||||
_ | isOpt "lines" opts && isOpt "tree" opts ->
|
|
||||||
returnFromLines (zip [1::Int ..] (lines s))
|
|
||||||
_ | isOpt "tree" opts ->
|
|
||||||
returnFromLines [(1::Int,s)]
|
|
||||||
_ | isOpt "lines" opts -> return (fromStrings $ lines s)
|
|
||||||
_ -> return (fromString s),
|
|
||||||
flags = [("file","the input file name")]
|
|
||||||
}),
|
|
||||||
("rt", emptyCommandInfo {
|
|
||||||
longname = "rank_trees",
|
|
||||||
synopsis = "show trees in an order of decreasing probability",
|
|
||||||
explanation = unlines [
|
|
||||||
"Order trees from the most to the least probable, using either",
|
|
||||||
"even distribution in each category (default) or biased as specified",
|
|
||||||
"by the file given by flag -probs=FILE, where each line has the form",
|
|
||||||
"'function probability', e.g. 'youPol_Pron 0.01'."
|
|
||||||
],
|
|
||||||
exec = needPGF $ \opts es env@(pgf, _) -> do
|
|
||||||
let tds = sortBy (\(_,p) (_,q) -> compare p q)
|
|
||||||
[(t, treeProbability pgf t) | t <- map cExpr (toExprs es)]
|
|
||||||
if isOpt "v" opts
|
|
||||||
then putStrLn $
|
|
||||||
unlines [PGF2.showExpr [] t ++ "\t--" ++ show d | (t,d) <- tds]
|
|
||||||
else return ()
|
|
||||||
returnFromExprs $ map (hsExpr . fst) tds,
|
|
||||||
flags = [
|
|
||||||
("probs","probabilities from this file (format 'f 0.6' per line)")
|
|
||||||
],
|
|
||||||
options = [
|
|
||||||
("v","show all trees with their probability scores")
|
|
||||||
],
|
|
||||||
examples = [
|
|
||||||
mkEx "p \"you are here\" | rt -probs=probs | pt -number=1 -- most probable result"
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
{-
|
|
||||||
("tq", emptyCommandInfo {
|
|
||||||
longname = "translation_quiz",
|
|
||||||
syntax = "tq -from=LANG -to=LANG (-cat=CAT)? (-probs=FILE)? TREE?",
|
|
||||||
synopsis = "start a translation quiz",
|
|
||||||
exec = \env@(pgf, mos) opts xs -> do
|
|
||||||
let from = optLangFlag "from" pgf opts
|
|
||||||
let to = optLangFlag "to" pgf opts
|
|
||||||
let typ = optType pgf opts
|
|
||||||
let mt = mexp xs
|
|
||||||
pgf <- optProbs opts pgf
|
|
||||||
restricted $ translationQuiz mt pgf from to typ
|
|
||||||
return void,
|
|
||||||
flags = [
|
|
||||||
("from","translate from this language"),
|
|
||||||
("to","translate to this language"),
|
|
||||||
("cat","translate in this category"),
|
|
||||||
("number","the maximum number of questions"),
|
|
||||||
("probs","file with biased probabilities for generation")
|
|
||||||
],
|
|
||||||
examples = [
|
|
||||||
mkEx ("tq -from=Eng -to=Swe -- any trees in startcat"),
|
|
||||||
mkEx ("tq -from=Eng -to=Swe (AdjCN (PositA ?2) (UseN ?)) -- only trees of this form")
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
("vd", emptyCommandInfo {
|
|
||||||
longname = "visualize_dependency",
|
|
||||||
synopsis = "show word dependency tree graphically",
|
|
||||||
explanation = unlines [
|
|
||||||
"Prints a dependency tree in the .dot format (the graphviz format, default)",
|
|
||||||
"or the CoNLL/MaltParser format (flag -output=conll for training, malt_input",
|
|
||||||
"for unanalysed input).",
|
|
||||||
"By default, the last argument is the head of every abstract syntax",
|
|
||||||
"function; moreover, the head depends on the head of the function above.",
|
|
||||||
"The graph can be saved in a file by the wf command as usual.",
|
|
||||||
"If the -view flag is defined, the graph is saved in a temporary file",
|
|
||||||
"which is processed by graphviz and displayed by the program indicated",
|
|
||||||
"by the flag. The target format is png, unless overridden by the",
|
|
||||||
"flag -format."
|
|
||||||
],
|
|
||||||
exec = \env@(pgf, mos) opts es -> do
|
|
||||||
let debug = isOpt "v" opts
|
|
||||||
let file = valStrOpts "file" "" opts
|
|
||||||
let outp = valStrOpts "output" "dot" opts
|
|
||||||
mlab <- case file of
|
|
||||||
"" -> return Nothing
|
|
||||||
_ -> (Just . H.getDepLabels . lines) `fmap` restricted (readFile file)
|
|
||||||
let lang = optLang pgf opts
|
|
||||||
let grphs = unlines $ map (H.graphvizDependencyTree outp debug mlab Nothing pgf lang) es
|
|
||||||
if isFlag "view" opts || isFlag "format" opts then do
|
|
||||||
let file s = "_grphd." ++ s
|
|
||||||
let view = optViewGraph opts
|
|
||||||
let format = optViewFormat opts
|
|
||||||
restricted $ writeUTF8File (file "dot") grphs
|
|
||||||
restrictedSystem $ "dot -T" ++ format ++ " " ++ file "dot" ++ " > " ++ file format
|
|
||||||
restrictedSystem $ view ++ " " ++ file format
|
|
||||||
return void
|
|
||||||
else return $ fromString grphs,
|
|
||||||
examples = [
|
|
||||||
mkEx "gr | vd -- generate a tree and show dependency tree in .dot",
|
|
||||||
mkEx "gr | vd -view=open -- generate a tree and display dependency tree on a Mac",
|
|
||||||
mkEx "gr -number=1000 | vd -file=dep.labels -output=malt -- generate training treebank",
|
|
||||||
mkEx "gr -number=100 | vd -file=dep.labels -output=malt_input -- generate test sentences"
|
|
||||||
],
|
|
||||||
options = [
|
|
||||||
("v","show extra information")
|
|
||||||
],
|
|
||||||
flags = [
|
|
||||||
("file","configuration file for labels per fun, format 'fun l1 ... label ... l2'"),
|
|
||||||
("format","format of the visualization file (default \"png\")"),
|
|
||||||
("output","output format of graph source (default \"dot\")"),
|
|
||||||
("view","program to open the resulting file (default \"open\")"),
|
|
||||||
("lang","the language of analysis")
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
-}
|
|
||||||
|
|
||||||
("vp", emptyCommandInfo {
|
|
||||||
longname = "visualize_parse",
|
|
||||||
synopsis = "show parse tree graphically",
|
|
||||||
explanation = unlines [
|
|
||||||
"Prints a parse tree in the .dot format (the graphviz format).",
|
|
||||||
"The graph can be saved in a file by the wf command as usual.",
|
|
||||||
"If the -view flag is defined, the graph is saved in a temporary file",
|
|
||||||
"which is processed by graphviz and displayed by the program indicated",
|
|
||||||
"by the flag. The target format is png, unless overridden by the",
|
|
||||||
"flag -format."
|
|
||||||
],
|
|
||||||
exec = needPGF $ \opts arg env@(pgf, concs) ->
|
|
||||||
do let es = toExprs arg
|
|
||||||
let concs = optConcs env opts
|
|
||||||
|
|
||||||
let gvOptions=graphvizDefaults{noLeaves = isOpt "noleaves" opts && not (isOpt "showleaves" opts),
|
|
||||||
noFun = isOpt "nofun" opts || not (isOpt "showfun" opts),
|
|
||||||
noCat = isOpt "nocat" opts && not (isOpt "showcat" opts),
|
|
||||||
nodeFont = valStrOpts "nodefont" "" opts,
|
|
||||||
leafFont = valStrOpts "leaffont" "" opts,
|
|
||||||
nodeColor = valStrOpts "nodecolor" "" opts,
|
|
||||||
leafColor = valStrOpts "leafcolor" "" opts,
|
|
||||||
nodeEdgeStyle = valStrOpts "nodeedgestyle" "solid" opts,
|
|
||||||
leafEdgeStyle = valStrOpts "leafedgestyle" "dashed" opts
|
|
||||||
}
|
|
||||||
|
|
||||||
let grph= if null es || null concs
|
|
||||||
then []
|
|
||||||
else graphvizParseTree (snd (head concs)) gvOptions (cExpr (head es))
|
|
||||||
if isFlag "view" opts || isFlag "format" opts then do
|
|
||||||
let file s = "_grph." ++ s
|
|
||||||
let view = optViewGraph opts
|
|
||||||
let format = optViewFormat opts
|
|
||||||
restricted $ writeUTF8File (file "dot") grph
|
|
||||||
restrictedSystem $ "dot -T" ++ format ++ " " ++ file "dot" ++ " > " ++ file format
|
|
||||||
restrictedSystem $ view ++ " " ++ file format
|
|
||||||
return void
|
|
||||||
else return $ fromString grph,
|
|
||||||
examples = [
|
|
||||||
mkEx "p -lang=Eng \"John walks\" | vp -- generate a tree and show parse tree as .dot script",
|
|
||||||
mkEx "gr | vp -view=\"open\" -- generate a tree and display parse tree on a Mac"
|
|
||||||
],
|
|
||||||
options = [
|
|
||||||
("showcat","show categories in the tree nodes (default)"),
|
|
||||||
("nocat","don't show categories"),
|
|
||||||
("showfun","show function names in the tree nodes"),
|
|
||||||
("nofun","don't show function names (default)"),
|
|
||||||
("showleaves","show the leaves of the tree (default)"),
|
|
||||||
("noleaves","don't show the leaves of the tree (i.e., only the abstract tree)")
|
|
||||||
],
|
|
||||||
flags = [
|
|
||||||
("lang","the language to visualize"),
|
|
||||||
("format","format of the visualization file (default \"png\")"),
|
|
||||||
("view","program to open the resulting file (default \"open\")"),
|
|
||||||
("nodefont","font for tree nodes (default: Times -- graphviz standard font)"),
|
|
||||||
("leaffont","font for tree leaves (default: nodefont)"),
|
|
||||||
("nodecolor","color for tree nodes (default: black -- graphviz standard color)"),
|
|
||||||
("leafcolor","color for tree leaves (default: nodecolor)"),
|
|
||||||
("nodeedgestyle","edge style between tree nodes (solid/dashed/dotted/bold, default: solid)"),
|
|
||||||
("leafedgestyle","edge style for links to leaves (solid/dashed/dotted/bold, default: dashed)")
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
|
|
||||||
("vt", emptyCommandInfo {
|
|
||||||
longname = "visualize_tree",
|
|
||||||
synopsis = "show a set of trees graphically",
|
|
||||||
explanation = unlines [
|
|
||||||
"Prints a set of trees in the .dot format (the graphviz format).",
|
|
||||||
"The graph can be saved in a file by the wf command as usual.",
|
|
||||||
"If the -view flag is defined, the graph is saved in a temporary file",
|
|
||||||
"which is processed by graphviz and displayed by the program indicated",
|
|
||||||
"by the flag. The target format is postscript, unless overridden by the",
|
|
||||||
"flag -format."
|
|
||||||
],
|
|
||||||
exec = needPGF $ \opts arg env@(pgf, _) ->
|
|
||||||
let es = toExprs arg in
|
|
||||||
if isOpt "api" opts
|
|
||||||
then do
|
|
||||||
mapM_ (putStrLn . exprToAPI) es
|
|
||||||
return void
|
|
||||||
else do
|
|
||||||
let gvOptions=graphvizDefaults{noFun = isOpt "nofun" opts,
|
|
||||||
noCat = isOpt "nocat" opts,
|
|
||||||
nodeFont = valStrOpts "nodefont" "" opts,
|
|
||||||
nodeColor = valStrOpts "nodecolor" "" opts,
|
|
||||||
nodeEdgeStyle = valStrOpts "nodeedgestyle" "solid" opts
|
|
||||||
}
|
|
||||||
let grph = unlines (map (graphvizAbstractTree pgf gvOptions . cExpr) es)
|
|
||||||
if isFlag "view" opts || isFlag "format" opts then do
|
|
||||||
let file s = "_grph." ++ s
|
|
||||||
let view = optViewGraph opts
|
|
||||||
let format = optViewFormat opts
|
|
||||||
restricted $ writeUTF8File (file "dot") grph
|
|
||||||
restrictedSystem $ "dot -T" ++ format ++ " " ++ file "dot" ++ " > " ++ file format
|
|
||||||
restrictedSystem $ view ++ " " ++ file format
|
|
||||||
return void
|
|
||||||
else return $ fromString grph,
|
|
||||||
examples = [
|
|
||||||
mkEx "p \"hello\" | vt -- parse a string and show trees as graph script",
|
|
||||||
mkEx "p \"hello\" | vt -view=\"open\" -- parse a string and display trees on a Mac"
|
|
||||||
],
|
|
||||||
options = [
|
|
||||||
("api", "show the tree with function names converted to 'mkC' with value cats C"),
|
|
||||||
("nofun","don't show functions but only categories"),
|
|
||||||
("nocat","don't show categories but only functions")
|
|
||||||
],
|
|
||||||
flags = [
|
|
||||||
("format","format of the visualization file (default \"png\")"),
|
|
||||||
("view","program to open the resulting file (default \"open\")"),
|
|
||||||
("nodefont","font for tree nodes (default: Times -- graphviz standard font)"),
|
|
||||||
("nodecolor","color for tree nodes (default: black -- graphviz standard color)"),
|
|
||||||
("nodeedgestyle","edge style between tree nodes (solid/dashed/dotted/bold, default: solid)")
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
|
|
||||||
("ai", emptyCommandInfo {
|
|
||||||
longname = "abstract_info",
|
|
||||||
syntax = "ai IDENTIFIER or ai EXPR",
|
|
||||||
synopsis = "Provides an information about a function, an expression or a category from the abstract syntax",
|
|
||||||
explanation = unlines [
|
|
||||||
"The command has one argument which is either function, expression or",
|
|
||||||
"a category defined in the abstract syntax of the current grammar. ",
|
|
||||||
"If the argument is a function then its type is printed out.",
|
|
||||||
"If it is a category then the category definition is printed.",
|
|
||||||
"If a whole expression is given it prints the expression with refined",
|
|
||||||
"metavariables and the type of the expression."
|
|
||||||
],
|
|
||||||
exec = needPGF $ \opts args env@(pgf,cncs) ->
|
|
||||||
case map cExpr (toExprs args) of
|
|
||||||
[e] -> case unApp e of
|
|
||||||
Just (id,[]) -> return (fromString
|
|
||||||
(case functionType pgf id of
|
|
||||||
Just ty -> showFun id ty
|
|
||||||
Nothing -> let funs = functionsByCat pgf id
|
|
||||||
in showCat id funs))
|
|
||||||
where
|
|
||||||
showCat c funs = "cat "++c++
|
|
||||||
" ;\n\n"++
|
|
||||||
unlines [showFun f ty| f<-funs,
|
|
||||||
Just ty <- [functionType pgf f]]
|
|
||||||
showFun f ty = "fun "++f++" : "++showType [] ty++" ;"
|
|
||||||
_ -> case inferExpr pgf e of
|
|
||||||
Left msg -> error msg
|
|
||||||
Right (e,ty) -> do putStrLn ("Expression: "++PGF2.showExpr [] e)
|
|
||||||
putStrLn ("Type: "++PGF2.showType [] ty)
|
|
||||||
putStrLn ("Probability: "++show (treeProbability pgf e))
|
|
||||||
return void
|
|
||||||
_ -> do putStrLn "a single function name or category name is expected"
|
|
||||||
return void,
|
|
||||||
needsTypeCheck = False
|
|
||||||
})
|
|
||||||
]
|
|
||||||
where
|
|
||||||
cParse env@(pgf,_) opts ss =
|
|
||||||
parsed [ parse cnc cat s | s<-ss,(lang,cnc)<-cncs]
|
|
||||||
where
|
|
||||||
cat = optType pgf opts
|
|
||||||
cncs = optConcs env opts
|
|
||||||
parsed rs = Piped (Exprs ts,unlines msgs)
|
|
||||||
where
|
|
||||||
ts = [hsExpr t|ParseOk ts<-rs,(t,p)<-takeOptNum opts ts]
|
|
||||||
msgs = concatMap mkMsg rs
|
|
||||||
|
|
||||||
mkMsg (ParseOk ts) = (map (PGF2.showExpr [] . fst).takeOptNum opts) ts
|
|
||||||
mkMsg (ParseFailed _ tok) = ["Parse failed: "++tok]
|
|
||||||
mkMsg (ParseIncomplete) = ["The sentence is incomplete"]
|
|
||||||
|
|
||||||
optLins env opts ts = case opts of
|
|
||||||
_ | isOpt "groups" opts ->
|
|
||||||
concatMap snd $ groupResults
|
|
||||||
[[(lang, s) | (lang,concr) <- optConcs env opts,s <- linear opts lang concr t] | t <- ts]
|
|
||||||
_ -> concatMap (optLin env opts) ts
|
|
||||||
optLin env@(pgf,_) opts t =
|
|
||||||
case opts of
|
|
||||||
_ | isOpt "treebank" opts ->
|
|
||||||
(abstractName pgf ++ ": " ++ PGF2.showExpr [] t) :
|
|
||||||
[lang ++ ": " ++ s | (lang,concr) <- optConcs env opts, s<-linear opts lang concr t]
|
|
||||||
_ -> [s | (lang,concr) <- optConcs env opts, s<-linear opts lang concr t]
|
|
||||||
|
|
||||||
linear :: [Option] -> ConcName -> Concr -> PGF2.Expr -> [String]
|
|
||||||
linear opts lang concr = case opts of
|
|
||||||
_ | isOpt "all" opts -> concat . map (map snd) . tabularLinearizeAll concr
|
|
||||||
_ | isOpt "list" opts -> (:[]) . commaList .
|
|
||||||
concatMap (map snd) . tabularLinearizeAll concr
|
|
||||||
_ | isOpt "table" opts -> concatMap (map (\(p,v) -> p+++":"+++v)) . tabularLinearizeAll concr
|
|
||||||
_ | isOpt "bracket" opts -> (:[]) . unwords . map showBracketedString . bracketedLinearize concr
|
|
||||||
_ -> (:[]) . linearize concr
|
|
||||||
|
|
||||||
groupResults :: [[(ConcName,String)]] -> [(ConcName,[String])]
|
|
||||||
groupResults = Map.toList . foldr more Map.empty . start . concat
|
|
||||||
where
|
|
||||||
start ls = [(l,[s]) | (l,s) <- ls]
|
|
||||||
more (l,s) =
|
|
||||||
Map.insertWith (\ [x] xs -> if elem x xs then xs else (x : xs)) l s
|
|
||||||
|
|
||||||
optConcs = optConcsFlag "lang"
|
|
||||||
|
|
||||||
optConcsFlag f (pgf,cncs) opts =
|
|
||||||
case valStrOpts f "" opts of
|
|
||||||
"" -> Map.toList cncs
|
|
||||||
lang -> mapMaybe pickLang (chunks ',' lang)
|
|
||||||
where
|
|
||||||
pickLang l = pick l `mplus` pick fl
|
|
||||||
where
|
|
||||||
fl = abstractName pgf++l
|
|
||||||
pick l = (,) l `fmap` Map.lookup l cncs
|
|
||||||
|
|
||||||
{-
|
|
||||||
-- replace each non-atomic constructor with mkC, where C is the val cat
|
|
||||||
tree2mk pgf = H.showExpr [] . t2m where
|
|
||||||
t2m t = case H.unApp t of
|
|
||||||
Just (cid,ts@(_:_)) -> H.mkApp (mk cid) (map t2m ts)
|
|
||||||
_ -> t
|
|
||||||
mk = H.mkCId . ("mk" ++) . H.showCId . H.lookValCat (H.abstract pgf)
|
|
||||||
|
|
||||||
unlex opts lang = stringOps Nothing (getUnlex opts lang ++ map prOpt opts) ----
|
|
||||||
|
|
||||||
getUnlex opts lang = case words (valStrOpts "unlexer" "" opts) of
|
|
||||||
lexs -> case lookup lang
|
|
||||||
[(H.mkCId la,tail le) | lex <- lexs, let (la,le) = span (/='=') lex, not (null le)] of
|
|
||||||
Just le -> chunks ',' le
|
|
||||||
_ -> []
|
|
||||||
-}
|
|
||||||
commaList [] = []
|
|
||||||
commaList ws = concat $ head ws : map (", " ++) (tail ws)
|
|
||||||
|
|
||||||
optFile opts = valStrOpts "file" "_gftmp" opts
|
|
||||||
|
|
||||||
optType pgf opts =
|
|
||||||
case listFlags "cat" opts of
|
|
||||||
v:_ -> let str = valueString v
|
|
||||||
in case readType str of
|
|
||||||
Just ty -> case checkType pgf ty of
|
|
||||||
Left msg -> error msg
|
|
||||||
Right ty -> ty
|
|
||||||
Nothing -> error ("Can't parse '"++str++"' as a type")
|
|
||||||
_ -> startCat pgf
|
|
||||||
|
|
||||||
optViewFormat opts = valStrOpts "format" "png" opts
|
|
||||||
optViewGraph opts = valStrOpts "view" "open" opts
|
|
||||||
{-
|
|
||||||
optNum opts = valIntOpts "number" 1 opts
|
|
||||||
-}
|
|
||||||
optNumInf opts = valIntOpts "number" 1000000000 opts ---- 10^9
|
|
||||||
takeOptNum opts = take (optNumInf opts)
|
|
||||||
|
|
||||||
returnFromCExprs = returnFromExprs . map hsExpr
|
|
||||||
returnFromExprs es =
|
|
||||||
return $ case es of
|
|
||||||
[] -> pipeMessage "no trees found"
|
|
||||||
_ -> fromExprs es
|
|
||||||
|
|
||||||
prGrammar env@(pgf,cncs) opts
|
|
||||||
| isOpt "langs" opts = return . fromString . unwords $ (map fst (optConcs env opts))
|
|
||||||
| isOpt "cats" opts = return . fromString . unwords $ categories pgf
|
|
||||||
| isOpt "funs" opts = return . fromString . unwords $ functions pgf
|
|
||||||
| isOpt "missing" opts = return . fromString . unwords $
|
|
||||||
[f | f <- functions pgf, not (and [hasLinearization concr f | (_,concr) <- optConcs env opts])]
|
|
||||||
| isOpt "fullform" opts = return $ fromString $ concatMap (prFullFormLexicon . snd) $ optConcs env opts
|
|
||||||
| isOpt "words" opts = return $ fromString $ concatMap (prAllWords . snd) $ optConcs env opts
|
|
||||||
| isOpt "lexc" opts = return $ fromString $ concatMap (prLexcLexicon . snd) $ optConcs env opts
|
|
||||||
| otherwise = return void
|
|
||||||
|
|
||||||
gizaAlignment pgf src_cnc tgt_cnc e =
|
|
||||||
let src_res = alignWords src_cnc e
|
|
||||||
tgt_res = alignWords tgt_cnc e
|
|
||||||
alignment = [show i++"-"++show j | (i,(_,src_fids)) <- zip [0..] src_res, (j,(_,tgt_fids)) <- zip [0..] tgt_res, not (null (intersect src_fids tgt_fids))]
|
|
||||||
in (unwords (map fst src_res), unwords (map fst tgt_res), unwords alignment)
|
|
||||||
|
|
||||||
morphos env opts s =
|
|
||||||
[(s,res) | (lang,concr) <- optConcs env opts, let res = lookupMorpho concr s, not (null res)]
|
|
||||||
{-
|
|
||||||
mexp xs = case xs of
|
|
||||||
t:_ -> Just t
|
|
||||||
_ -> Nothing
|
|
||||||
-}
|
|
||||||
-- ps -f -g s returns g (f s)
|
|
||||||
{-
|
|
||||||
treeOps pgf opts s = foldr app s (reverse opts) where
|
|
||||||
app (OOpt op) | Just (Left f) <- treeOp pgf op = f
|
|
||||||
app (OFlag op (VId x)) | Just (Right f) <- treeOp pgf op = f (H.mkCId x)
|
|
||||||
app _ = id
|
|
||||||
|
|
||||||
treeOpOptions pgf = [(op,expl) | (op,(expl,Left _)) <- allTreeOps pgf]
|
|
||||||
treeOpFlags pgf = [(op,expl) | (op,(expl,Right _)) <- allTreeOps pgf]
|
|
||||||
|
|
||||||
translationQuiz :: Maybe H.Expr -> H.PGF -> H.Language -> H.Language -> H.Type -> IO ()
|
|
||||||
translationQuiz mex pgf ig og typ = do
|
|
||||||
tts <- translationList mex pgf ig og typ infinity
|
|
||||||
mkQuiz "Welcome to GF Translation Quiz." tts
|
|
||||||
|
|
||||||
morphologyQuiz :: Maybe H.Expr -> H.PGF -> H.Language -> H.Type -> IO ()
|
|
||||||
morphologyQuiz mex pgf ig typ = do
|
|
||||||
tts <- morphologyList mex pgf ig typ infinity
|
|
||||||
mkQuiz "Welcome to GF Morphology Quiz." tts
|
|
||||||
|
|
||||||
-- | the maximal number of precompiled quiz problems
|
|
||||||
infinity :: Int
|
|
||||||
infinity = 256
|
|
||||||
-}
|
|
||||||
prLexcLexicon :: Concr -> String
|
|
||||||
prLexcLexicon concr =
|
|
||||||
unlines $ "Multichar_Symbols":multichars:"":"LEXICON Root" : [prLexc l p ++ ":" ++ w ++ " # ;" | (w,lps) <- morpho, (l,p,_) <- lps] ++ ["END"]
|
|
||||||
where
|
|
||||||
morpho = fullFormLexicon concr
|
|
||||||
prLexc l p = l ++ concat (mkTags (words p))
|
|
||||||
mkTags p = case p of
|
|
||||||
"s":ws -> mkTags ws --- remove record field
|
|
||||||
ws -> map ('+':) ws
|
|
||||||
|
|
||||||
multichars = unwords $ nub $ concat [mkTags (words p) | (w,lps) <- morpho, (l,p,_) <- lps]
|
|
||||||
-- thick_A+(AAdj+Posit+Gen):thick's # ;
|
|
||||||
|
|
||||||
prFullFormLexicon :: Concr -> String
|
|
||||||
prFullFormLexicon concr =
|
|
||||||
unlines (map prMorphoAnalysis (fullFormLexicon concr))
|
|
||||||
|
|
||||||
prAllWords :: Concr -> String
|
|
||||||
prAllWords concr =
|
|
||||||
unwords [w | (w,_) <- fullFormLexicon concr]
|
|
||||||
|
|
||||||
prMorphoAnalysis :: (String,[MorphoAnalysis]) -> String
|
|
||||||
prMorphoAnalysis (w,lps) =
|
|
||||||
unlines (w:[fun ++ " : " ++ cat | (fun,cat,p) <- lps])
|
|
||||||
|
|
||||||
hsExpr c =
|
|
||||||
case unApp c of
|
|
||||||
Just (f,cs) -> H.mkApp (H.mkCId f) (map hsExpr cs)
|
|
||||||
_ -> case unStr c of
|
|
||||||
Just str -> H.mkStr str
|
|
||||||
_ -> error $ "GF.Command.Commands2.hsExpr "++show c
|
|
||||||
|
|
||||||
cExpr e =
|
|
||||||
case H.unApp e of
|
|
||||||
Just (f,es) -> mkApp (H.showCId f) (map cExpr es)
|
|
||||||
_ -> case H.unStr e of
|
|
||||||
Just str -> mkStr str
|
|
||||||
_ -> error $ "GF.Command.Commands2.cExpr "++show e
|
|
||||||
|
|
||||||
needPGF exec opts ts =
|
|
||||||
do Env mb_pgf cncs <- getPGFEnv
|
|
||||||
case mb_pgf of
|
|
||||||
Just pgf -> liftSIO $ exec opts ts (pgf,cncs)
|
|
||||||
_ -> fail "Import a grammar before using this command"
|
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
-- elsewhere
|
-- elsewhere
|
||||||
module GF.Command.CommonCommands where
|
module GF.Command.CommonCommands where
|
||||||
import Data.List(sort)
|
import Data.List(sort)
|
||||||
import Data.Char (isSpace)
|
|
||||||
import GF.Command.CommandInfo
|
import GF.Command.CommandInfo
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import GF.Infra.SIO
|
import GF.Infra.SIO
|
||||||
@@ -16,7 +15,7 @@ import GF.Text.Pretty
|
|||||||
import GF.Text.Transliterations
|
import GF.Text.Transliterations
|
||||||
import GF.Text.Lexing(stringOp,opInEnv)
|
import GF.Text.Lexing(stringOp,opInEnv)
|
||||||
|
|
||||||
import qualified PGF as H(showCId,showExpr,toATree,toTrie,Trie(..))
|
import PGF2(showExpr)
|
||||||
|
|
||||||
extend old new = Map.union (Map.fromList new) old -- Map.union is left-biased
|
extend old new = Map.union (Map.fromList new) old -- Map.union is left-biased
|
||||||
|
|
||||||
@@ -102,9 +101,7 @@ commonCommands = fmap (mapCommandExec liftSIO) $ Map.fromList [
|
|||||||
"To see transliteration tables, use command ut."
|
"To see transliteration tables, use command ut."
|
||||||
],
|
],
|
||||||
examples = [
|
examples = [
|
||||||
-- mkEx "l (EAdd 3 4) | ps -code -- linearize code-like output",
|
|
||||||
mkEx "l (EAdd 3 4) | ps -unlexcode -- linearize code-like output",
|
mkEx "l (EAdd 3 4) | ps -unlexcode -- linearize code-like output",
|
||||||
-- mkEx "ps -lexer=code | p -cat=Exp -- parse code-like input",
|
|
||||||
mkEx "ps -lexcode | p -cat=Exp -- parse code-like input",
|
mkEx "ps -lexcode | p -cat=Exp -- parse code-like input",
|
||||||
mkEx "gr -cat=QCl | l | ps -bind -- linearization output from LangFin",
|
mkEx "gr -cat=QCl | l | ps -bind -- linearization output from LangFin",
|
||||||
mkEx "ps -to_devanagari \"A-p\" -- show Devanagari in UTF8 terminal",
|
mkEx "ps -to_devanagari \"A-p\" -- show Devanagari in UTF8 terminal",
|
||||||
@@ -117,13 +114,11 @@ commonCommands = fmap (mapCommandExec liftSIO) $ Map.fromList [
|
|||||||
let (os,fs) = optsAndFlags opts
|
let (os,fs) = optsAndFlags opts
|
||||||
trans <- optTranslit opts
|
trans <- optTranslit opts
|
||||||
|
|
||||||
case opts of
|
if isOpt "lines" opts
|
||||||
_ | isOpt "lines" opts -> return $ fromStrings $ map (trans . stringOps (envFlag fs) (map prOpt os)) $ toStrings x
|
then return $ fromStrings $ map (trans . stringOps (envFlag fs) (map prOpt os)) $ toStrings x
|
||||||
_ | isOpt "paragraphs" opts -> return $ fromStrings $ map (trans . stringOps (envFlag fs) (map prOpt os)) $ toParagraphs $ toStrings x
|
else return ((fromString . trans . stringOps (envFlag fs) (map prOpt os) . toString) x),
|
||||||
_ -> return ((fromString . trans . stringOps (envFlag fs) (map prOpt os) . toString) x),
|
|
||||||
options = [
|
options = [
|
||||||
("lines","apply the operation separately to each input line, returning a list of lines"),
|
("lines","apply the operation separately to each input line, returning a list of lines")
|
||||||
("paragraphs","apply separately to each input paragraph (as separated by empty lines), returning a list of lines")
|
|
||||||
] ++
|
] ++
|
||||||
stringOpOptions,
|
stringOpOptions,
|
||||||
flags = [
|
flags = [
|
||||||
@@ -178,12 +173,6 @@ commonCommands = fmap (mapCommandExec liftSIO) $ Map.fromList [
|
|||||||
mkEx "gt | l | ? wc -- generate trees, linearize, and count words"
|
mkEx "gt | l | ? wc -- generate trees, linearize, and count words"
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
("tt", emptyCommandInfo {
|
|
||||||
longname = "to_trie",
|
|
||||||
syntax = "to_trie",
|
|
||||||
synopsis = "combine a list of trees into a trie",
|
|
||||||
exec = \ _ -> return . fromString . trie . toExprs
|
|
||||||
}),
|
|
||||||
("ut", emptyCommandInfo {
|
("ut", emptyCommandInfo {
|
||||||
longname = "unicode_table",
|
longname = "unicode_table",
|
||||||
synopsis = "show a transliteration table for a unicode character set",
|
synopsis = "show a transliteration table for a unicode character set",
|
||||||
@@ -231,7 +220,6 @@ envFlag fs =
|
|||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
|
|
||||||
stringOpOptions = sort $ [
|
stringOpOptions = sort $ [
|
||||||
("bind","bind tokens separated by Prelude.BIND, i.e. &+"),
|
|
||||||
("chars","lexer that makes every non-space character a token"),
|
("chars","lexer that makes every non-space character a token"),
|
||||||
("from_cp1251","decode from cp1251 (Cyrillic used in Bulgarian resource)"),
|
("from_cp1251","decode from cp1251 (Cyrillic used in Bulgarian resource)"),
|
||||||
("from_utf8","decode from utf8 (default)"),
|
("from_utf8","decode from utf8 (default)"),
|
||||||
@@ -256,27 +244,6 @@ stringOpOptions = sort $ [
|
|||||||
("to_" ++ p, "from GF " ++ n ++ " transliteration to unicode")] |
|
("to_" ++ p, "from GF " ++ n ++ " transliteration to unicode")] |
|
||||||
(p,n) <- transliterationPrintNames]
|
(p,n) <- transliterationPrintNames]
|
||||||
|
|
||||||
trie = render . pptss . H.toTrie . map H.toATree
|
|
||||||
where
|
|
||||||
pptss [ts] = "*"<+>nest 2 (ppts ts)
|
|
||||||
pptss tss = vcat [i<+>nest 2 (ppts ts)|(i,ts)<-zip [(1::Int)..] tss]
|
|
||||||
|
|
||||||
ppts = vcat . map ppt
|
|
||||||
|
|
||||||
ppt t =
|
|
||||||
case t of
|
|
||||||
H.Oth e -> pp (H.showExpr [] e)
|
|
||||||
H.Ap f [[]] -> pp (H.showCId f)
|
|
||||||
H.Ap f tss -> H.showCId f $$ nest 2 (pptss tss)
|
|
||||||
|
|
||||||
-- ** Converting command input
|
-- ** Converting command input
|
||||||
toString = unwords . toStrings
|
toString = unwords . toStrings
|
||||||
toLines = unlines . toStrings
|
toLines = unlines . toStrings
|
||||||
|
|
||||||
toParagraphs = map (unwords . words) . toParas
|
|
||||||
where
|
|
||||||
toParas ls = case break (all isSpace) ls of
|
|
||||||
([],[]) -> []
|
|
||||||
([],_:ll) -> toParas ll
|
|
||||||
(l, []) -> [unwords l]
|
|
||||||
(l, _:ll) -> unwords l : toParas ll
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
module GF.Command.Importing (importGrammar, importSource) where
|
module GF.Command.Importing (importGrammar, importSource) where
|
||||||
|
|
||||||
import PGF
|
import PGF2
|
||||||
import PGF.Internal(optimizePGF,unionPGF,msgUnionPGF)
|
import PGF2.Internal(unionPGF)
|
||||||
|
|
||||||
import GF.Compile
|
import GF.Compile
|
||||||
import GF.Compile.Multi (readMulti)
|
import GF.Compile.Multi (readMulti)
|
||||||
@@ -17,14 +17,16 @@ import GF.Data.ErrM
|
|||||||
|
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
|
import qualified Data.Map as Map
|
||||||
|
import Control.Monad(foldM)
|
||||||
|
|
||||||
-- import a grammar in an environment where it extends an existing grammar
|
-- import a grammar in an environment where it extends an existing grammar
|
||||||
importGrammar :: PGF -> Options -> [FilePath] -> IO PGF
|
importGrammar :: Maybe PGF -> Options -> [FilePath] -> IO (Maybe PGF)
|
||||||
importGrammar pgf0 _ [] = return pgf0
|
importGrammar pgf0 _ [] = return pgf0
|
||||||
importGrammar pgf0 opts files =
|
importGrammar pgf0 opts files =
|
||||||
case takeExtensions (last files) of
|
case takeExtensions (last files) of
|
||||||
".cf" -> importCF opts files getBNFCRules bnfc2cf
|
".cf" -> fmap Just $ importCF opts files getBNFCRules bnfc2cf
|
||||||
".ebnf" -> importCF opts files getEBNFRules ebnf2cf
|
".ebnf" -> fmap Just $ importCF opts files getEBNFRules ebnf2cf
|
||||||
".gfm" -> do
|
".gfm" -> do
|
||||||
ascss <- mapM readMulti files
|
ascss <- mapM readMulti files
|
||||||
let cs = concatMap snd ascss
|
let cs = concatMap snd ascss
|
||||||
@@ -36,14 +38,15 @@ importGrammar pgf0 opts files =
|
|||||||
Bad msg -> do putStrLn ('\n':'\n':msg)
|
Bad msg -> do putStrLn ('\n':'\n':msg)
|
||||||
return pgf0
|
return pgf0
|
||||||
".pgf" -> do
|
".pgf" -> do
|
||||||
pgf2 <- mapM readPGF files >>= return . foldl1 unionPGF
|
mapM readPGF files >>= foldM ioUnionPGF pgf0
|
||||||
ioUnionPGF pgf0 pgf2
|
|
||||||
ext -> die $ "Unknown filename extension: " ++ show ext
|
ext -> die $ "Unknown filename extension: " ++ show ext
|
||||||
|
|
||||||
ioUnionPGF :: PGF -> PGF -> IO PGF
|
ioUnionPGF :: Maybe PGF -> PGF -> IO (Maybe PGF)
|
||||||
ioUnionPGF one two = case msgUnionPGF one two of
|
ioUnionPGF Nothing two = return (Just two)
|
||||||
(pgf, Just msg) -> putStrLn msg >> return pgf
|
ioUnionPGF (Just one) two =
|
||||||
(pgf,_) -> return pgf
|
case unionPGF one two of
|
||||||
|
Nothing -> putStrLn "Abstract changed, previous concretes discarded." >> return (Just two)
|
||||||
|
Just pgf -> return (Just pgf)
|
||||||
|
|
||||||
importSource :: Options -> [FilePath] -> IO SourceGrammar
|
importSource :: Options -> [FilePath] -> IO SourceGrammar
|
||||||
importSource opts files = fmap (snd.snd) (batchCompile opts files)
|
importSource opts files = fmap (snd.snd) (batchCompile opts files)
|
||||||
@@ -56,7 +59,6 @@ importCF opts files get convert = impCF
|
|||||||
startCat <- case rules of
|
startCat <- case rules of
|
||||||
(Rule cat _ _ : _) -> return cat
|
(Rule cat _ _ : _) -> return cat
|
||||||
_ -> fail "empty CFG"
|
_ -> fail "empty CFG"
|
||||||
let pgf = cf2pgf (last files) (mkCFG startCat Set.empty rules)
|
probs <- maybe (return Map.empty) readProbabilitiesFromFile (flag optProbsFile opts)
|
||||||
probs <- maybe (return . defaultProbabilities) readProbabilitiesFromFile (flag optProbsFile opts) pgf
|
let pgf = cf2pgf opts (last files) (mkCFG startCat Set.empty rules) probs
|
||||||
return $ setProbabilities probs
|
return pgf
|
||||||
$ if flag optOptimizePGF opts then optimizePGF pgf else pgf
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ module GF.Command.Interpreter (
|
|||||||
import GF.Command.CommandInfo
|
import GF.Command.CommandInfo
|
||||||
import GF.Command.Abstract
|
import GF.Command.Abstract
|
||||||
import GF.Command.Parse
|
import GF.Command.Parse
|
||||||
import PGF.Internal(Expr(..))
|
|
||||||
import GF.Infra.UseIO(putStrLnE)
|
import GF.Infra.UseIO(putStrLnE)
|
||||||
|
import PGF2
|
||||||
|
|
||||||
import Control.Monad(when)
|
import Control.Monad(when)
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
@@ -53,17 +53,8 @@ interpretPipe env cs = do
|
|||||||
-- | macro definition applications: replace ?i by (exps !! i)
|
-- | macro definition applications: replace ?i by (exps !! i)
|
||||||
appCommand :: CommandArguments -> Command -> Command
|
appCommand :: CommandArguments -> Command -> Command
|
||||||
appCommand args c@(Command i os arg) = case arg of
|
appCommand args c@(Command i os arg) = case arg of
|
||||||
AExpr e -> Command i os (AExpr (app e))
|
AExpr e -> Command i os (AExpr (exprSubstitute e (toExprs args)))
|
||||||
_ -> c
|
_ -> c
|
||||||
where
|
|
||||||
xs = toExprs args
|
|
||||||
|
|
||||||
app e = case e of
|
|
||||||
EAbs b x e -> EAbs b x (app e)
|
|
||||||
EApp e1 e2 -> EApp (app e1) (app e2)
|
|
||||||
ELit l -> ELit l
|
|
||||||
EMeta i -> xs !! i
|
|
||||||
EFun x -> EFun x
|
|
||||||
|
|
||||||
-- | return the trees to be sent in pipe, and the output possibly printed
|
-- | return the trees to be sent in pipe, and the output possibly printed
|
||||||
--interpret :: CommandEnv -> [Expr] -> Command -> SIO CommandOutput
|
--interpret :: CommandEnv -> [Expr] -> Command -> SIO CommandOutput
|
||||||
@@ -110,4 +101,4 @@ getCommandTrees env needsTypeCheck a args =
|
|||||||
ATerm t -> return (Term t)
|
ATerm t -> return (Term t)
|
||||||
ANoArg -> return args -- use piped
|
ANoArg -> return args -- use piped
|
||||||
where
|
where
|
||||||
one e = return (Exprs [e]) -- ignore piped
|
one e = return (Exprs [(e,0)]) -- ignore piped
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module GF.Command.Parse(readCommandLine, pCommand) where
|
module GF.Command.Parse(readCommandLine, pCommand) where
|
||||||
|
|
||||||
import PGF(pExpr,pIdent)
|
import PGF2(pExpr,pIdent)
|
||||||
import GF.Grammar.Parser(runPartial,pTerm)
|
import GF.Grammar.Parser(runPartial,pTerm)
|
||||||
import GF.Command.Abstract
|
import GF.Command.Abstract
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ pCommandLine =
|
|||||||
pPipe = sepBy1 (skipSpaces >> pCommand) (skipSpaces >> char '|')
|
pPipe = sepBy1 (skipSpaces >> pCommand) (skipSpaces >> char '|')
|
||||||
|
|
||||||
pCommand = (do
|
pCommand = (do
|
||||||
cmd <- pIdent <++ (char '%' >> fmap ('%':) pIdent)
|
cmd <- readS_to_P pIdent <++ (char '%' >> fmap ('%':) (readS_to_P pIdent))
|
||||||
skipSpaces
|
skipSpaces
|
||||||
opts <- sepBy pOption skipSpaces
|
opts <- sepBy pOption skipSpaces
|
||||||
arg <- if getCommandOp cmd == "cc" then pArgTerm else pArgument
|
arg <- if getCommandOp cmd == "cc" then pArgTerm else pArgument
|
||||||
@@ -37,7 +37,7 @@ pCommand = (do
|
|||||||
|
|
||||||
pOption = do
|
pOption = do
|
||||||
char '-'
|
char '-'
|
||||||
flg <- pIdent
|
flg <- readS_to_P pIdent
|
||||||
option (OOpt flg) (fmap (OFlag flg) (char '=' >> pValue))
|
option (OOpt flg) (fmap (OFlag flg) (char '=' >> pValue))
|
||||||
|
|
||||||
pValue = do
|
pValue = do
|
||||||
@@ -52,9 +52,9 @@ pFilename = liftM2 (:) (satisfy isFileFirst) (munch (not . isSpace)) where
|
|||||||
|
|
||||||
pArgument =
|
pArgument =
|
||||||
option ANoArg
|
option ANoArg
|
||||||
(fmap AExpr pExpr
|
(fmap AExpr (readS_to_P pExpr)
|
||||||
<++
|
<++
|
||||||
(skipSpaces >> char '%' >> fmap AMacro pIdent))
|
(skipSpaces >> char '%' >> fmap AMacro (readS_to_P pIdent)))
|
||||||
|
|
||||||
pArgTerm = ATerm `fmap` readS_to_P sTerm
|
pArgTerm = ATerm `fmap` readS_to_P sTerm
|
||||||
where
|
where
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ module GF.Command.TreeOperations (
|
|||||||
treeChunks
|
treeChunks
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import PGF(Expr,PGF,CId,compute,mkApp,unApp,unapply,unMeta,exprSize,exprFunctions)
|
import PGF2(Expr,PGF,Fun,compute,mkApp,unApp,unapply,unMeta,exprSize,exprFunctions)
|
||||||
import Data.List
|
import Data.List
|
||||||
|
|
||||||
type TreeOp = [Expr] -> [Expr]
|
type TreeOp = [Expr] -> [Expr]
|
||||||
|
|
||||||
treeOp :: PGF -> String -> Maybe (Either TreeOp (CId -> TreeOp))
|
treeOp :: PGF -> String -> Maybe (Either TreeOp (Fun -> TreeOp))
|
||||||
treeOp pgf f = fmap snd $ lookup f $ allTreeOps pgf
|
treeOp pgf f = fmap snd $ lookup f $ allTreeOps pgf
|
||||||
|
|
||||||
allTreeOps :: PGF -> [(String,(String,Either TreeOp (CId -> TreeOp)))]
|
allTreeOps :: PGF -> [(String,(String,Either TreeOp (Fun -> TreeOp)))]
|
||||||
allTreeOps pgf = [
|
allTreeOps pgf = [
|
||||||
("compute",("compute by using semantic definitions (def)",
|
("compute",("compute by using semantic definitions (def)",
|
||||||
Left $ map (compute pgf))),
|
Left $ map (compute pgf))),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module GF.Compile (compileToPGF, link, batchCompile, srcAbsName) where
|
module GF.Compile (compileToPGF, link, batchCompile, srcAbsName) where
|
||||||
|
|
||||||
import GF.Compile.GrammarToPGF(mkCanon2pgf)
|
import GF.Compile.GrammarToPGF(grammar2PGF)
|
||||||
import GF.Compile.ReadFiles(ModEnv,getOptionsFromFile,getAllFiles,
|
import GF.Compile.ReadFiles(ModEnv,getOptionsFromFile,getAllFiles,
|
||||||
importsOfModule)
|
importsOfModule)
|
||||||
import GF.CompileOne(compileOne)
|
import GF.CompileOne(compileOne)
|
||||||
@@ -14,7 +14,7 @@ import GF.Infra.UseIO(IOE,FullPath,liftIO,getLibraryDirectory,putIfVerb,
|
|||||||
justModuleName,extendPathEnv,putStrE,putPointE)
|
justModuleName,extendPathEnv,putStrE,putPointE)
|
||||||
import GF.Data.Operations(raise,(+++),err)
|
import GF.Data.Operations(raise,(+++),err)
|
||||||
|
|
||||||
import Control.Monad(foldM,when,(<=<),filterM,liftM)
|
import Control.Monad(foldM,when,(<=<))
|
||||||
import GF.System.Directory(doesFileExist,getModificationTime)
|
import GF.System.Directory(doesFileExist,getModificationTime)
|
||||||
import System.FilePath((</>),isRelative,dropFileName)
|
import System.FilePath((</>),isRelative,dropFileName)
|
||||||
import qualified Data.Map as Map(empty,insert,elems) --lookup
|
import qualified Data.Map as Map(empty,insert,elems) --lookup
|
||||||
@@ -22,8 +22,7 @@ import Data.List(nub)
|
|||||||
import Data.Time(UTCTime)
|
import Data.Time(UTCTime)
|
||||||
import GF.Text.Pretty(render,($$),(<+>),nest)
|
import GF.Text.Pretty(render,($$),(<+>),nest)
|
||||||
|
|
||||||
import PGF.Internal(optimizePGF)
|
import PGF2(PGF,readProbabilitiesFromFile)
|
||||||
import PGF(PGF,defaultProbabilities,setProbabilities,readProbabilitiesFromFile)
|
|
||||||
|
|
||||||
-- | Compiles a number of source files and builds a 'PGF' structure for them.
|
-- | Compiles a number of source files and builds a 'PGF' structure for them.
|
||||||
-- This is a composition of 'link' and 'batchCompile'.
|
-- This is a composition of 'link' and 'batchCompile'.
|
||||||
@@ -36,11 +35,10 @@ link :: Options -> (ModuleName,Grammar) -> IOE PGF
|
|||||||
link opts (cnc,gr) =
|
link opts (cnc,gr) =
|
||||||
putPointE Normal opts "linking ... " $ do
|
putPointE Normal opts "linking ... " $ do
|
||||||
let abs = srcAbsName gr cnc
|
let abs = srcAbsName gr cnc
|
||||||
pgf <- mkCanon2pgf opts gr abs
|
probs <- liftIO (maybe (return Map.empty) readProbabilitiesFromFile (flag optProbsFile opts))
|
||||||
probs <- liftIO (maybe (return . defaultProbabilities) readProbabilitiesFromFile (flag optProbsFile opts) pgf)
|
pgf <- grammar2PGF opts gr abs probs
|
||||||
when (verbAtLeast opts Normal) $ putStrE "OK"
|
when (verbAtLeast opts Normal) $ putStrE "OK"
|
||||||
return $ setProbabilities probs
|
return pgf
|
||||||
$ if flag optOptimizePGF opts then optimizePGF pgf else pgf
|
|
||||||
|
|
||||||
-- | Returns the name of the abstract syntax corresponding to the named concrete syntax
|
-- | Returns the name of the abstract syntax corresponding to the named concrete syntax
|
||||||
srcAbsName gr cnc = err (const cnc) id $ abstractOfConcrete gr cnc
|
srcAbsName gr cnc = err (const cnc) id $ abstractOfConcrete gr cnc
|
||||||
@@ -78,14 +76,10 @@ compileModule opts1 env@(_,rfs) file =
|
|||||||
do file <- getRealFile file
|
do file <- getRealFile file
|
||||||
opts0 <- getOptionsFromFile file
|
opts0 <- getOptionsFromFile file
|
||||||
let curr_dir = dropFileName file
|
let curr_dir = dropFileName file
|
||||||
lib_dirs <- getLibraryDirectory (addOptions opts0 opts1)
|
lib_dir <- getLibraryDirectory (addOptions opts0 opts1)
|
||||||
let opts = addOptions (fixRelativeLibPaths curr_dir lib_dirs opts0) opts1
|
let opts = addOptions (fixRelativeLibPaths curr_dir lib_dir opts0) opts1
|
||||||
-- putIfVerb opts $ "curr_dir:" +++ show curr_dir ----
|
|
||||||
-- putIfVerb opts $ "lib_dir:" +++ show lib_dirs ----
|
|
||||||
ps0 <- extendPathEnv opts
|
ps0 <- extendPathEnv opts
|
||||||
let ps = nub (curr_dir : ps0)
|
let ps = nub (curr_dir : ps0)
|
||||||
-- putIfVerb opts $ "options from file: " ++ show opts0
|
|
||||||
-- putIfVerb opts $ "augmented options: " ++ show opts
|
|
||||||
putIfVerb opts $ "module search path:" +++ show ps ----
|
putIfVerb opts $ "module search path:" +++ show ps ----
|
||||||
files <- getAllFiles opts ps rfs file
|
files <- getAllFiles opts ps rfs file
|
||||||
putIfVerb opts $ "files to read:" +++ show files ----
|
putIfVerb opts $ "files to read:" +++ show files ----
|
||||||
@@ -98,17 +92,13 @@ compileModule opts1 env@(_,rfs) file =
|
|||||||
if exists
|
if exists
|
||||||
then return file
|
then return file
|
||||||
else if isRelative file
|
else if isRelative file
|
||||||
then do
|
then do lib_dir <- getLibraryDirectory opts1
|
||||||
lib_dirs <- getLibraryDirectory opts1
|
let file1 = lib_dir </> file
|
||||||
let candidates = [ lib_dir </> file | lib_dir <- lib_dirs ]
|
exists <- doesFileExist file1
|
||||||
putIfVerb opts1 (render ("looking for: " $$ nest 2 candidates))
|
if exists
|
||||||
file1s <- filterM doesFileExist candidates
|
then return file1
|
||||||
case length file1s of
|
else raise (render ("None of these files exists:" $$ nest 2 (file $$ file1)))
|
||||||
0 -> raise (render ("Unable to find: " $$ nest 2 candidates))
|
else raise (render ("File" <+> file <+> "does not exist."))
|
||||||
1 -> do return $ head file1s
|
|
||||||
_ -> do putIfVerb opts1 ("matched multiple candidates: " +++ show file1s)
|
|
||||||
return $ head file1s
|
|
||||||
else raise (render ("File" <+> file <+> "does not exist"))
|
|
||||||
|
|
||||||
compileOne' :: Options -> CompileEnv -> FullPath -> IOE CompileEnv
|
compileOne' :: Options -> CompileEnv -> FullPath -> IOE CompileEnv
|
||||||
compileOne' opts env@(gr,_) = extendCompileEnv env <=< compileOne opts gr
|
compileOne' opts env@(gr,_) = extendCompileEnv env <=< compileOne opts gr
|
||||||
|
|||||||
@@ -1,99 +1,110 @@
|
|||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts, ImplicitParams #-}
|
||||||
module GF.Compile.CFGtoPGF (cf2pgf) where
|
module GF.Compile.CFGtoPGF (cf2pgf) where
|
||||||
|
|
||||||
import GF.Grammar.CFG
|
import GF.Grammar.CFG
|
||||||
import GF.Infra.UseIO
|
import GF.Infra.UseIO
|
||||||
|
import GF.Infra.Option
|
||||||
|
import GF.Compile.OptimizePGF
|
||||||
|
|
||||||
import PGF
|
import PGF2
|
||||||
import PGF.Internal
|
import PGF2.Internal
|
||||||
|
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import qualified Data.IntMap as IntMap
|
import qualified Data.IntMap as IntMap
|
||||||
import Data.Array.IArray
|
import Data.Array.IArray
|
||||||
import Data.List
|
import Data.List
|
||||||
|
import Data.Maybe(fromMaybe)
|
||||||
|
|
||||||
--------------------------
|
--------------------------
|
||||||
-- the compiler ----------
|
-- the compiler ----------
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
cf2pgf :: FilePath -> ParamCFG -> PGF
|
cf2pgf :: Options -> FilePath -> ParamCFG -> Map.Map Fun Double -> PGF
|
||||||
cf2pgf fpath cf =
|
cf2pgf opts fpath cf probs =
|
||||||
let pgf = PGF Map.empty aname (cf2abstr cf) (Map.singleton cname (cf2concr cf))
|
build (let abstr = cf2abstr cf probs
|
||||||
in updateProductionIndices pgf
|
in newPGF [] aname abstr [(cname, cf2concr opts abstr cf)])
|
||||||
where
|
where
|
||||||
name = justModuleName fpath
|
name = justModuleName fpath
|
||||||
aname = mkCId (name ++ "Abs")
|
aname = name ++ "Abs"
|
||||||
cname = mkCId name
|
cname = name
|
||||||
|
|
||||||
cf2abstr :: ParamCFG -> Abstr
|
cf2abstr :: (?builder :: Builder s) => ParamCFG -> Map.Map Fun Double -> B s AbstrInfo
|
||||||
cf2abstr cfg = Abstr aflags afuns acats
|
cf2abstr cfg probs = newAbstr aflags acats afuns
|
||||||
where
|
where
|
||||||
aflags = Map.singleton (mkCId "startcat") (LStr (fst (cfgStartCat cfg)))
|
aflags = [("startcat", LStr (fst (cfgStartCat cfg)))]
|
||||||
|
|
||||||
acats = Map.fromList [(cat, ([], [(0,mkRuleName rule) | rule <- rules], 0))
|
acats = [(c', [], toLogProb (fromMaybe 0 (Map.lookup c' probs))) | cat <- allCats' cfg, let c' = cat2id cat]
|
||||||
| (cat,rules) <- (Map.toList . Map.fromListWith (++))
|
afuns = [(f', dTyp [hypo Explicit "_" (dTyp [] (cat2id c) []) | NonTerminal c <- ruleRhs rule] (cat2id (ruleLhs rule)) [], 0, [], toLogProb (fromMaybe 0 (Map.lookup f' funs_probs)))
|
||||||
[(cat2id cat, catRules cfg cat) |
|
| rule <- allRules cfg
|
||||||
cat <- allCats' cfg]]
|
, let f' = mkRuleName rule]
|
||||||
afuns = Map.fromList [(mkRuleName rule, (cftype [cat2id c | NonTerminal c <- ruleRhs rule] (cat2id (ruleLhs rule)), 0, Nothing, 0))
|
|
||||||
| rule <- allRules cfg]
|
|
||||||
|
|
||||||
cat2id = mkCId . fst
|
funs_probs = (Map.fromList . concat . Map.elems . fmap pad . Map.fromListWith (++))
|
||||||
|
[(cat,[(f',Map.lookup f' probs)]) | rule <- allRules cfg,
|
||||||
|
let cat = cat2id (ruleLhs rule),
|
||||||
|
let f' = mkRuleName rule]
|
||||||
|
where
|
||||||
|
pad :: [(a,Maybe Double)] -> [(a,Double)]
|
||||||
|
pad pfs = [(f,fromMaybe deflt mb_p) | (f,mb_p) <- pfs]
|
||||||
|
where
|
||||||
|
deflt = case length [f | (f,Nothing) <- pfs] of
|
||||||
|
0 -> 0
|
||||||
|
n -> max 0 ((1 - sum [d | (f,Just d) <- pfs]) / fromIntegral n)
|
||||||
|
|
||||||
cf2concr :: ParamCFG -> Concr
|
toLogProb = realToFrac . negate . log
|
||||||
cf2concr cfg = Concr Map.empty Map.empty
|
|
||||||
cncfuns lindefsrefs lindefsrefs
|
cat2id = fst
|
||||||
sequences productions
|
|
||||||
IntMap.empty Map.empty
|
cf2concr :: (?builder :: Builder s) => Options -> B s AbstrInfo -> ParamCFG -> B s ConcrInfo
|
||||||
cnccats
|
cf2concr opts abstr cfg =
|
||||||
IntMap.empty
|
let (lindefs',linrefs',productions',cncfuns',sequences',cnccats') =
|
||||||
totalCats
|
(if flag optOptimizePGF opts then optimizePGF (fst (cfgStartCat cfg)) else id)
|
||||||
|
(lindefsrefs,lindefsrefs,IntMap.toList productions,cncfuns,sequences,cnccats)
|
||||||
|
in newConcr abstr [] []
|
||||||
|
lindefs' linrefs'
|
||||||
|
productions' cncfuns'
|
||||||
|
sequences' cnccats' totalCats
|
||||||
where
|
where
|
||||||
cats = allCats' cfg
|
cats = allCats' cfg
|
||||||
rules = allRules cfg
|
rules = allRules cfg
|
||||||
|
|
||||||
sequences0 = Set.fromList (listArray (0,0) [SymCat 0 0] :
|
idSeq = [SymCat 0 0]
|
||||||
map mkSequence rules)
|
|
||||||
sequences = listArray (0,Set.size sequences0-1) (Set.toList sequences0)
|
|
||||||
|
|
||||||
idFun = CncFun wildCId (listArray (0,0) [seqid])
|
sequences0 = Set.fromList (idSeq :
|
||||||
where
|
map mkSequence rules)
|
||||||
seq = listArray (0,0) [SymCat 0 0]
|
sequences = Set.toList sequences0
|
||||||
seqid = binSearch seq sequences (bounds sequences)
|
|
||||||
|
idFun = ("_",[Set.findIndex idSeq sequences0])
|
||||||
((fun_cnt,cncfuns0),productions0) = mapAccumL (convertRule cs) (1,[idFun]) rules
|
((fun_cnt,cncfuns0),productions0) = mapAccumL (convertRule cs) (1,[idFun]) rules
|
||||||
productions = foldl addProd IntMap.empty (concat (productions0++coercions))
|
productions = foldl addProd IntMap.empty (concat (productions0++coercions))
|
||||||
cncfuns = listArray (0,fun_cnt-1) (reverse cncfuns0)
|
cncfuns = reverse cncfuns0
|
||||||
|
|
||||||
lbls = listArray (0,0) ["s"]
|
lbls = ["s"]
|
||||||
(fid,cnccats0) = (mapAccumL mkCncCat 0 . Map.toList . Map.fromListWith max)
|
(fid,cnccats) = (mapAccumL mkCncCat 0 . Map.toList . Map.fromListWith max)
|
||||||
[(c,p) | (c,ps) <- cats, p <- ps]
|
[(c,p) | (c,ps) <- cats, p <- ps]
|
||||||
((totalCats,cs), coercions) = mapAccumL mkCoercions (fid,Map.empty) cats
|
((totalCats,cs), coercions) = mapAccumL mkCoercions (fid,Map.empty) cats
|
||||||
cnccats = Map.fromList cnccats0
|
|
||||||
|
|
||||||
lindefsrefs =
|
lindefsrefs = map mkLinDefRef cats
|
||||||
IntMap.fromList (map mkLinDefRef cats)
|
|
||||||
|
|
||||||
convertRule cs (funid,funs) rule =
|
convertRule cs (funid,funs) rule =
|
||||||
let args = [PArg [] (cat2arg c) | NonTerminal c <- ruleRhs rule]
|
let args = [PArg [] (cat2arg c) | NonTerminal c <- ruleRhs rule]
|
||||||
prod = PApply funid args
|
prod = PApply funid args
|
||||||
seqid = binSearch (mkSequence rule) sequences (bounds sequences)
|
seqid = Set.findIndex (mkSequence rule) sequences0
|
||||||
fun = CncFun (mkRuleName rule) (listArray (0,0) [seqid])
|
fun = (mkRuleName rule, [seqid])
|
||||||
funid' = funid+1
|
funid' = funid+1
|
||||||
in funid' `seq` ((funid',fun:funs),let (c,ps) = ruleLhs rule in [(cat2fid c p, prod) | p <- ps])
|
in funid' `seq` ((funid',fun:funs),let (c,ps) = ruleLhs rule in [(cat2fid c p, prod) | p <- ps])
|
||||||
|
|
||||||
mkSequence rule = listArray (0,length syms-1) syms
|
mkSequence rule = snd $ mapAccumL convertSymbol 0 (ruleRhs rule)
|
||||||
where
|
where
|
||||||
syms = snd $ mapAccumL convertSymbol 0 (ruleRhs rule)
|
|
||||||
|
|
||||||
convertSymbol d (NonTerminal (c,_)) = (d+1,if c `elem` ["Int","Float","String"] then SymLit d 0 else SymCat d 0)
|
convertSymbol d (NonTerminal (c,_)) = (d+1,if c `elem` ["Int","Float","String"] then SymLit d 0 else SymCat d 0)
|
||||||
convertSymbol d (Terminal t) = (d, SymKS t)
|
convertSymbol d (Terminal t) = (d, SymKS t)
|
||||||
|
|
||||||
mkCncCat fid (cat,n)
|
mkCncCat fid (cat,n)
|
||||||
| cat == "Int" = (fid, (mkCId cat, CncCat fidInt fidInt lbls))
|
| cat == "Int" = (fid, (cat, fidInt, fidInt, lbls))
|
||||||
| cat == "Float" = (fid, (mkCId cat, CncCat fidFloat fidFloat lbls))
|
| cat == "Float" = (fid, (cat, fidFloat, fidFloat, lbls))
|
||||||
| cat == "String" = (fid, (mkCId cat, CncCat fidString fidString lbls))
|
| cat == "String" = (fid, (cat, fidString, fidString, lbls))
|
||||||
| otherwise = let fid' = fid+n+1
|
| otherwise = let fid' = fid+n+1
|
||||||
in fid' `seq` (fid', (mkCId cat,CncCat fid (fid+n) lbls))
|
in fid' `seq` (fid', (cat, fid, fid+n, lbls))
|
||||||
|
|
||||||
mkCoercions (fid,cs) c@(cat,[p]) = ((fid,cs),[])
|
mkCoercions (fid,cs) c@(cat,[p]) = ((fid,cs),[])
|
||||||
mkCoercions (fid,cs) c@(cat,ps ) =
|
mkCoercions (fid,cs) c@(cat,ps ) =
|
||||||
@@ -105,22 +116,13 @@ cf2concr cfg = Concr Map.empty Map.empty
|
|||||||
|
|
||||||
addProd prods (fid,prod) =
|
addProd prods (fid,prod) =
|
||||||
case IntMap.lookup fid prods of
|
case IntMap.lookup fid prods of
|
||||||
Just set -> IntMap.insert fid (Set.insert prod set) prods
|
Just set -> IntMap.insert fid (prod:set) prods
|
||||||
Nothing -> IntMap.insert fid (Set.singleton prod) prods
|
Nothing -> IntMap.insert fid [prod] prods
|
||||||
|
|
||||||
binSearch v arr (i,j)
|
|
||||||
| i <= j = case compare v (arr ! k) of
|
|
||||||
LT -> binSearch v arr (i,k-1)
|
|
||||||
EQ -> k
|
|
||||||
GT -> binSearch v arr (k+1,j)
|
|
||||||
| otherwise = error "binSearch"
|
|
||||||
where
|
|
||||||
k = (i+j) `div` 2
|
|
||||||
|
|
||||||
cat2fid cat p =
|
cat2fid cat p =
|
||||||
case Map.lookup (mkCId cat) cnccats of
|
case [start | (cat',start,_,_) <- cnccats, cat == cat'] of
|
||||||
Just (CncCat fid _ _) -> fid+p
|
(start:_) -> fid+p
|
||||||
_ -> error "cat2fid"
|
_ -> error "cat2fid"
|
||||||
|
|
||||||
cat2arg c@(cat,[p]) = cat2fid cat p
|
cat2arg c@(cat,[p]) = cat2fid cat p
|
||||||
cat2arg c@(cat,ps ) =
|
cat2arg c@(cat,ps ) =
|
||||||
@@ -131,4 +133,5 @@ cf2concr cfg = Concr Map.empty Map.empty
|
|||||||
mkRuleName rule =
|
mkRuleName rule =
|
||||||
case ruleName rule of
|
case ruleName rule of
|
||||||
CFObj n _ -> n
|
CFObj n _ -> n
|
||||||
_ -> wildCId
|
_ -> "_"
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
module GF.Compile.CheckGrammar(checkModule) where
|
module GF.Compile.CheckGrammar(checkModule) where
|
||||||
import Prelude hiding ((<>)) -- GHC 8.4.1 clash with Text.PrettyPrint
|
|
||||||
|
|
||||||
import GF.Infra.Ident
|
import GF.Infra.Ident
|
||||||
import GF.Infra.Option
|
import GF.Infra.Option
|
||||||
@@ -34,14 +33,13 @@ import qualified GF.Compile.Compute.ConcreteNew as CN
|
|||||||
import GF.Grammar
|
import GF.Grammar
|
||||||
import GF.Grammar.Lexer
|
import GF.Grammar.Lexer
|
||||||
import GF.Grammar.Lookup
|
import GF.Grammar.Lookup
|
||||||
--import GF.Grammar.Predef
|
|
||||||
--import GF.Grammar.PatternMatch
|
|
||||||
|
|
||||||
import GF.Data.Operations
|
import GF.Data.Operations
|
||||||
import GF.Infra.CheckM
|
import GF.Infra.CheckM
|
||||||
|
|
||||||
import Data.List
|
import Data.List
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
|
import qualified Data.Map as Map
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import GF.Text.Pretty
|
import GF.Text.Pretty
|
||||||
|
|
||||||
@@ -59,7 +57,7 @@ checkModule opts cwd sgr mo@(m,mi) = do
|
|||||||
where
|
where
|
||||||
updateCheckInfos mo = fmap (foldl update mo) . parallelCheck . map check
|
updateCheckInfos mo = fmap (foldl update mo) . parallelCheck . map check
|
||||||
where check (i,info) = fmap ((,) i) (checkInfo opts cwd sgr mo i info)
|
where check (i,info) = fmap ((,) i) (checkInfo opts cwd sgr mo i info)
|
||||||
update mo@(m,mi) (i,info) = (m,mi{jments=updateTree (i,info) (jments mi)})
|
update mo@(m,mi) (i,info) = (m,mi{jments=Map.insert i info (jments mi)})
|
||||||
|
|
||||||
-- check if restricted inheritance modules are still coherent
|
-- check if restricted inheritance modules are still coherent
|
||||||
-- i.e. that the defs of remaining names don't depend on omitted names
|
-- i.e. that the defs of remaining names don't depend on omitted names
|
||||||
@@ -72,7 +70,7 @@ checkRestrictedInheritance cwd sgr (name,mo) = checkInModule cwd mo NoLoc empty
|
|||||||
where
|
where
|
||||||
mos = modules sgr
|
mos = modules sgr
|
||||||
checkRem ((i,m),mi) = do
|
checkRem ((i,m),mi) = do
|
||||||
let (incl,excl) = partition (isInherited mi) (map fst (tree2list (jments m)))
|
let (incl,excl) = partition (isInherited mi) (Map.keys (jments m))
|
||||||
let incld c = Set.member c (Set.fromList incl)
|
let incld c = Set.member c (Set.fromList incl)
|
||||||
let illegal c = Set.member c (Set.fromList excl)
|
let illegal c = Set.member c (Set.fromList excl)
|
||||||
let illegals = [(f,is) |
|
let illegals = [(f,is) |
|
||||||
@@ -89,10 +87,10 @@ checkCompleteGrammar opts cwd gr (am,abs) (cm,cnc) = checkInModule cwd cnc NoLoc
|
|||||||
let jsc = jments cnc
|
let jsc = jments cnc
|
||||||
|
|
||||||
-- check that all concrete constants are in abstract; build types for all lin
|
-- check that all concrete constants are in abstract; build types for all lin
|
||||||
jsc <- foldM checkCnc emptyBinTree (tree2list jsc)
|
jsc <- foldM checkCnc Map.empty (Map.toList jsc)
|
||||||
|
|
||||||
-- check that all abstract constants are in concrete; build default lin and lincats
|
-- check that all abstract constants are in concrete; build default lin and lincats
|
||||||
jsc <- foldM checkAbs jsc (tree2list jsa)
|
jsc <- foldM checkAbs jsc (Map.toList jsa)
|
||||||
|
|
||||||
return (cm,cnc{jments=jsc})
|
return (cm,cnc{jments=jsc})
|
||||||
where
|
where
|
||||||
@@ -113,17 +111,17 @@ checkCompleteGrammar opts cwd gr (am,abs) (cm,cnc) = checkInModule cwd cnc NoLoc
|
|||||||
case lookupIdent c js of
|
case lookupIdent c js of
|
||||||
Ok (AnyInd _ _) -> return js
|
Ok (AnyInd _ _) -> return js
|
||||||
Ok (CncFun ty (Just def) mn mf) ->
|
Ok (CncFun ty (Just def) mn mf) ->
|
||||||
return $ updateTree (c,CncFun ty (Just def) mn mf) js
|
return $ Map.insert c (CncFun ty (Just def) mn mf) js
|
||||||
Ok (CncFun ty Nothing mn mf) ->
|
Ok (CncFun ty Nothing mn mf) ->
|
||||||
case mb_def of
|
case mb_def of
|
||||||
Ok def -> return $ updateTree (c,CncFun ty (Just (L NoLoc def)) mn mf) js
|
Ok def -> return $ Map.insert c (CncFun ty (Just (L NoLoc def)) mn mf) js
|
||||||
Bad _ -> do noLinOf c
|
Bad _ -> do noLinOf c
|
||||||
return js
|
return js
|
||||||
_ -> do
|
_ -> do
|
||||||
case mb_def of
|
case mb_def of
|
||||||
Ok def -> do (cont,val) <- linTypeOfType gr cm ty
|
Ok def -> do (cont,val) <- linTypeOfType gr cm ty
|
||||||
let linty = (snd (valCat ty),cont,val)
|
let linty = (snd (valCat ty),cont,val)
|
||||||
return $ updateTree (c,CncFun (Just linty) (Just (L NoLoc def)) Nothing Nothing) js
|
return $ Map.insert c (CncFun (Just linty) (Just (L NoLoc def)) Nothing Nothing) js
|
||||||
Bad _ -> do noLinOf c
|
Bad _ -> do noLinOf c
|
||||||
return js
|
return js
|
||||||
where noLinOf c = checkWarn ("no linearization of" <+> c)
|
where noLinOf c = checkWarn ("no linearization of" <+> c)
|
||||||
@@ -132,26 +130,32 @@ checkCompleteGrammar opts cwd gr (am,abs) (cm,cnc) = checkInModule cwd cnc NoLoc
|
|||||||
Ok (CncCat (Just _) _ _ _ _) -> return js
|
Ok (CncCat (Just _) _ _ _ _) -> return js
|
||||||
Ok (CncCat Nothing md mr mp mpmcfg) -> do
|
Ok (CncCat Nothing md mr mp mpmcfg) -> do
|
||||||
checkWarn ("no linearization type for" <+> c <> ", inserting default {s : Str}")
|
checkWarn ("no linearization type for" <+> c <> ", inserting default {s : Str}")
|
||||||
return $ updateTree (c,CncCat (Just (L NoLoc defLinType)) md mr mp mpmcfg) js
|
return $ Map.insert c (CncCat (Just (L NoLoc defLinType)) md mr mp mpmcfg) js
|
||||||
_ -> do
|
_ -> do
|
||||||
checkWarn ("no linearization type for" <+> c <> ", inserting default {s : Str}")
|
checkWarn ("no linearization type for" <+> c <> ", inserting default {s : Str}")
|
||||||
return $ updateTree (c,CncCat (Just (L NoLoc defLinType)) Nothing Nothing Nothing Nothing) js
|
return $ Map.insert c (CncCat (Just (L NoLoc defLinType)) Nothing Nothing Nothing Nothing) js
|
||||||
_ -> return js
|
_ -> return js
|
||||||
|
|
||||||
checkCnc js i@(c,info) =
|
checkCnc js (c,info) =
|
||||||
case info of
|
case info of
|
||||||
CncFun _ d mn mf -> case lookupOrigInfo gr (am,c) of
|
CncFun _ d mn mf -> case lookupOrigInfo gr (am,c) of
|
||||||
Ok (_,AbsFun (Just (L _ ty)) _ _ _) ->
|
Ok (_,AbsFun (Just (L _ ty)) _ _ _) ->
|
||||||
do (cont,val) <- linTypeOfType gr cm ty
|
do (cont,val) <- linTypeOfType gr cm ty
|
||||||
let linty = (snd (valCat ty),cont,val)
|
let linty = (snd (valCat ty),cont,val)
|
||||||
return $ updateTree (c,CncFun (Just linty) d mn mf) js
|
return $ Map.insert c (CncFun (Just linty) d mn mf) js
|
||||||
_ -> do checkWarn ("function" <+> c <+> "is not in abstract")
|
_ -> do checkWarn ("function" <+> c <+> "is not in abstract")
|
||||||
return js
|
return js
|
||||||
CncCat _ _ _ _ _ -> case lookupOrigInfo gr (am,c) of
|
CncCat {} ->
|
||||||
Ok _ -> return $ updateTree i js
|
case lookupOrigInfo gr (am,c) of
|
||||||
_ -> do checkWarn ("category" <+> c <+> "is not in abstract")
|
Ok (_,AbsCat _) -> return $ Map.insert c info js
|
||||||
return js
|
{- -- This might be too pedantic:
|
||||||
_ -> return $ updateTree i js
|
Ok (_,AbsFun {}) ->
|
||||||
|
checkError ("lincat:"<+>c<+>"is a fun, not a cat")
|
||||||
|
-}
|
||||||
|
_ -> do checkWarn ("category" <+> c <+> "is not in abstract")
|
||||||
|
return js
|
||||||
|
|
||||||
|
_ -> return $ Map.insert c info js
|
||||||
|
|
||||||
|
|
||||||
-- | General Principle: only Just-values are checked.
|
-- | General Principle: only Just-values are checked.
|
||||||
@@ -255,18 +259,30 @@ checkInfo opts cwd sgr (m,mo) c info = checkInModule cwd mo NoLoc empty $ do
|
|||||||
return (ResOverload os [(y,x) | (x,y) <- tysts'])
|
return (ResOverload os [(y,x) | (x,y) <- tysts'])
|
||||||
|
|
||||||
ResParam (Just (L loc pcs)) _ -> do
|
ResParam (Just (L loc pcs)) _ -> do
|
||||||
ts <- chIn loc "parameter type" $
|
(vs,pcs) <- chIn loc "parameter type" $
|
||||||
liftM concat $ mapM mkPar pcs
|
mkParams 0 [] pcs
|
||||||
return (ResParam (Just (L loc pcs)) (Just ts))
|
return (ResParam (Just (L loc pcs)) (Just vs))
|
||||||
|
|
||||||
|
ResValue (L loc ty) _ ->
|
||||||
|
chIn loc "operation" $ do
|
||||||
|
let (_,Cn x) = typeFormCnc ty
|
||||||
|
is = case Map.lookup x (jments mo) of
|
||||||
|
Just (ResParam (Just (L _ pcs)) _) -> [i | (f,_,i) <- pcs, f == c]
|
||||||
|
_ -> []
|
||||||
|
case is of
|
||||||
|
[i] -> return (ResValue (L loc ty) i)
|
||||||
|
_ -> checkError (pp "Failed to find the value index for parameter" <+> pp c)
|
||||||
|
|
||||||
_ -> return info
|
_ -> return info
|
||||||
where
|
where
|
||||||
gr = prependModule sgr (m,mo)
|
gr = prependModule sgr (m,mo)
|
||||||
chIn loc cat = checkInModule cwd mo loc ("Happened in" <+> cat <+> c)
|
chIn loc cat = checkInModule cwd mo loc ("Happened in" <+> cat <+> c)
|
||||||
|
|
||||||
mkPar (f,co) = do
|
mkParams i vs [] = return (vs,[])
|
||||||
vs <- liftM combinations $ mapM (\(_,_,ty) -> allParamValues gr ty) co
|
mkParams i vs ((f,co,_):pcs) = do
|
||||||
return $ map (mkApp (QC (m,f))) vs
|
vs0 <- liftM combinations $ mapM (\(_,_,ty) -> allParamValues gr ty) co
|
||||||
|
(vs,pcs) <- mkParams (i + length vs0) (vs ++ map (mkApp (QC (m,f))) vs0) pcs
|
||||||
|
return (vs,(f,co,i):pcs)
|
||||||
|
|
||||||
checkUniq xss = case xss of
|
checkUniq xss = case xss of
|
||||||
x:y:xs
|
x:y:xs
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
module GF.Compile.Coding where
|
|
||||||
{-
|
|
||||||
import GF.Grammar.Grammar
|
|
||||||
import GF.Grammar.Macros
|
|
||||||
import GF.Text.Coding
|
|
||||||
--import GF.Infra.Option
|
|
||||||
import GF.Data.Operations
|
|
||||||
|
|
||||||
--import Data.Char
|
|
||||||
import System.IO
|
|
||||||
import qualified Data.ByteString.Char8 as BS
|
|
||||||
|
|
||||||
encodeStringsInModule :: TextEncoding -> SourceModule -> SourceModule
|
|
||||||
encodeStringsInModule enc = codeSourceModule (BS.unpack . encodeUnicode enc)
|
|
||||||
|
|
||||||
decodeStringsInModule :: TextEncoding -> SourceModule -> SourceModule
|
|
||||||
decodeStringsInModule enc mo = codeSourceModule (decodeUnicode enc . BS.pack) mo
|
|
||||||
|
|
||||||
codeSourceModule :: (String -> String) -> SourceModule -> SourceModule
|
|
||||||
codeSourceModule co (id,mo) = (id,mo{jments = mapTree codj (jments mo)})
|
|
||||||
where
|
|
||||||
codj (c,info) = case info of
|
|
||||||
ResOper pty pt -> ResOper (codeLTerms co pty) (codeLTerms co pt)
|
|
||||||
ResOverload es tyts -> ResOverload es [(codeLTerm co ty,codeLTerm co t) | (ty,t) <- tyts]
|
|
||||||
CncCat mcat mdef mref mpr mpmcfg -> CncCat mcat (codeLTerms co mdef) (codeLTerms co mref) (codeLTerms co mpr) mpmcfg
|
|
||||||
CncFun mty mt mpr mpmcfg -> CncFun mty (codeLTerms co mt) (codeLTerms co mpr) mpmcfg
|
|
||||||
_ -> info
|
|
||||||
|
|
||||||
codeLTerms co = fmap (codeLTerm co)
|
|
||||||
|
|
||||||
codeLTerm :: (String -> String) -> L Term -> L Term
|
|
||||||
codeLTerm = fmap . codeTerm
|
|
||||||
|
|
||||||
codeTerm :: (String -> String) -> Term -> Term
|
|
||||||
codeTerm co = codt
|
|
||||||
where
|
|
||||||
codt t = case t of
|
|
||||||
K s -> K (co s)
|
|
||||||
T ty cs -> T ty [(codp p,codt v) | (p,v) <- cs]
|
|
||||||
EPatt p -> EPatt (codp p)
|
|
||||||
_ -> composSafeOp codt t
|
|
||||||
|
|
||||||
codp p = case p of --- really: composOpPatt
|
|
||||||
PR rs -> PR [(l,codp p) | (l,p) <- rs]
|
|
||||||
PString s -> PString (co s)
|
|
||||||
PChars s -> PChars (co s)
|
|
||||||
PT x p -> PT x (codp p)
|
|
||||||
PAs x p -> PAs x (codp p)
|
|
||||||
PNeg p -> PNeg (codp p)
|
|
||||||
PRep p -> PRep (codp p)
|
|
||||||
PSeq p q -> PSeq (codp p) (codp q)
|
|
||||||
PAlt p q -> PAlt (codp p) (codp q)
|
|
||||||
_ -> p
|
|
||||||
|
|
||||||
-- | Run an encoding function on all string literals within the given string.
|
|
||||||
codeStringLiterals :: (String -> String) -> String -> String
|
|
||||||
codeStringLiterals _ [] = []
|
|
||||||
codeStringLiterals co ('"':cs) = '"' : inStringLiteral cs
|
|
||||||
where inStringLiteral [] = error "codeStringLiterals: unterminated string literal"
|
|
||||||
inStringLiteral ('"':ds) = '"' : codeStringLiterals co ds
|
|
||||||
inStringLiteral ('\\':d:ds) = '\\' : co [d] ++ inStringLiteral ds
|
|
||||||
inStringLiteral (d:ds) = co [d] ++ inStringLiteral ds
|
|
||||||
codeStringLiterals co (c:cs) = c : codeStringLiterals co cs
|
|
||||||
-}
|
|
||||||
@@ -5,7 +5,6 @@ module GF.Compile.Compute.ConcreteNew
|
|||||||
normalForm,
|
normalForm,
|
||||||
Value(..), Bind(..), Env, value2term, eval, vapply
|
Value(..), Bind(..), Env, value2term, eval, vapply
|
||||||
) where
|
) where
|
||||||
import Prelude hiding ((<>)) -- GHC 8.4.1 clash with Text.PrettyPrint
|
|
||||||
|
|
||||||
import GF.Grammar hiding (Env, VGen, VApp, VRecType)
|
import GF.Grammar hiding (Env, VGen, VApp, VRecType)
|
||||||
import GF.Grammar.Lookup(lookupResDefLoc,allParamValues)
|
import GF.Grammar.Lookup(lookupResDefLoc,allParamValues)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module GF.Compile.Compute.Value where
|
module GF.Compile.Compute.Value where
|
||||||
import GF.Grammar.Grammar(Label,Type,MetaId,Patt,QIdent)
|
import GF.Grammar.Grammar(Label,Type,MetaId,Patt,QIdent)
|
||||||
import PGF.Internal(BindType)
|
import PGF2(BindType)
|
||||||
import GF.Infra.Ident(Ident)
|
import GF.Infra.Ident(Ident)
|
||||||
import Text.Show.Functions()
|
import Text.Show.Functions()
|
||||||
import Data.Ix(Ix)
|
import Data.Ix(Ix)
|
||||||
|
|||||||
@@ -1,365 +1,351 @@
|
|||||||
-- | Translate concrete syntax to Haskell
|
-- | Translate concrete syntax to Haskell
|
||||||
module GF.Compile.ConcreteToHaskell(concretes2haskell,concrete2haskell) where
|
module GF.Compile.ConcreteToHaskell(concretes2haskell,concrete2haskell) where
|
||||||
import Data.List(sort,sortBy)
|
import Data.List(isPrefixOf,sort,sortOn)
|
||||||
import Data.Function(on)
|
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import qualified Data.Set as S
|
import qualified Data.Set as S
|
||||||
import GF.Data.ErrM
|
|
||||||
import GF.Data.Utilities(mapSnd)
|
|
||||||
import GF.Text.Pretty
|
import GF.Text.Pretty
|
||||||
import GF.Grammar.Grammar
|
--import GF.Grammar.Predef(cPredef,cInts)
|
||||||
import GF.Grammar.Lookup(lookupFunType,lookupOrigInfo,allOrigInfos)--,allParamValues
|
--import GF.Compile.Compute.Predef(predef)
|
||||||
import GF.Grammar.Macros(typeForm,collectOp,collectPattOp,mkAbs,mkApp)
|
--import GF.Compile.Compute.Value(Predefined(..))
|
||||||
import GF.Grammar.Lockfield(isLockLabel)
|
import GF.Infra.Ident(Ident,identS,identW,prefixIdent)
|
||||||
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.Infra.Option
|
import GF.Infra.Option
|
||||||
import GF.Compile.Compute.ConcreteNew(normalForm,resourceValues)
|
import GF.Haskell as H
|
||||||
import GF.Haskell
|
import GF.Grammar.Canonical as C
|
||||||
import Debug.Trace
|
import GF.Compile.GrammarToCanonical
|
||||||
|
import Debug.Trace(trace)
|
||||||
|
|
||||||
-- | Generate Haskell code for the all concrete syntaxes associated with
|
-- | Generate Haskell code for the all concrete syntaxes associated with
|
||||||
-- the named abstract syntax in given the grammar.
|
-- the named abstract syntax in given the grammar.
|
||||||
concretes2haskell opts absname gr =
|
concretes2haskell opts absname gr =
|
||||||
[(cncname,concrete2haskell opts gr cenv absname cnc cncmod)
|
[(filename,render80 $ concrete2haskell opts abstr cncmod)
|
||||||
| let cenv = resourceValues opts gr,
|
| let Grammar abstr cncs = grammar2canonical opts absname gr,
|
||||||
cnc<-allConcretes gr absname,
|
cncmod<-cncs,
|
||||||
let cncname = render cnc ++ ".hs" :: FilePath
|
let ModId name = concName cncmod
|
||||||
Ok cncmod = lookupModule gr cnc
|
filename = name ++ ".hs" :: FilePath
|
||||||
]
|
]
|
||||||
|
|
||||||
-- | Generate Haskell code for the given concrete module.
|
-- | Generate Haskell code for the given concrete module.
|
||||||
-- The only options that make a difference are
|
-- The only options that make a difference are
|
||||||
-- @-haskell=noprefix@ and @-haskell=variants@.
|
-- @-haskell=noprefix@ and @-haskell=variants@.
|
||||||
concrete2haskell opts gr cenv absname cnc modinfo =
|
concrete2haskell opts
|
||||||
renderStyle style{lineLength=80,ribbonsPerLine=1} $
|
abstr@(Abstract _ _ cats funs)
|
||||||
haskPreamble va absname cnc $$ vcat (
|
modinfo@(Concrete cnc absname _ ps lcs lns) =
|
||||||
nl:Comment "--- Parameter types ---":
|
haskPreamble absname cnc $$
|
||||||
neededParamTypes S.empty (params defs) ++
|
vcat (
|
||||||
nl:Comment "--- Type signatures for linearization functions ---":
|
nl:Comment "--- Parameter types ---":
|
||||||
map signature (S.toList allcats)++
|
map paramDef ps ++
|
||||||
nl:Comment "--- Linearization functions for empty categories ---":
|
nl:Comment "--- Type signatures for linearization functions ---":
|
||||||
emptydefs ++
|
map signature cats ++
|
||||||
nl:Comment "--- Linearization types and linearization functions ---":
|
nl:Comment "--- Linearization functions for empty categories ---":
|
||||||
map ppDef defs ++
|
emptydefs ++
|
||||||
nl:Comment "--- Type classes for projection functions ---":
|
nl:Comment "--- Linearization types ---":
|
||||||
map labelClass (S.toList labels) ++
|
map lincatDef lcs ++
|
||||||
nl:Comment "--- Record types ---":
|
nl:Comment "--- Linearization functions ---":
|
||||||
concatMap recordType recs)
|
lindefs ++
|
||||||
|
nl:Comment "--- Type classes for projection functions ---":
|
||||||
|
map labelClass (S.toList labels) ++
|
||||||
|
nl:Comment "--- Record types ---":
|
||||||
|
concatMap recordType recs)
|
||||||
where
|
where
|
||||||
nl = Comment ""
|
nl = Comment ""
|
||||||
|
recs = S.toList (S.difference (records (lcs,lns)) common_records)
|
||||||
|
|
||||||
labels = S.difference (S.unions (map S.fromList recs)) common_labels
|
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_records = S.fromList [[label_s]]
|
||||||
common_labels = 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
|
signature (CatDef c _) = TypeSig lf (Fun abs (pure lin))
|
||||||
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))
|
|
||||||
where
|
where
|
||||||
abs = tcon0 (prefixIdent "A." (gId c))
|
abs = tcon0 (prefixIdent "A." (gId c))
|
||||||
lin = tcon0 lc
|
lin = tcon0 lc
|
||||||
lf = prefixIdent "lin" c
|
lf = linfunName c
|
||||||
lc = prefixIdent "Lin" c
|
lc = lincatName c
|
||||||
|
|
||||||
emptydefs = map emptydef (S.toList emptyCats)
|
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
|
emptyCats = allcats `S.difference` linfuncats
|
||||||
cats = S.fromList [c|Right (c,_)<-defs]
|
where
|
||||||
allcats = S.fromList [c|((_,c),AbsCat (Just _))<-allOrigInfos gr absname]
|
--funcats = S.fromList [c | FunDef f (C.Type _ (TypeApp c _))<-funs]
|
||||||
|
allcats = S.fromList [c | CatDef c _<-cats]
|
||||||
|
|
||||||
params = S.toList . S.unions . map params1
|
gId :: ToIdent i => i -> Ident
|
||||||
params1 (Left (_,rhs)) = paramTypes gr rhs
|
gId = (if haskellOption opts HaskellNoPrefix then id else prefixIdent "G")
|
||||||
params1 (Right (_,(_,rhs))) = tableTypes gr [rhs]
|
. toIdent
|
||||||
|
|
||||||
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
|
va = haskellOption opts HaskellVariants
|
||||||
pure = if va then ListT else id
|
pure = if va then ListT else id
|
||||||
|
|
||||||
neededParamTypes have [] = []
|
haskPreamble :: ModId -> ModId -> Doc
|
||||||
neededParamTypes have (q:qs) =
|
haskPreamble absname cncname =
|
||||||
if q `S.member` have
|
"{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, LambdaCase #-}" $$
|
||||||
then neededParamTypes have qs
|
"module" <+> cncname <+> "where" $$
|
||||||
else let ((got,need),def) = paramType va gId gr q
|
"import Prelude hiding (Ordering(..))" $$
|
||||||
in def++neededParamTypes (S.union got have) (S.toList need++qs)
|
"import Control.Applicative((<$>),(<*>))" $$
|
||||||
|
"import PGF.Haskell" $$
|
||||||
haskPreamble :: Bool -> ModuleName -> ModuleName -> Doc
|
"import qualified" <+> absname <+> "as A" $$
|
||||||
haskPreamble va absname cncname =
|
"" $$
|
||||||
"{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, LambdaCase #-}" $$
|
"--- Standard definitions ---" $$
|
||||||
"module" <+> cncname <+> "where" $$
|
"linString (A.GString s) ="<+>pure "R_s [TK s]" $$
|
||||||
"import Prelude hiding (Ordering(..))" $$
|
"linInt (A.GInt i) ="<+>pure "R_s [TK (show i)]" $$
|
||||||
"import Control.Applicative((<$>),(<*>))" $$
|
"linFloat (A.GFloat x) ="<+>pure "R_s [TK (show x)]" $$
|
||||||
"import PGF.Haskell" $$
|
"" $$
|
||||||
"import qualified" <+> absname <+> "as A" $$
|
"----------------------------------------------------" $$
|
||||||
"" $$
|
"-- Automatic translation from GF to Haskell follows" $$
|
||||||
"--- 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))]
|
|
||||||
where
|
where
|
||||||
Ok abstype = lookupFunType gr absname name
|
pure = if va then brackets else pp
|
||||||
(absctx,_abscat,_absargs) = typeForm abstype
|
|
||||||
|
|
||||||
e' = unAbs (length params) $
|
paramDef pd =
|
||||||
nf loc (mkAbs params (mkApp def (map Vr args)))
|
case pd of
|
||||||
params = [(b,prefixIdent "g" x)|(b,x,_)<-ctx]
|
ParamAliasDef p t -> H.Type (conap0 (gId p)) (convLinType t)
|
||||||
args = map snd params
|
ParamDef p pvs -> Data (conap0 (gId p)) (map paramCon pvs) derive
|
||||||
abs_args = map (prefixIdent "abs_") args
|
where
|
||||||
lhs = [ConP (aId name) (map VarP abs_args)]
|
paramCon (Param c cs) = ConAp (gId c) (map (tcon0.gId) cs)
|
||||||
rhs = foldr letlin e' (zip args absctx)
|
derive = ["Eq","Ord","Show"]
|
||||||
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)
|
|
||||||
|
|
||||||
unAbs 0 t = t
|
convLinType = ppT
|
||||||
unAbs n (Abs _ _ t) = unAbs (n-1) t
|
where
|
||||||
unAbs _ t = t
|
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)
|
class Records t where
|
||||||
where
|
records :: t -> S.Set [LabelId]
|
||||||
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 =
|
instance Records t => Records [t] where
|
||||||
case t of
|
records = S.unions . map records
|
||||||
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
|
instance (Records t1,Records t2) => Records (t1,t2) where
|
||||||
|
records (t1,t2) = S.union (records t1) (records t2)
|
||||||
|
|
||||||
|
instance Records LincatDef where
|
||||||
records ts = S.unions (map recs ts)
|
records (LincatDef _ lt) = records lt
|
||||||
where
|
|
||||||
recs t =
|
instance Records LinDef where
|
||||||
case t of
|
records (LinDef _ _ lv) = records lv
|
||||||
R r -> S.insert (labels r) (records (map (snd.snd) r))
|
|
||||||
RecType r -> S.insert (labels r) (records (map snd r))
|
instance Records LinType where
|
||||||
_ -> collectOp recs t
|
records t =
|
||||||
|
case t of
|
||||||
labels = sort . filter (not . isLockLabel) . map fst
|
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 =
|
coerce env ty t =
|
||||||
case (ty,t) of
|
case (ty,t) of
|
||||||
(_,Let d t) -> Let d (coerce (extend env d) ty t)
|
(_,VariantValue ts) -> VariantValue (map (coerce env ty) ts)
|
||||||
(_,FV ts) -> FV (map (coerce env ty) ts)
|
(TableType ti tv,TableValue _ cs) ->
|
||||||
(Table ti tv,V _ ts) -> V ti (map (coerce env tv) ts)
|
TableValue ti [TableRow p (coerce env tv t)|TableRow p t<-cs]
|
||||||
(Table ti tv,T (TTyped _) cs) -> T (TTyped ti) (mapSnd (coerce env tv) cs)
|
(RecordType rt,RecordValue r) ->
|
||||||
(RecType rt,R r) ->
|
RecordValue [RecordRow l (coerce env ft f) |
|
||||||
R [(l,(Just ft,coerce env ft f))|(l,(_,f))<-r,Just ft<-[lookup l rt]]
|
RecordRow l f<-r,ft<-[ft|RecordRow l' ft<-rt,l'==l]]
|
||||||
(RecType rt,Vr x)->
|
(RecordType rt,VarValue x)->
|
||||||
case lookup x env of
|
case lookup x env of
|
||||||
Just ty' | ty'/=ty -> -- better to compare to normal form of ty'
|
Just ty' | ty'/=ty -> -- better to compare to normal form of ty'
|
||||||
--trace ("coerce "++render ty'++" to "++render ty) $
|
--trace ("coerce "++render ty'++" to "++render ty) $
|
||||||
App (to_rcon (map fst rt)) t
|
app (to_rcon rt) [t]
|
||||||
_ -> trace ("no coerce to "++render ty) t
|
| otherwise -> t -- types match, no coercion needed
|
||||||
|
_ -> trace (render ("missing type to coerce"<+>x<+>"to"<+>render ty
|
||||||
|
$$ "in" <+> map fst env))
|
||||||
|
t
|
||||||
_ -> t
|
_ -> t
|
||||||
where
|
where
|
||||||
extend env (x,(Just ty,rhs)) = (x,ty):env
|
app f ts = ParamConstant (Param f ts) -- !! a hack
|
||||||
extend env _ = env
|
to_rcon = ParamId . Unqual . to_rcon' . labels
|
||||||
|
|
||||||
convert va gId gr = convert' va gId [] gr
|
patVars p = []
|
||||||
|
|
||||||
convert' va gId vs gr = ppT
|
labels r = [l|RecordRow l _<-r]
|
||||||
where
|
|
||||||
ppT0 = convert' False gId vs gr
|
|
||||||
ppTv vs' = convert' va gId vs' gr
|
|
||||||
|
|
||||||
ppT t =
|
proj = Var . identS . proj'
|
||||||
case t of
|
proj' (LabelId l) = "proj_"++l
|
||||||
-- Only for 'let' inserted on the top-level by this converter:
|
rcon = Var . rcon'
|
||||||
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
|
|
||||||
rcon' = identS . rcon_name
|
rcon' = identS . rcon_name
|
||||||
rcon_name ls = "R"++concat (sort ['_':render l|l<-ls,not (isLockLabel l)])
|
rcon_name ls = "R"++concat (sort ['_':l|LabelId l<-ls])
|
||||||
to_rcon = con . to_rcon'
|
|
||||||
to_rcon' = ("to_"++) . rcon_name
|
to_rcon' = ("to_"++) . rcon_name
|
||||||
|
|
||||||
recordType ls =
|
recordType ls =
|
||||||
@@ -400,31 +386,6 @@ labelClass l =
|
|||||||
r = identS "r"
|
r = identS "r"
|
||||||
a = identS "a"
|
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 =
|
enumCon name arity =
|
||||||
if arity==0
|
if arity==0
|
||||||
then single (Var name)
|
then single (Var name)
|
||||||
@@ -433,5 +394,23 @@ enumCon name arity =
|
|||||||
ap (List [f]) a = Op f "<$>" a
|
ap (List [f]) a = Op f "<$>" a
|
||||||
ap f a = Op f "<*>" a
|
ap f a = Op f "<*>" a
|
||||||
|
|
||||||
qual :: ModuleName -> Ident -> Ident
|
lincatName,linfunName :: CatId -> Ident
|
||||||
qual m = prefixIdent (render m++"_")
|
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,11 +3,7 @@ module GF.Compile.ExampleBased (
|
|||||||
configureExBased
|
configureExBased
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import PGF
|
import PGF2
|
||||||
--import PGF.Probabilistic
|
|
||||||
--import PGF.Morphology
|
|
||||||
--import GF.Compile.ToAPI
|
|
||||||
|
|
||||||
import Data.List
|
import Data.List
|
||||||
|
|
||||||
parseExamplesInGrammar :: ExConfiguration -> FilePath -> IO (FilePath,[String])
|
parseExamplesInGrammar :: ExConfiguration -> FilePath -> IO (FilePath,[String])
|
||||||
@@ -37,47 +33,38 @@ convertFile conf src file = do
|
|||||||
(ex, end) = break (=='"') (tail exend)
|
(ex, end) = break (=='"') (tail exend)
|
||||||
in ((unwords (words cat),ex), tail end) -- quotes ignored
|
in ((unwords (words cat),ex), tail end) -- quotes ignored
|
||||||
pgf = resource_pgf conf
|
pgf = resource_pgf conf
|
||||||
morpho = resource_morpho conf
|
|
||||||
lang = language conf
|
lang = language conf
|
||||||
convEx (cat,ex) = do
|
convEx (cat,ex) = do
|
||||||
appn "("
|
appn "("
|
||||||
let typ = maybe (error "no valid cat") id $ readType cat
|
let typ = maybe (error "no valid cat") id $ readType cat
|
||||||
ws <- case fst (parse_ pgf lang typ (Just 4) ex) of
|
ws <- case parse lang typ ex of
|
||||||
ParseFailed _ -> do
|
ParseFailed _ _ -> do
|
||||||
let ws = morphoMissing morpho (words ex)
|
|
||||||
appv ("WARNING: cannot parse example " ++ ex)
|
appv ("WARNING: cannot parse example " ++ ex)
|
||||||
case ws of
|
|
||||||
[] -> return ()
|
|
||||||
_ -> appv (" missing words: " ++ unwords ws)
|
|
||||||
return ws
|
|
||||||
TypeError _ ->
|
|
||||||
return []
|
return []
|
||||||
ParseIncomplete ->
|
ParseIncomplete ->
|
||||||
return []
|
return []
|
||||||
ParseOk ts ->
|
ParseOk ts ->
|
||||||
case rank ts of
|
case ts of
|
||||||
(t:tt) -> do
|
(t:tt) -> do
|
||||||
if null tt
|
if null tt
|
||||||
then return ()
|
then return ()
|
||||||
else appv ("WARNING: ambiguous example " ++ ex)
|
else appv ("WARNING: ambiguous example " ++ ex)
|
||||||
appn t
|
appn (printExp conf (fst t))
|
||||||
mapM_ (appn . (" --- " ++)) tt
|
mapM_ (appn . (" --- " ++) . printExp conf . fst) tt
|
||||||
appn ")"
|
appn ")"
|
||||||
return []
|
return []
|
||||||
return ws
|
return ws
|
||||||
rank ts = [printExp conf t ++ " -- " ++ show p | (t,p) <- rankTreesByProbs pgf ts]
|
|
||||||
appf = appendFile file
|
appf = appendFile file
|
||||||
appn s = appf s >> appf "\n"
|
appn s = appf s >> appf "\n"
|
||||||
appv s = appn ("--- " ++ s) >> putStrLn s
|
appv s = appn ("--- " ++ s) >> putStrLn s
|
||||||
|
|
||||||
data ExConfiguration = ExConf {
|
data ExConfiguration = ExConf {
|
||||||
resource_pgf :: PGF,
|
resource_pgf :: PGF,
|
||||||
resource_morpho :: Morpho,
|
|
||||||
verbose :: Bool,
|
verbose :: Bool,
|
||||||
language :: Language,
|
language :: Concr,
|
||||||
printExp :: Tree -> String
|
printExp :: Expr -> String
|
||||||
}
|
}
|
||||||
|
|
||||||
configureExBased :: PGF -> Morpho -> Language -> (Tree -> String) -> ExConfiguration
|
configureExBased :: PGF -> Concr -> (Expr -> String) -> ExConfiguration
|
||||||
configureExBased pgf morpho lang pr = ExConf pgf morpho False lang pr
|
configureExBased pgf concr pr = ExConf pgf False concr pr
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
module GF.Compile.Export where
|
module GF.Compile.Export where
|
||||||
|
|
||||||
import PGF
|
import PGF2
|
||||||
import PGF.Internal(ppPGF)
|
|
||||||
import GF.Compile.PGFtoHaskell
|
import GF.Compile.PGFtoHaskell
|
||||||
|
--import GF.Compile.PGFtoAbstract
|
||||||
import GF.Compile.PGFtoJava
|
import GF.Compile.PGFtoJava
|
||||||
import GF.Compile.PGFtoProlog
|
import GF.Compile.PGFtoJSON
|
||||||
import GF.Compile.PGFtoJS
|
|
||||||
import GF.Compile.PGFtoPython
|
|
||||||
import GF.Infra.Option
|
import GF.Infra.Option
|
||||||
--import GF.Speech.CFG
|
--import GF.Speech.CFG
|
||||||
import GF.Speech.PGFToCFG
|
import GF.Speech.PGFToCFG
|
||||||
@@ -20,6 +18,7 @@ import GF.Speech.SLF
|
|||||||
import GF.Speech.PrRegExp
|
import GF.Speech.PrRegExp
|
||||||
|
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
|
import qualified Data.Map as Map
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import GF.Text.Pretty
|
import GF.Text.Pretty
|
||||||
|
|
||||||
@@ -33,12 +32,12 @@ exportPGF :: Options
|
|||||||
-> [(FilePath,String)] -- ^ List of recommended file names and contents.
|
-> [(FilePath,String)] -- ^ List of recommended file names and contents.
|
||||||
exportPGF opts fmt pgf =
|
exportPGF opts fmt pgf =
|
||||||
case fmt of
|
case fmt of
|
||||||
FmtPGFPretty -> multi "txt" (render . ppPGF)
|
FmtPGFPretty -> multi "txt" (showPGF)
|
||||||
FmtJavaScript -> multi "js" pgf2js
|
FmtCanonicalGF -> [] -- canon "gf" (render80 . abstract2canonical)
|
||||||
FmtPython -> multi "py" pgf2python
|
FmtCanonicalJson-> []
|
||||||
|
FmtJSON -> multi "json" pgf2json
|
||||||
FmtHaskell -> multi "hs" (grammar2haskell opts name)
|
FmtHaskell -> multi "hs" (grammar2haskell opts name)
|
||||||
FmtJava -> multi "java" (grammar2java opts name)
|
FmtJava -> multi "java" (grammar2java opts name)
|
||||||
FmtProlog -> multi "pl" grammar2prolog
|
|
||||||
FmtBNF -> single "bnf" bnfPrinter
|
FmtBNF -> single "bnf" bnfPrinter
|
||||||
FmtEBNF -> single "ebnf" (ebnfPrinter opts)
|
FmtEBNF -> single "ebnf" (ebnfPrinter opts)
|
||||||
FmtSRGS_XML -> single "grxml" (srgsXmlPrinter opts)
|
FmtSRGS_XML -> single "grxml" (srgsXmlPrinter opts)
|
||||||
@@ -52,17 +51,13 @@ exportPGF opts fmt pgf =
|
|||||||
FmtRegExp -> single "rexp" regexpPrinter
|
FmtRegExp -> single "rexp" regexpPrinter
|
||||||
FmtFA -> single "dot" slfGraphvizPrinter
|
FmtFA -> single "dot" slfGraphvizPrinter
|
||||||
where
|
where
|
||||||
name = fromMaybe (showCId (abstractName pgf)) (flag optName opts)
|
name = fromMaybe (abstractName pgf) (flag optName opts)
|
||||||
|
|
||||||
multi :: String -> (PGF -> String) -> [(FilePath,String)]
|
multi :: String -> (PGF -> String) -> [(FilePath,String)]
|
||||||
multi ext pr = [(name <.> ext, pr pgf)]
|
multi ext pr = [(name <.> ext, pr pgf)]
|
||||||
|
|
||||||
single :: String -> (PGF -> CId -> String) -> [(FilePath,String)]
|
-- canon ext pr = [("canonical"</>name<.>ext,pr pgf)]
|
||||||
single ext pr = [(showCId cnc <.> ext, pr pgf cnc) | cnc <- languages pgf]
|
|
||||||
|
single :: String -> (PGF -> Concr -> String) -> [(FilePath,String)]
|
||||||
|
single ext pr = [(concreteName cnc <.> ext, pr pgf cnc) | cnc <- Map.elems (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
|
|
||||||
outputConcr pgf = case languages pgf of
|
|
||||||
[] -> error "No concrete syntax."
|
|
||||||
cnc:_ -> cnc
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
|
{-# LANGUAGE CPP #-}
|
||||||
module GF.Compile.GenerateBC(generateByteCode) where
|
module GF.Compile.GenerateBC(generateByteCode) where
|
||||||
|
|
||||||
import GF.Grammar
|
import GF.Grammar
|
||||||
import GF.Grammar.Lookup(lookupAbsDef,lookupFunType)
|
import GF.Grammar.Lookup(lookupAbsDef,lookupFunType)
|
||||||
import GF.Data.Operations
|
import GF.Data.Operations
|
||||||
import PGF(CId,utf8CId)
|
import PGF2.Internal(CodeLabel,Instr(..),IVal(..),TailInfo(..),Literal(..))
|
||||||
import PGF.Internal(CodeLabel,Instr(..),IVal(..),TailInfo(..),Literal(..))
|
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import Data.List(nub,mapAccumL)
|
import Data.List(nub,mapAccumL)
|
||||||
import Data.Maybe(fromMaybe)
|
import Data.Maybe(fromMaybe)
|
||||||
@@ -63,7 +63,7 @@ compileEquations gr arity st (i:is) eqs fl bs = whilePP eqs Map.empty
|
|||||||
|
|
||||||
case_instr t =
|
case_instr t =
|
||||||
case t of
|
case t of
|
||||||
(Q (_,id)) -> CASE (i2i id)
|
(Q (_,id)) -> CASE (showIdent id)
|
||||||
(EInt n) -> CASE_LIT (LInt n)
|
(EInt n) -> CASE_LIT (LInt n)
|
||||||
(K s) -> CASE_LIT (LStr s)
|
(K s) -> CASE_LIT (LStr s)
|
||||||
(EFloat d) -> CASE_LIT (LFlt d)
|
(EFloat d) -> CASE_LIT (LFlt d)
|
||||||
@@ -105,7 +105,7 @@ compileFun gr eval st vs (App e1 e2) h0 bs args =
|
|||||||
compileFun gr eval st vs (Q (m,id)) h0 bs args =
|
compileFun gr eval st vs (Q (m,id)) h0 bs args =
|
||||||
case lookupAbsDef gr m id of
|
case lookupAbsDef gr m id of
|
||||||
Ok (_,Just _)
|
Ok (_,Just _)
|
||||||
-> (h0,bs,eval st (GLOBAL (i2i id)) args)
|
-> (h0,bs,eval st (GLOBAL (showIdent id)) args)
|
||||||
_ -> let Ok ty = lookupFunType gr m id
|
_ -> let Ok ty = lookupFunType gr m id
|
||||||
(ctxt,_,_) = typeForm ty
|
(ctxt,_,_) = typeForm ty
|
||||||
c_arity = length ctxt
|
c_arity = length ctxt
|
||||||
@@ -114,14 +114,14 @@ compileFun gr eval st vs (Q (m,id)) h0 bs args =
|
|||||||
diff = c_arity-n_args
|
diff = c_arity-n_args
|
||||||
in if diff <= 0
|
in if diff <= 0
|
||||||
then if n_args == 0
|
then if n_args == 0
|
||||||
then (h0,bs,eval st (GLOBAL (i2i id)) [])
|
then (h0,bs,eval st (GLOBAL (showIdent id)) [])
|
||||||
else let h1 = h0 + 2 + n_args
|
else let h1 = h0 + 2 + n_args
|
||||||
in (h1,bs,PUT_CONSTR (i2i id):is1++eval st (HEAP h0) [])
|
in (h1,bs,PUT_CONSTR (showIdent id):is1++eval st (HEAP h0) [])
|
||||||
else let h1 = h0 + 1 + n_args
|
else let h1 = h0 + 1 + n_args
|
||||||
is2 = [SET (FREE_VAR i) | i <- [0..n_args-1]] ++ [SET (ARG_VAR (i+1)) | i <- [0..diff-1]]
|
is2 = [SET (FREE_VAR i) | i <- [0..n_args-1]] ++ [SET (ARG_VAR (i+1)) | i <- [0..diff-1]]
|
||||||
b = CHECK_ARGS diff :
|
b = CHECK_ARGS diff :
|
||||||
ALLOC (c_arity+2) :
|
ALLOC (c_arity+2) :
|
||||||
PUT_CONSTR (i2i id) :
|
PUT_CONSTR (showIdent id) :
|
||||||
is2 ++
|
is2 ++
|
||||||
TUCK (ARG_VAR 0) diff :
|
TUCK (ARG_VAR 0) diff :
|
||||||
EVAL (HEAP h0) (TailCall diff) :
|
EVAL (HEAP h0) (TailCall diff) :
|
||||||
@@ -167,16 +167,16 @@ compileFun gr eval st vs e _ _ _ = error (show e)
|
|||||||
|
|
||||||
compileArg gr st vs (Q(m,id)) h0 bs =
|
compileArg gr st vs (Q(m,id)) h0 bs =
|
||||||
case lookupAbsDef gr m id of
|
case lookupAbsDef gr m id of
|
||||||
Ok (_,Just _) -> (h0,bs,GLOBAL (i2i id),[])
|
Ok (_,Just _) -> (h0,bs,GLOBAL (showIdent id),[])
|
||||||
_ -> let Ok ty = lookupFunType gr m id
|
_ -> let Ok ty = lookupFunType gr m id
|
||||||
(ctxt,_,_) = typeForm ty
|
(ctxt,_,_) = typeForm ty
|
||||||
c_arity = length ctxt
|
c_arity = length ctxt
|
||||||
in if c_arity == 0
|
in if c_arity == 0
|
||||||
then (h0,bs,GLOBAL (i2i id),[])
|
then (h0,bs,GLOBAL (showIdent id),[])
|
||||||
else let is2 = [SET (ARG_VAR (i+1)) | i <- [0..c_arity-1]]
|
else let is2 = [SET (ARG_VAR (i+1)) | i <- [0..c_arity-1]]
|
||||||
b = CHECK_ARGS c_arity :
|
b = CHECK_ARGS c_arity :
|
||||||
ALLOC (c_arity+2) :
|
ALLOC (c_arity+2) :
|
||||||
PUT_CONSTR (i2i id) :
|
PUT_CONSTR (showIdent id) :
|
||||||
is2 ++
|
is2 ++
|
||||||
TUCK (ARG_VAR 0) c_arity :
|
TUCK (ARG_VAR 0) c_arity :
|
||||||
EVAL (HEAP h0) (TailCall c_arity) :
|
EVAL (HEAP h0) (TailCall c_arity) :
|
||||||
@@ -224,12 +224,12 @@ compileArg gr st vs e h0 bs =
|
|||||||
diff = c_arity-n_args
|
diff = c_arity-n_args
|
||||||
in if diff <= 0
|
in if diff <= 0
|
||||||
then let h2 = h1 + 2 + n_args
|
then let h2 = h1 + 2 + n_args
|
||||||
in (h2,bs1,HEAP h1,is1 ++ (PUT_CONSTR (i2i id) : is2))
|
in (h2,bs1,HEAP h1,is1 ++ (PUT_CONSTR (showIdent id) : is2))
|
||||||
else let h2 = h1 + 1 + n_args
|
else let h2 = h1 + 1 + n_args
|
||||||
is2 = [SET (FREE_VAR i) | i <- [0..n_args-1]] ++ [SET (ARG_VAR (i+1)) | i <- [0..diff-1]]
|
is2 = [SET (FREE_VAR i) | i <- [0..n_args-1]] ++ [SET (ARG_VAR (i+1)) | i <- [0..diff-1]]
|
||||||
b = CHECK_ARGS diff :
|
b = CHECK_ARGS diff :
|
||||||
ALLOC (c_arity+2) :
|
ALLOC (c_arity+2) :
|
||||||
PUT_CONSTR (i2i id) :
|
PUT_CONSTR (showIdent id) :
|
||||||
is2 ++
|
is2 ++
|
||||||
TUCK (ARG_VAR 0) diff :
|
TUCK (ARG_VAR 0) diff :
|
||||||
EVAL (HEAP h0) (TailCall diff) :
|
EVAL (HEAP h0) (TailCall diff) :
|
||||||
@@ -298,9 +298,6 @@ freeVars xs (Vr x)
|
|||||||
| not (elem x xs) = [x]
|
| not (elem x xs) = [x]
|
||||||
freeVars xs e = collectOp (freeVars xs) e
|
freeVars xs e = collectOp (freeVars xs) e
|
||||||
|
|
||||||
i2i :: Ident -> CId
|
|
||||||
i2i = utf8CId . ident2utf8
|
|
||||||
|
|
||||||
push_is :: Int -> Int -> [IVal] -> [IVal]
|
push_is :: Int -> Int -> [IVal] -> [IVal]
|
||||||
push_is i 0 is = is
|
push_is i 0 is = is
|
||||||
push_is i n is = ARG_VAR i : push_is (i-1) (n-1) is
|
push_is i n is = ARG_VAR i : push_is (i-1) (n-1) is
|
||||||
|
|||||||
@@ -13,8 +13,9 @@ module GF.Compile.GeneratePMCFG
|
|||||||
(generatePMCFG, pgfCncCat, addPMCFG, resourceValues
|
(generatePMCFG, pgfCncCat, addPMCFG, resourceValues
|
||||||
) where
|
) where
|
||||||
|
|
||||||
--import PGF.CId
|
import qualified PGF2 as PGF2
|
||||||
import PGF.Internal as PGF(CncCat(..),Symbol(..),fidVar)
|
import qualified PGF2.Internal as PGF2
|
||||||
|
import PGF2.Internal(Symbol(..),fidVar)
|
||||||
|
|
||||||
import GF.Infra.Option
|
import GF.Infra.Option
|
||||||
import GF.Grammar hiding (Env, mkRecord, mkTable)
|
import GF.Grammar hiding (Env, mkRecord, mkTable)
|
||||||
@@ -68,7 +69,7 @@ mapAccumWithKeyM f a m = do let xs = Map.toAscList m
|
|||||||
|
|
||||||
|
|
||||||
--addPMCFG :: Options -> SourceGrammar -> GlobalEnv -> Maybe FilePath -> Ident -> Ident -> SeqSet -> Ident -> Info -> IOE (SeqSet, Info)
|
--addPMCFG :: Options -> SourceGrammar -> GlobalEnv -> Maybe FilePath -> Ident -> Ident -> SeqSet -> Ident -> Info -> IOE (SeqSet, Info)
|
||||||
addPMCFG opts gr cenv opath am cm seqs id (GF.Grammar.CncFun mty@(Just (cat,cont,val)) mlin@(Just (L loc term)) mprn Nothing) = do
|
addPMCFG opts gr cenv opath am cm seqs id (CncFun mty@(Just (cat,cont,val)) mlin@(Just (L loc term)) mprn Nothing) = do
|
||||||
--when (verbAtLeast opts Verbose) $ ePutStr ("\n+ "++showIdent id++" ...")
|
--when (verbAtLeast opts Verbose) $ ePutStr ("\n+ "++showIdent id++" ...")
|
||||||
let pres = protoFCat gr res val
|
let pres = protoFCat gr res val
|
||||||
pargs = [protoFCat gr (snd $ catSkeleton ty) lincat | ((_,_,ty),(_,_,lincat)) <- zip ctxt cont]
|
pargs = [protoFCat gr (snd $ catSkeleton ty) lincat | ((_,_,ty),(_,_,lincat)) <- zip ctxt cont]
|
||||||
@@ -92,7 +93,7 @@ addPMCFG opts gr cenv opath am cm seqs id (GF.Grammar.CncFun mty@(Just (cat,cont
|
|||||||
ePutStr ("\n+ "++showIdent id++" "++show (product (map catFactor pargs)))
|
ePutStr ("\n+ "++showIdent id++" "++show (product (map catFactor pargs)))
|
||||||
seqs1 `seq` stats `seq` return ()
|
seqs1 `seq` stats `seq` return ()
|
||||||
when (verbAtLeast opts Verbose) $ ePutStr (" "++show stats)
|
when (verbAtLeast opts Verbose) $ ePutStr (" "++show stats)
|
||||||
return (seqs1,GF.Grammar.CncFun mty mlin mprn (Just pmcfg))
|
return (seqs1,CncFun mty mlin mprn (Just pmcfg))
|
||||||
where
|
where
|
||||||
(ctxt,res,_) = err bug typeForm (lookupFunType gr am id)
|
(ctxt,res,_) = err bug typeForm (lookupFunType gr am id)
|
||||||
|
|
||||||
@@ -102,11 +103,11 @@ addPMCFG opts gr cenv opath am cm seqs id (GF.Grammar.CncFun mty@(Just (cat,cont
|
|||||||
newArgs = map getFIds newArgs'
|
newArgs = map getFIds newArgs'
|
||||||
in addFunction env0 newCat fun newArgs
|
in addFunction env0 newCat fun newArgs
|
||||||
|
|
||||||
addPMCFG opts gr cenv opath am cm seqs id (GF.Grammar.CncCat mty@(Just (L _ lincat))
|
addPMCFG opts gr cenv opath am cm seqs id (CncCat mty@(Just (L _ lincat))
|
||||||
mdef@(Just (L loc1 def))
|
mdef@(Just (L loc1 def))
|
||||||
mref@(Just (L loc2 ref))
|
mref@(Just (L loc2 ref))
|
||||||
mprn
|
mprn
|
||||||
Nothing) = do
|
Nothing) = do
|
||||||
let pcat = protoFCat gr (am,id) lincat
|
let pcat = protoFCat gr (am,id) lincat
|
||||||
pvar = protoFCat gr (MN identW,cVar) typeStr
|
pvar = protoFCat gr (MN identW,cVar) typeStr
|
||||||
|
|
||||||
@@ -131,7 +132,7 @@ addPMCFG opts gr cenv opath am cm seqs id (GF.Grammar.CncCat mty@(Just (L _ linc
|
|||||||
let pmcfg = getPMCFG pmcfgEnv2
|
let pmcfg = getPMCFG pmcfgEnv2
|
||||||
|
|
||||||
when (verbAtLeast opts Verbose) $ ePutStr ("\n+ "++showIdent id++" "++show (catFactor pcat))
|
when (verbAtLeast opts Verbose) $ ePutStr ("\n+ "++showIdent id++" "++show (catFactor pcat))
|
||||||
seqs2 `seq` pmcfg `seq` return (seqs2,GF.Grammar.CncCat mty mdef mref mprn (Just pmcfg))
|
seqs2 `seq` pmcfg `seq` return (seqs2,CncCat mty mdef mref mprn (Just pmcfg))
|
||||||
where
|
where
|
||||||
addLindef lins (newCat', newArgs') env0 =
|
addLindef lins (newCat', newArgs') env0 =
|
||||||
let [newCat] = getFIds newCat'
|
let [newCat] = getFIds newCat'
|
||||||
@@ -157,12 +158,15 @@ convert opts gr cenv loc term ty@(_,val) pargs =
|
|||||||
args = map Vr vars
|
args = map Vr vars
|
||||||
vars = map (\(bt,x,t) -> x) context
|
vars = map (\(bt,x,t) -> x) context
|
||||||
|
|
||||||
pgfCncCat :: SourceGrammar -> Type -> Int -> CncCat
|
pgfCncCat :: SourceGrammar -> PGF2.Cat -> Type -> Int -> (PGF2.Cat,Int,Int,[String])
|
||||||
pgfCncCat gr lincat index =
|
pgfCncCat gr id lincat index =
|
||||||
let ((_,size),schema) = computeCatRange gr lincat
|
let ((_,size),schema) = computeCatRange gr lincat
|
||||||
in PGF.CncCat index (index+size-1)
|
in ( id
|
||||||
(mkArray (map (renderStyle style{mode=OneLineMode} . ppPath)
|
, index
|
||||||
(getStrPaths schema)))
|
, index+size-1
|
||||||
|
, map (renderStyle style{mode=OneLineMode} . ppPath)
|
||||||
|
(getStrPaths schema)
|
||||||
|
)
|
||||||
where
|
where
|
||||||
getStrPaths :: Schema Identity s c -> [Path]
|
getStrPaths :: Schema Identity s c -> [Path]
|
||||||
getStrPaths = collect CNil []
|
getStrPaths = collect CNil []
|
||||||
@@ -471,7 +475,7 @@ goV (CPar t) rpath ss = restrictHead (reversePath rpath) t >> return ss
|
|||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
-- SeqSet
|
-- SeqSet
|
||||||
|
|
||||||
type SeqSet = Map.Map Sequence SeqId
|
type SeqSet = Map.Map [Symbol] SeqId
|
||||||
|
|
||||||
addSequencesB :: SeqSet -> Branch (Value [Symbol]) -> (SeqSet, Branch (Value SeqId))
|
addSequencesB :: SeqSet -> Branch (Value [Symbol]) -> (SeqSet, Branch (Value SeqId))
|
||||||
addSequencesB seqs (Case nr path bs) = let !(seqs1,bs1) = mapAccumL' (\seqs (trm,b) -> let !(seqs',b') = addSequencesB seqs b
|
addSequencesB seqs (Case nr path bs) = let !(seqs1,bs1) = mapAccumL' (\seqs (trm,b) -> let !(seqs',b') = addSequencesB seqs b
|
||||||
@@ -500,13 +504,11 @@ mapAccumL' f s (x:xs) = (s'',y:ys)
|
|||||||
!(s'',ys) = mapAccumL' f s' xs
|
!(s'',ys) = mapAccumL' f s' xs
|
||||||
|
|
||||||
addSequence :: SeqSet -> [Symbol] -> (SeqSet,SeqId)
|
addSequence :: SeqSet -> [Symbol] -> (SeqSet,SeqId)
|
||||||
addSequence seqs lst =
|
addSequence seqs seq =
|
||||||
case Map.lookup seq seqs of
|
case Map.lookup seq seqs of
|
||||||
Just id -> (seqs,id)
|
Just id -> (seqs,id)
|
||||||
Nothing -> let !last_seq = Map.size seqs
|
Nothing -> let !last_seq = Map.size seqs
|
||||||
in (Map.insert seq last_seq seqs, last_seq)
|
in (Map.insert seq last_seq seqs, last_seq)
|
||||||
where
|
|
||||||
seq = mkArray lst
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------
|
------------------------------------------------------------
|
||||||
|
|||||||
@@ -50,20 +50,13 @@ getSourceModule opts file0 =
|
|||||||
Right (i,mi0) ->
|
Right (i,mi0) ->
|
||||||
do liftIO $ removeTemp tmp
|
do liftIO $ removeTemp tmp
|
||||||
let mi =mi0 {mflags=mflags mi0 `addOptions` opts, msrc=file0}
|
let mi =mi0 {mflags=mflags mi0 `addOptions` opts, msrc=file0}
|
||||||
optCoding' = renameEncoding `fmap` flag optEncoding (mflags mi0)
|
case renameEncoding `fmap` flag optEncoding (mflags mi0) of
|
||||||
case (optCoding,optCoding') of
|
Just coding' ->
|
||||||
{-
|
when (coding/=coding') $
|
||||||
(Nothing,Nothing) ->
|
|
||||||
unless (BS.all isAscii raw) $
|
|
||||||
ePutStrLn $ file0++":\n Warning: default encoding has changed from Latin-1 to UTF-8"
|
|
||||||
-}
|
|
||||||
(_,Just coding') ->
|
|
||||||
when (coding/=coding') $
|
|
||||||
raise $ "Encoding mismatch: "++coding++" /= "++coding'
|
raise $ "Encoding mismatch: "++coding++" /= "++coding'
|
||||||
where coding = maybe defaultEncoding renameEncoding optCoding
|
where coding = maybe defaultEncoding renameEncoding optCoding
|
||||||
_ -> return ()
|
_ -> return ()
|
||||||
--liftIO $ transcodeModule' (i,mi) -- old lexer
|
return (i,mi)
|
||||||
return (i,mi) -- new lexer
|
|
||||||
|
|
||||||
getBNFCRules :: Options -> FilePath -> IOE [BNFCRule]
|
getBNFCRules :: Options -> FilePath -> IOE [BNFCRule]
|
||||||
getBNFCRules opts fpath = do
|
getBNFCRules opts fpath = do
|
||||||
|
|||||||
389
src/compiler/GF/Compile/GrammarToCanonical.hs
Normal file
389
src/compiler/GF/Compile/GrammarToCanonical.hs
Normal file
@@ -0,0 +1,389 @@
|
|||||||
|
-- | 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 PGF2.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 Empty = [""] -- Empty == K ""
|
||||||
|
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,23 +1,17 @@
|
|||||||
{-# LANGUAGE BangPatterns, FlexibleContexts #-}
|
{-# LANGUAGE ImplicitParams, BangPatterns, FlexibleContexts, MagicHash #-}
|
||||||
module GF.Compile.GrammarToPGF (mkCanon2pgf) where
|
module GF.Compile.GrammarToPGF (grammar2PGF) where
|
||||||
|
|
||||||
--import GF.Compile.Export
|
|
||||||
import GF.Compile.GeneratePMCFG
|
import GF.Compile.GeneratePMCFG
|
||||||
import GF.Compile.GenerateBC
|
import GF.Compile.GenerateBC
|
||||||
|
import GF.Compile.OptimizePGF
|
||||||
|
|
||||||
import PGF(CId,mkCId,utf8CId)
|
import PGF2 hiding (mkType)
|
||||||
import PGF.Internal(fidInt,fidFloat,fidString,fidVar)
|
import PGF2.Internal
|
||||||
import PGF.Internal(updateProductionIndices)
|
|
||||||
--import qualified PGF.Macros as CM
|
|
||||||
import qualified PGF.Internal as C
|
|
||||||
import qualified PGF.Internal as D
|
|
||||||
import GF.Grammar.Predef
|
import GF.Grammar.Predef
|
||||||
--import GF.Grammar.Printer
|
import GF.Grammar.Grammar hiding (Production)
|
||||||
import GF.Grammar.Grammar
|
|
||||||
import qualified GF.Grammar.Lookup as Look
|
import qualified GF.Grammar.Lookup as Look
|
||||||
import qualified GF.Grammar as A
|
import qualified GF.Grammar as A
|
||||||
import qualified GF.Grammar.Macros as GM
|
import qualified GF.Grammar.Macros as GM
|
||||||
--import GF.Compile.GeneratePMCFG
|
|
||||||
|
|
||||||
import GF.Infra.Ident
|
import GF.Infra.Ident
|
||||||
import GF.Infra.Option
|
import GF.Infra.Option
|
||||||
@@ -25,108 +19,141 @@ import GF.Infra.UseIO (IOE)
|
|||||||
import GF.Data.Operations
|
import GF.Data.Operations
|
||||||
|
|
||||||
import Data.List
|
import Data.List
|
||||||
|
import Data.Char
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import qualified Data.IntMap as IntMap
|
import qualified Data.IntMap as IntMap
|
||||||
import Data.Array.IArray
|
import Data.Array.IArray
|
||||||
|
import Data.Maybe(fromMaybe)
|
||||||
|
|
||||||
mkCanon2pgf :: Options -> SourceGrammar -> ModuleName -> IOE D.PGF
|
import GHC.Prim
|
||||||
mkCanon2pgf opts gr am = do
|
import GHC.Base(getTag)
|
||||||
(an,abs) <- mkAbstr am
|
|
||||||
cncs <- mapM mkConcr (allConcretes gr am)
|
grammar2PGF :: Options -> SourceGrammar -> ModuleName -> Map.Map PGF2.Fun Double -> IO PGF
|
||||||
return $ updateProductionIndices (D.PGF Map.empty an abs (Map.fromList cncs))
|
grammar2PGF opts gr am probs = do
|
||||||
|
cnc_infos <- getConcreteInfos gr am
|
||||||
|
return $
|
||||||
|
build (let gflags = if flag optSplitPGF opts
|
||||||
|
then [("split", LStr "true")]
|
||||||
|
else []
|
||||||
|
(an,abs) = mkAbstr am probs
|
||||||
|
cncs = map (mkConcr opts abs) cnc_infos
|
||||||
|
in newPGF gflags an abs cncs)
|
||||||
where
|
where
|
||||||
cenv = resourceValues opts gr
|
cenv = resourceValues opts gr
|
||||||
|
aflags = err (const noOptions) mflags (lookupModule gr am)
|
||||||
|
|
||||||
mkAbstr am = return (mi2i am, D.Abstr flags funs cats)
|
mkAbstr :: (?builder :: Builder s) => ModuleName -> Map.Map PGF2.Fun Double -> (AbsName, B s AbstrInfo)
|
||||||
|
mkAbstr am probs = (mi2i am, newAbstr flags cats funs)
|
||||||
where
|
where
|
||||||
aflags = err (const noOptions) mflags (lookupModule gr am)
|
|
||||||
|
|
||||||
adefs =
|
adefs =
|
||||||
[((cPredefAbs,c), AbsCat (Just (L NoLoc []))) | c <- [cFloat,cInt,cString]] ++
|
[((cPredefAbs,c), AbsCat (Just (L NoLoc []))) | c <- [cFloat,cInt,cString]] ++
|
||||||
Look.allOrigInfos gr am
|
Look.allOrigInfos gr am
|
||||||
|
|
||||||
flags = Map.fromList [(mkCId f,x) | (f,x) <- optionsPGF aflags]
|
flags = optionsPGF aflags
|
||||||
|
|
||||||
funs = Map.fromList [(i2i f, (mkType [] ty, arity, mkDef gr arity mdef, 0)) |
|
toLogProb = realToFrac . negate . log
|
||||||
|
|
||||||
|
cats = [(c', snd (mkContext [] cont), toLogProb (fromMaybe 0 (Map.lookup c' probs))) |
|
||||||
|
((m,c),AbsCat (Just (L _ cont))) <- adefs, let c' = i2i c]
|
||||||
|
|
||||||
|
funs = [(f', mkType [] ty, arity, bcode, toLogProb (fromMaybe 0 (Map.lookup f' funs_probs))) |
|
||||||
((m,f),AbsFun (Just (L _ ty)) ma mdef _) <- adefs,
|
((m,f),AbsFun (Just (L _ ty)) ma mdef _) <- adefs,
|
||||||
let arity = mkArity ma mdef ty]
|
let arity = mkArity ma mdef ty,
|
||||||
|
let bcode = mkDef gr arity mdef,
|
||||||
|
let f' = i2i f]
|
||||||
|
|
||||||
cats = Map.fromList [(i2i c, (snd (mkContext [] cont),catfuns c, 0)) |
|
funs_probs = (Map.fromList . concat . Map.elems . fmap pad . Map.fromListWith (++))
|
||||||
((m,c),AbsCat (Just (L _ cont))) <- adefs]
|
[(i2i cat,[(i2i f,Map.lookup f' probs)]) | ((m,f),AbsFun (Just (L _ ty)) _ _ _) <- adefs,
|
||||||
|
let (_,(_,cat),_) = GM.typeForm ty,
|
||||||
|
let f' = i2i f]
|
||||||
|
where
|
||||||
|
pad :: [(a,Maybe Double)] -> [(a,Double)]
|
||||||
|
pad pfs = [(f,fromMaybe deflt mb_p) | (f,mb_p) <- pfs]
|
||||||
|
where
|
||||||
|
deflt = case length [f | (f,Nothing) <- pfs] of
|
||||||
|
0 -> 0
|
||||||
|
n -> max 0 ((1 - sum [d | (f,Just d) <- pfs]) / fromIntegral n)
|
||||||
|
|
||||||
catfuns cat =
|
mkConcr opts abs (cm,ex_seqs,cdefs) =
|
||||||
[(0,i2i f) | ((m,f),AbsFun (Just (L _ ty)) _ _ (Just True)) <- adefs, snd (GM.valCat ty) == cat]
|
let cflags = err (const noOptions) mflags (lookupModule gr cm)
|
||||||
|
ciCmp | flag optCaseSensitive cflags = compare
|
||||||
|
| otherwise = compareCaseInsensitive
|
||||||
|
|
||||||
mkConcr cm = do
|
flags = optionsPGF aflags
|
||||||
let cflags = err (const noOptions) mflags (lookupModule gr cm)
|
|
||||||
|
|
||||||
(ex_seqs,cdefs) <- addMissingPMCFGs
|
|
||||||
Map.empty
|
|
||||||
([((cPredefAbs,c), CncCat (Just (L NoLoc GM.defLinType)) Nothing Nothing Nothing Nothing) | c <- [cInt,cFloat,cString]] ++
|
|
||||||
Look.allOrigInfos gr cm)
|
|
||||||
|
|
||||||
let flags = Map.fromList [(mkCId f,x) | (f,x) <- optionsPGF cflags]
|
|
||||||
|
|
||||||
seqs = (mkSetArray . Set.fromList . concat) $
|
seqs = (mkSetArray . Set.fromList . concat) $
|
||||||
(Map.keys ex_seqs : [maybe [] elems (mseqs mi) | (m,mi) <- allExtends gr cm])
|
(elems (ex_seqs :: Array SeqId [Symbol]) : [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_cnt1,!cnccats) = genCncCats gr am cm cdefs
|
||||||
|
cnccat_ranges = Map.fromList (map (\(cid,s,e,_) -> (cid,(s,e))) cnccats)
|
||||||
!(!fid_cnt2,!productions,!lindefs,!linrefs,!cncfuns)
|
!(!fid_cnt2,!productions,!lindefs,!linrefs,!cncfuns)
|
||||||
= genCncFuns gr am cm ex_seqs_arr seqs cdefs fid_cnt1 cnccats
|
= genCncFuns gr am cm ex_seqs ciCmp seqs cdefs fid_cnt1 cnccat_ranges
|
||||||
|
|
||||||
printnames = genPrintNames cdefs
|
printnames = genPrintNames cdefs
|
||||||
return (mi2i cm, D.Concr flags
|
|
||||||
printnames
|
startCat = (fromMaybe "S" (flag optStartCat aflags))
|
||||||
cncfuns
|
|
||||||
lindefs
|
(lindefs',linrefs',productions',cncfuns',sequences',cnccats') =
|
||||||
linrefs
|
(if flag optOptimizePGF opts then optimizePGF startCat else id)
|
||||||
seqs
|
(lindefs,linrefs,productions,cncfuns,elems seqs,cnccats)
|
||||||
productions
|
|
||||||
IntMap.empty
|
in (mi2i cm, newConcr abs
|
||||||
Map.empty
|
flags
|
||||||
cnccats
|
printnames
|
||||||
IntMap.empty
|
lindefs'
|
||||||
fid_cnt2)
|
linrefs'
|
||||||
|
productions'
|
||||||
|
cncfuns'
|
||||||
|
sequences'
|
||||||
|
cnccats'
|
||||||
|
fid_cnt2)
|
||||||
|
|
||||||
|
getConcreteInfos gr am = mapM flatten (allConcretes gr am)
|
||||||
where
|
where
|
||||||
|
flatten cm = do
|
||||||
|
(seqs,infos) <- addMissingPMCFGs cm Map.empty
|
||||||
|
(lit_infos ++ Look.allOrigInfos gr cm)
|
||||||
|
return (cm,mkMapArray seqs :: Array SeqId [Symbol],infos)
|
||||||
|
|
||||||
|
lit_infos = [((cPredefAbs,c), CncCat (Just (L NoLoc GM.defLinType)) Nothing Nothing Nothing Nothing) | c <- [cInt,cFloat,cString]]
|
||||||
|
|
||||||
-- if some module was compiled with -no-pmcfg, then
|
-- if some module was compiled with -no-pmcfg, then
|
||||||
-- we have to create the PMCFG code just before linking
|
-- we have to create the PMCFG code just before linking
|
||||||
addMissingPMCFGs seqs [] = return (seqs,[])
|
addMissingPMCFGs cm seqs [] = return (seqs,[])
|
||||||
addMissingPMCFGs seqs (((m,id), info):is) = do
|
addMissingPMCFGs cm seqs (((m,id), info):is) = do
|
||||||
(seqs,info) <- addPMCFG opts gr cenv Nothing am cm seqs id info
|
(seqs,info) <- addPMCFG opts gr cenv Nothing am cm seqs id info
|
||||||
(seqs,is ) <- addMissingPMCFGs seqs is
|
(seqs,infos) <- addMissingPMCFGs cm seqs is
|
||||||
return (seqs, ((m,id), info) : is)
|
return (seqs, ((m,id), info) : infos)
|
||||||
|
|
||||||
i2i :: Ident -> CId
|
i2i :: Ident -> String
|
||||||
i2i = utf8CId . ident2utf8
|
i2i = showIdent
|
||||||
|
|
||||||
mi2i :: ModuleName -> CId
|
mi2i :: ModuleName -> String
|
||||||
mi2i (MN i) = i2i i
|
mi2i (MN i) = i2i i
|
||||||
|
|
||||||
mkType :: [Ident] -> A.Type -> C.Type
|
mkType :: (?builder :: Builder s) => [Ident] -> A.Type -> B s PGF2.Type
|
||||||
mkType scope t =
|
mkType scope t =
|
||||||
case GM.typeForm t of
|
case GM.typeForm t of
|
||||||
(hyps,(_,cat),args) -> let (scope',hyps') = mkContext scope hyps
|
(hyps,(_,cat),args) -> let (scope',hyps') = mkContext scope hyps
|
||||||
in C.DTyp hyps' (i2i cat) (map (mkExp scope') args)
|
in dTyp hyps' (i2i cat) (map (mkExp scope') args)
|
||||||
|
|
||||||
mkExp :: [Ident] -> A.Term -> C.Expr
|
mkExp :: (?builder :: Builder s) => [Ident] -> A.Term -> B s Expr
|
||||||
mkExp scope t =
|
mkExp scope t =
|
||||||
case t of
|
case t of
|
||||||
Q (_,c) -> C.EFun (i2i c)
|
Q (_,c) -> eFun (i2i c)
|
||||||
QC (_,c) -> C.EFun (i2i c)
|
QC (_,c) -> eFun (i2i c)
|
||||||
Vr x -> case lookup x (zip scope [0..]) of
|
Vr x -> case lookup x (zip scope [0..]) of
|
||||||
Just i -> C.EVar i
|
Just i -> eVar i
|
||||||
Nothing -> C.EMeta 0
|
Nothing -> eMeta 0
|
||||||
Abs b x t-> C.EAbs b (i2i x) (mkExp (x:scope) t)
|
Abs b x t-> eAbs b (i2i x) (mkExp (x:scope) t)
|
||||||
App t1 t2-> C.EApp (mkExp scope t1) (mkExp scope t2)
|
App t1 t2-> eApp (mkExp scope t1) (mkExp scope t2)
|
||||||
EInt i -> C.ELit (C.LInt (fromIntegral i))
|
EInt i -> eLit (LInt (fromIntegral i))
|
||||||
EFloat f -> C.ELit (C.LFlt f)
|
EFloat f -> eLit (LFlt f)
|
||||||
K s -> C.ELit (C.LStr s)
|
K s -> eLit (LStr s)
|
||||||
Meta i -> C.EMeta i
|
Meta i -> eMeta i
|
||||||
_ -> C.EMeta 0
|
_ -> eMeta 0
|
||||||
|
{-
|
||||||
mkPatt scope p =
|
mkPatt scope p =
|
||||||
case p of
|
case p of
|
||||||
A.PP (_,c) ps->let (scope',ps') = mapAccumL mkPatt scope ps
|
A.PP (_,c) ps->let (scope',ps') = mapAccumL mkPatt scope ps
|
||||||
@@ -141,66 +168,64 @@ mkPatt scope p =
|
|||||||
A.PImplArg p-> let (scope',p') = mkPatt scope p
|
A.PImplArg p-> let (scope',p') = mkPatt scope p
|
||||||
in (scope',C.PImplArg p')
|
in (scope',C.PImplArg p')
|
||||||
A.PTilde t -> ( scope,C.PTilde (mkExp scope t))
|
A.PTilde t -> ( scope,C.PTilde (mkExp scope t))
|
||||||
|
-}
|
||||||
mkContext :: [Ident] -> A.Context -> ([Ident],[C.Hypo])
|
mkContext :: (?builder :: Builder s) => [Ident] -> A.Context -> ([Ident],[B s PGF2.Hypo])
|
||||||
mkContext scope hyps = mapAccumL (\scope (bt,x,ty) -> let ty' = mkType scope ty
|
mkContext scope hyps = mapAccumL (\scope (bt,x,ty) -> let ty' = mkType scope ty
|
||||||
in if x == identW
|
in if x == identW
|
||||||
then ( scope,(bt,i2i x,ty'))
|
then ( scope,hypo bt (i2i x) ty')
|
||||||
else (x:scope,(bt,i2i x,ty'))) scope hyps
|
else (x:scope,hypo bt (i2i x) ty')) scope hyps
|
||||||
|
|
||||||
mkDef gr arity (Just eqs) = Just ([C.Equ ps' (mkExp scope' e) | L _ (ps,e) <- eqs, let (scope',ps') = mapAccumL mkPatt [] ps]
|
mkDef gr arity (Just eqs) = generateByteCode gr arity eqs
|
||||||
,generateByteCode gr arity eqs
|
mkDef gr arity Nothing = []
|
||||||
)
|
|
||||||
mkDef gr arity Nothing = Nothing
|
|
||||||
|
|
||||||
mkArity (Just a) _ ty = a -- known arity, i.e. defined function
|
mkArity (Just a) _ ty = a -- known arity, i.e. defined function
|
||||||
mkArity Nothing (Just _) ty = 0 -- defined function with no arity - must be an axiom
|
mkArity Nothing (Just _) ty = 0 -- defined function with no arity - must be an axiom
|
||||||
mkArity Nothing _ ty = let (ctxt, _, _) = GM.typeForm ty -- constructor
|
mkArity Nothing _ ty = let (ctxt, _, _) = GM.typeForm ty -- constructor
|
||||||
in length ctxt
|
in length ctxt
|
||||||
|
|
||||||
genCncCats gr am cm cdefs =
|
genCncCats gr am cm cdefs = mkCncCats 0 cdefs
|
||||||
let (index,cats) = mkCncCats 0 cdefs
|
|
||||||
in (index, Map.fromList cats)
|
|
||||||
where
|
where
|
||||||
mkCncCats index [] = (index,[])
|
mkCncCats index [] = (index,[])
|
||||||
mkCncCats index (((m,id),CncCat (Just (L _ lincat)) _ _ _ _):cdefs)
|
mkCncCats index (((m,id),CncCat (Just (L _ lincat)) _ _ _ _):cdefs)
|
||||||
| id == cInt =
|
| id == cInt =
|
||||||
let cc = pgfCncCat gr lincat fidInt
|
let cc = pgfCncCat gr (i2i id) lincat fidInt
|
||||||
(index',cats) = mkCncCats index cdefs
|
(index',cats) = mkCncCats index cdefs
|
||||||
in (index', (i2i id,cc) : cats)
|
in (index', cc : cats)
|
||||||
| id == cFloat =
|
| id == cFloat =
|
||||||
let cc = pgfCncCat gr lincat fidFloat
|
let cc = pgfCncCat gr (i2i id) lincat fidFloat
|
||||||
(index',cats) = mkCncCats index cdefs
|
(index',cats) = mkCncCats index cdefs
|
||||||
in (index', (i2i id,cc) : cats)
|
in (index', cc : cats)
|
||||||
| id == cString =
|
| id == cString =
|
||||||
let cc = pgfCncCat gr lincat fidString
|
let cc = pgfCncCat gr (i2i id) lincat fidString
|
||||||
(index',cats) = mkCncCats index cdefs
|
(index',cats) = mkCncCats index cdefs
|
||||||
in (index', (i2i id,cc) : cats)
|
in (index', cc : cats)
|
||||||
| otherwise =
|
| otherwise =
|
||||||
let cc@(C.CncCat _s e _) = pgfCncCat gr lincat index
|
let cc@(_, _s, e, _) = pgfCncCat gr (i2i id) lincat index
|
||||||
(index',cats) = mkCncCats (e+1) cdefs
|
(index',cats) = mkCncCats (e+1) cdefs
|
||||||
in (index', (i2i id,cc) : cats)
|
in (index', cc : cats)
|
||||||
mkCncCats index (_ :cdefs) = mkCncCats index cdefs
|
mkCncCats index (_ :cdefs) = mkCncCats index cdefs
|
||||||
|
|
||||||
genCncFuns :: Grammar
|
genCncFuns :: Grammar
|
||||||
-> ModuleName
|
-> ModuleName
|
||||||
-> ModuleName
|
-> ModuleName
|
||||||
-> Array SeqId Sequence
|
-> Array SeqId [Symbol]
|
||||||
-> Array SeqId Sequence
|
-> ([Symbol] -> [Symbol] -> Ordering)
|
||||||
|
-> Array SeqId [Symbol]
|
||||||
-> [(QIdent, Info)]
|
-> [(QIdent, Info)]
|
||||||
-> FId
|
-> FId
|
||||||
-> Map.Map CId D.CncCat
|
-> Map.Map PGF2.Cat (Int,Int)
|
||||||
-> (FId,
|
-> (FId,
|
||||||
IntMap.IntMap (Set.Set D.Production),
|
[(FId, [Production])],
|
||||||
IntMap.IntMap [FunId],
|
[(FId, [FunId])],
|
||||||
IntMap.IntMap [FunId],
|
[(FId, [FunId])],
|
||||||
Array FunId D.CncFun)
|
[(PGF2.Fun,[SeqId])])
|
||||||
genCncFuns gr am cm ex_seqs seqs cdefs fid_cnt cnccats =
|
genCncFuns gr am cm ex_seqs ciCmp seqs cdefs fid_cnt cnccat_ranges =
|
||||||
let (fid_cnt1,funs_cnt1,funs1,lindefs,linrefs) = mkCncCats cdefs fid_cnt 0 [] IntMap.empty IntMap.empty
|
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
|
(fid_cnt2,funs_cnt2,funs2,prods0) = mkCncFuns cdefs fid_cnt1 funs_cnt1 funs1 lindefs Map.empty IntMap.empty
|
||||||
in (fid_cnt2,prods,lindefs,linrefs,array (0,funs_cnt2-1) funs2)
|
prods = [(fid,Set.toList prodSet) | (fid,prodSet) <- IntMap.toList prods0]
|
||||||
|
in (fid_cnt2,prods,IntMap.toList lindefs,IntMap.toList linrefs,reverse funs2)
|
||||||
where
|
where
|
||||||
mkCncCats [] fid_cnt funs_cnt funs lindefs linrefs =
|
mkCncCats [] fid_cnt funs_cnt funs lindefs linrefs =
|
||||||
(fid_cnt,funs_cnt,funs,lindefs,linrefs)
|
(fid_cnt,funs_cnt,funs,lindefs,linrefs)
|
||||||
mkCncCats (((m,id),CncCat _ _ _ _ (Just (PMCFG prods0 funs0))):cdefs) fid_cnt funs_cnt funs lindefs linrefs =
|
mkCncCats (((m,id),CncCat _ _ _ _ (Just (PMCFG prods0 funs0))):cdefs) fid_cnt funs_cnt funs lindefs linrefs =
|
||||||
let !funs_cnt' = let (s_funid, e_funid) = bounds funs0
|
let !funs_cnt' = let (s_funid, e_funid) = bounds funs0
|
||||||
@@ -209,14 +234,13 @@ genCncFuns gr am cm ex_seqs seqs cdefs fid_cnt cnccats =
|
|||||||
linrefs' = foldl' (toLinRef (am,id) funs_cnt) linrefs prods0
|
linrefs' = foldl' (toLinRef (am,id) funs_cnt) linrefs prods0
|
||||||
funs' = foldl' (toCncFun funs_cnt (m,mkLinDefId id)) funs (assocs funs0)
|
funs' = foldl' (toCncFun funs_cnt (m,mkLinDefId id)) funs (assocs funs0)
|
||||||
in mkCncCats cdefs fid_cnt funs_cnt' funs' lindefs' linrefs'
|
in mkCncCats cdefs fid_cnt funs_cnt' funs' lindefs' linrefs'
|
||||||
mkCncCats (_ :cdefs) fid_cnt funs_cnt funs lindefs linrefs =
|
mkCncCats (_ :cdefs) fid_cnt funs_cnt funs lindefs linrefs =
|
||||||
mkCncCats cdefs fid_cnt funs_cnt funs lindefs linrefs
|
mkCncCats cdefs fid_cnt funs_cnt funs lindefs linrefs
|
||||||
|
|
||||||
mkCncFuns [] fid_cnt funs_cnt funs lindefs crc prods =
|
mkCncFuns [] fid_cnt funs_cnt funs lindefs crc prods =
|
||||||
(fid_cnt,funs_cnt,funs,prods)
|
(fid_cnt,funs_cnt,funs,prods)
|
||||||
mkCncFuns (((m,id),CncFun _ _ _ (Just (PMCFG prods0 funs0))):cdefs) fid_cnt funs_cnt funs lindefs crc prods =
|
mkCncFuns (((m,id),CncFun _ _ _ (Just (PMCFG prods0 funs0))):cdefs) fid_cnt funs_cnt funs lindefs crc prods =
|
||||||
let ---Ok ty_C = fmap GM.typeForm (Look.lookupFunType gr am id)
|
let ty_C = err error (\x -> x) $ fmap GM.typeForm (Look.lookupFunType gr am id)
|
||||||
ty_C = err error (\x -> x) $ fmap GM.typeForm (Look.lookupFunType gr am id)
|
|
||||||
!funs_cnt' = let (s_funid, e_funid) = bounds funs0
|
!funs_cnt' = let (s_funid, e_funid) = bounds funs0
|
||||||
in funs_cnt+(e_funid-s_funid+1)
|
in funs_cnt+(e_funid-s_funid+1)
|
||||||
!(fid_cnt',crc',prods')
|
!(fid_cnt',crc',prods')
|
||||||
@@ -227,23 +251,23 @@ genCncFuns gr am cm ex_seqs seqs cdefs fid_cnt cnccats =
|
|||||||
mkCncFuns (_ :cdefs) fid_cnt funs_cnt funs lindefs crc prods =
|
mkCncFuns (_ :cdefs) fid_cnt funs_cnt funs lindefs crc prods =
|
||||||
mkCncFuns cdefs fid_cnt funs_cnt funs lindefs crc prods
|
mkCncFuns cdefs fid_cnt funs_cnt funs lindefs crc prods
|
||||||
|
|
||||||
toProd lindefs (ctxt_C,res_C,_) offs st (Production fid0 funid0 args0) =
|
toProd lindefs (ctxt_C,res_C,_) offs st (A.Production fid0 funid0 args0) =
|
||||||
let !((fid_cnt,crc,prods),args) = mapAccumL mkArg st (zip ctxt_C args0)
|
let !((fid_cnt,crc,prods),args) = mapAccumL mkArg st (zip ctxt_C args0)
|
||||||
set0 = Set.fromList (map (C.PApply (offs+funid0)) (sequence args))
|
set0 = Set.fromList (map (PApply (offs+funid0)) (sequence args))
|
||||||
fid = mkFId res_C fid0
|
fid = mkFId res_C fid0
|
||||||
!prods' = case IntMap.lookup fid prods of
|
!prods' = case IntMap.lookup fid prods of
|
||||||
Just set -> IntMap.insert fid (Set.union set0 set) prods
|
Just set -> IntMap.insert fid (Set.union set0 set) prods
|
||||||
Nothing -> IntMap.insert fid set0 prods
|
Nothing -> IntMap.insert fid set0 prods
|
||||||
in (fid_cnt,crc,prods')
|
in (fid_cnt,crc,prods')
|
||||||
where
|
where
|
||||||
mkArg st@(fid_cnt,crc,prods) ((_,_,ty),fid0s ) =
|
mkArg st@(fid_cnt,crc,prods) ((_,_,ty),fid0s) =
|
||||||
case fid0s of
|
case fid0s of
|
||||||
[fid0] -> (st,map (flip C.PArg (mkFId arg_C fid0)) ctxt)
|
[fid0] -> (st,map (flip PArg (mkFId arg_C fid0)) ctxt)
|
||||||
fid0s -> case Map.lookup fids crc of
|
fid0s -> case Map.lookup fids crc of
|
||||||
Just fid -> (st,map (flip C.PArg fid) ctxt)
|
Just fid -> (st,map (flip PArg fid) ctxt)
|
||||||
Nothing -> let !crc' = Map.insert fids fid_cnt crc
|
Nothing -> let !crc' = Map.insert fids fid_cnt crc
|
||||||
!prods' = IntMap.insert fid_cnt (Set.fromList (map C.PCoerce fids)) prods
|
!prods' = IntMap.insert fid_cnt (Set.fromList (map PCoerce fids)) prods
|
||||||
in ((fid_cnt+1,crc',prods'),map (flip C.PArg fid_cnt) ctxt)
|
in ((fid_cnt+1,crc',prods'),map (flip PArg fid_cnt) ctxt)
|
||||||
where
|
where
|
||||||
(hargs_C,arg_C) = GM.catSkeleton ty
|
(hargs_C,arg_C) = GM.catSkeleton ty
|
||||||
ctxt = mapM (mkCtxt lindefs) hargs_C
|
ctxt = mapM (mkCtxt lindefs) hargs_C
|
||||||
@@ -251,14 +275,14 @@ genCncFuns gr am cm ex_seqs seqs cdefs fid_cnt cnccats =
|
|||||||
|
|
||||||
mkLinDefId id = prefixIdent "lindef " id
|
mkLinDefId id = prefixIdent "lindef " id
|
||||||
|
|
||||||
toLinDef res offs lindefs (Production fid0 funid0 args) =
|
toLinDef res offs lindefs (A.Production fid0 funid0 args) =
|
||||||
if args == [[fidVar]]
|
if args == [[fidVar]]
|
||||||
then IntMap.insertWith (++) fid [offs+funid0] lindefs
|
then IntMap.insertWith (++) fid [offs+funid0] lindefs
|
||||||
else lindefs
|
else lindefs
|
||||||
where
|
where
|
||||||
fid = mkFId res fid0
|
fid = mkFId res fid0
|
||||||
|
|
||||||
toLinRef res offs linrefs (Production fid0 funid0 [fargs]) =
|
toLinRef res offs linrefs (A.Production fid0 funid0 [fargs]) =
|
||||||
if fid0 == fidVar
|
if fid0 == fidVar
|
||||||
then foldr (\fid -> IntMap.insertWith (++) fid [offs+funid0]) linrefs fids
|
then foldr (\fid -> IntMap.insertWith (++) fid [offs+funid0]) linrefs fids
|
||||||
else linrefs
|
else linrefs
|
||||||
@@ -266,25 +290,25 @@ genCncFuns gr am cm ex_seqs seqs cdefs fid_cnt cnccats =
|
|||||||
fids = map (mkFId res) fargs
|
fids = map (mkFId res) fargs
|
||||||
|
|
||||||
mkFId (_,cat) fid0 =
|
mkFId (_,cat) fid0 =
|
||||||
case Map.lookup (i2i cat) cnccats of
|
case Map.lookup (i2i cat) cnccat_ranges of
|
||||||
Just (C.CncCat s e _) -> s+fid0
|
Just (s,e) -> s+fid0
|
||||||
Nothing -> error ("GrammarToPGF.mkFId: missing category "++showIdent cat)
|
Nothing -> error ("GrammarToPGF.mkFId: missing category "++showIdent cat)
|
||||||
|
|
||||||
mkCtxt lindefs (_,cat) =
|
mkCtxt lindefs (_,cat) =
|
||||||
case Map.lookup (i2i cat) cnccats of
|
case Map.lookup (i2i cat) cnccat_ranges of
|
||||||
Just (C.CncCat s e _) -> [(C.fidVar,fid) | fid <- [s..e], Just _ <- [IntMap.lookup fid lindefs]]
|
Just (s,e) -> [(fid,fid) | fid <- [s..e], Just _ <- [IntMap.lookup fid lindefs]]
|
||||||
Nothing -> error "GrammarToPGF.mkCtxt failed"
|
Nothing -> error "GrammarToPGF.mkCtxt failed"
|
||||||
|
|
||||||
toCncFun offs (m,id) funs (funid0,lins0) =
|
toCncFun offs (m,id) funs (funid0,lins0) =
|
||||||
let mseqs = case lookupModule gr m of
|
let mseqs = case lookupModule gr m of
|
||||||
Ok (ModInfo{mseqs=Just mseqs}) -> mseqs
|
Ok (ModInfo{mseqs=Just mseqs}) -> mseqs
|
||||||
_ -> ex_seqs
|
_ -> ex_seqs
|
||||||
in (offs+funid0,C.CncFun (i2i id) (amap (newIndex mseqs) lins0)):funs
|
in (i2i id, map (newIndex mseqs) (elems lins0)):funs
|
||||||
where
|
where
|
||||||
newIndex mseqs i = binSearch (mseqs ! i) seqs (bounds seqs)
|
newIndex mseqs i = binSearch (mseqs ! i) seqs (bounds seqs)
|
||||||
|
|
||||||
binSearch v arr (i,j)
|
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)
|
LT -> binSearch v arr (i,k-1)
|
||||||
EQ -> k
|
EQ -> k
|
||||||
GT -> binSearch v arr (k+1,j)
|
GT -> binSearch v arr (k+1,j)
|
||||||
@@ -292,8 +316,9 @@ genCncFuns gr am cm ex_seqs seqs cdefs fid_cnt cnccats =
|
|||||||
where
|
where
|
||||||
k = (i+j) `div` 2
|
k = (i+j) `div` 2
|
||||||
|
|
||||||
|
|
||||||
genPrintNames cdefs =
|
genPrintNames cdefs =
|
||||||
Map.fromAscList [(i2i id, name) | ((m,id),info) <- cdefs, name <- prn info]
|
[(i2i id, name) | ((m,id),info) <- cdefs, name <- prn info]
|
||||||
where
|
where
|
||||||
prn (CncFun _ _ (Just (L _ tr)) _) = [flatten tr]
|
prn (CncFun _ _ (Just (L _ tr)) _) = [flatten tr]
|
||||||
prn (CncCat _ _ _ (Just (L _ tr)) _) = [flatten tr]
|
prn (CncCat _ _ _ (Just (L _ tr)) _) = [flatten tr]
|
||||||
@@ -303,6 +328,120 @@ genPrintNames cdefs =
|
|||||||
flatten (Alts x _) = flatten x
|
flatten (Alts x _) = flatten x
|
||||||
flatten (C x y) = flatten x +++ flatten y
|
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]
|
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]
|
mkSetArray set = listArray (0,Set.size set-1) (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.
|
||||||
|
|
||||||
|
compareCaseInsensitive [] [] = EQ
|
||||||
|
compareCaseInsensitive [] _ = LT
|
||||||
|
compareCaseInsensitive _ [] = GT
|
||||||
|
compareCaseInsensitive (x:xs) (y:ys) =
|
||||||
|
case compareSym x y of
|
||||||
|
EQ -> compareCaseInsensitive xs ys
|
||||||
|
x -> x
|
||||||
|
where
|
||||||
|
compareSym s1 s2 =
|
||||||
|
case s1 of
|
||||||
|
SymCat d1 r1
|
||||||
|
-> case s2 of
|
||||||
|
SymCat d2 r2
|
||||||
|
-> case compare d1 d2 of
|
||||||
|
EQ -> r1 `compare` r2
|
||||||
|
x -> x
|
||||||
|
_ -> LT
|
||||||
|
SymLit d1 r1
|
||||||
|
-> case s2 of
|
||||||
|
SymCat {} -> GT
|
||||||
|
SymLit d2 r2
|
||||||
|
-> case compare d1 d2 of
|
||||||
|
EQ -> r1 `compare` r2
|
||||||
|
x -> x
|
||||||
|
_ -> LT
|
||||||
|
SymVar d1 r1
|
||||||
|
-> if tagToEnum# (getTag s2 ># 2#)
|
||||||
|
then LT
|
||||||
|
else case s2 of
|
||||||
|
SymVar d2 r2
|
||||||
|
-> case compare d1 d2 of
|
||||||
|
EQ -> r1 `compare` r2
|
||||||
|
x -> x
|
||||||
|
_ -> GT
|
||||||
|
SymKS t1
|
||||||
|
-> if tagToEnum# (getTag s2 ># 3#)
|
||||||
|
then LT
|
||||||
|
else case s2 of
|
||||||
|
SymKS t2 -> t1 `compareToken` t2
|
||||||
|
_ -> GT
|
||||||
|
SymKP a1 b1
|
||||||
|
-> if tagToEnum# (getTag s2 ># 4#)
|
||||||
|
then LT
|
||||||
|
else case s2 of
|
||||||
|
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
|
||||||
|
|||||||
@@ -21,23 +21,16 @@ import GF.Grammar.Printer
|
|||||||
import GF.Grammar.Macros
|
import GF.Grammar.Macros
|
||||||
import GF.Grammar.Lookup
|
import GF.Grammar.Lookup
|
||||||
import GF.Grammar.Predef
|
import GF.Grammar.Predef
|
||||||
--import GF.Compile.Refresh
|
|
||||||
--import GF.Compile.Compute.Concrete
|
|
||||||
import GF.Compile.Compute.ConcreteNew(GlobalEnv,normalForm,resourceValues)
|
import GF.Compile.Compute.ConcreteNew(GlobalEnv,normalForm,resourceValues)
|
||||||
--import GF.Compile.CheckGrammar
|
|
||||||
--import GF.Compile.Update
|
|
||||||
|
|
||||||
import GF.Data.Operations
|
import GF.Data.Operations
|
||||||
--import GF.Infra.CheckM
|
|
||||||
import GF.Infra.Option
|
import GF.Infra.Option
|
||||||
|
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
--import Data.List
|
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
|
import qualified Data.Map as Map
|
||||||
import GF.Text.Pretty
|
import GF.Text.Pretty
|
||||||
import Debug.Trace
|
import Debug.Trace
|
||||||
|
|
||||||
|
|
||||||
-- | partial evaluation of concrete syntax. AR 6\/2001 -- 16\/5\/2003 -- 5\/2\/2005.
|
-- | partial evaluation of concrete syntax. AR 6\/2001 -- 16\/5\/2003 -- 5\/2\/2005.
|
||||||
|
|
||||||
optimizeModule :: Options -> SourceGrammar -> SourceModule -> Err SourceModule
|
optimizeModule :: Options -> SourceGrammar -> SourceModule -> Err SourceModule
|
||||||
@@ -54,7 +47,7 @@ optimizeModule opts sgr m@(name,mi)
|
|||||||
|
|
||||||
updateEvalInfo mi (i,info) = do
|
updateEvalInfo mi (i,info) = do
|
||||||
info <- evalInfo oopts resenv sgr (name,mi) i info
|
info <- evalInfo oopts resenv sgr (name,mi) i info
|
||||||
return (mi{jments=updateTree (i,info) (jments mi)})
|
return (mi{jments=Map.insert i info (jments mi)})
|
||||||
|
|
||||||
evalInfo :: Options -> GlobalEnv -> SourceGrammar -> SourceModule -> Ident -> Info -> Err Info
|
evalInfo :: Options -> GlobalEnv -> SourceGrammar -> SourceModule -> Ident -> Info -> Err Info
|
||||||
evalInfo opts resenv sgr m c info = do
|
evalInfo opts resenv sgr m c info = do
|
||||||
|
|||||||
189
src/compiler/GF/Compile/OptimizePGF.hs
Normal file
189
src/compiler/GF/Compile/OptimizePGF.hs
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
{-# LANGUAGE BangPatterns #-}
|
||||||
|
module GF.Compile.OptimizePGF(optimizePGF) where
|
||||||
|
|
||||||
|
import PGF2(Cat,Fun)
|
||||||
|
import PGF2.Internal
|
||||||
|
import Data.Array.ST
|
||||||
|
import Data.Array.Unboxed
|
||||||
|
import qualified Data.Map as Map
|
||||||
|
import qualified Data.Set as Set
|
||||||
|
import qualified Data.IntSet as IntSet
|
||||||
|
import qualified Data.IntMap as IntMap
|
||||||
|
import qualified Data.List as List
|
||||||
|
import Control.Monad.ST
|
||||||
|
|
||||||
|
type ConcrData = ([(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
|
||||||
|
|
||||||
|
optimizePGF :: Cat -> ConcrData -> ConcrData
|
||||||
|
optimizePGF startCat = topDownFilter startCat . bottomUpFilter
|
||||||
|
|
||||||
|
catString = "String"
|
||||||
|
catInt = "Int"
|
||||||
|
catFloat = "Float"
|
||||||
|
catVar = "__gfVar"
|
||||||
|
|
||||||
|
topDownFilter :: Cat -> ConcrData -> ConcrData
|
||||||
|
topDownFilter startCat (lindefs,linrefs,prods,cncfuns,sequences,cnccats) =
|
||||||
|
let env0 = (Map.empty,Map.empty)
|
||||||
|
(env1,lindefs') = List.mapAccumL (\env (fid,funids) -> let (env',funids') = List.mapAccumL (optimizeFun fid [PArg [] fidVar]) env funids in (env',(fid,funids')))
|
||||||
|
env0
|
||||||
|
lindefs
|
||||||
|
(env2,linrefs') = List.mapAccumL (\env (fid,funids) -> let (env',funids') = List.mapAccumL (optimizeFun fidVar [PArg [] fid]) env funids in (env',(fid,funids')))
|
||||||
|
env1
|
||||||
|
linrefs
|
||||||
|
(env3,prods') = List.mapAccumL (\env (fid,set) -> let (env',set') = List.mapAccumL (optimizeProd fid) env set in (env',(fid,set')))
|
||||||
|
env2
|
||||||
|
prods
|
||||||
|
cnccats' = map filterCatLabels cnccats
|
||||||
|
(sequences',cncfuns') = env3
|
||||||
|
in (lindefs',linrefs',prods',mkSetArray cncfuns',mkSetArray sequences',cnccats')
|
||||||
|
where
|
||||||
|
cncfuns_array = listArray (0,length cncfuns-1) cncfuns :: Array FunId (Fun, [SeqId])
|
||||||
|
sequences_array = listArray (0,length sequences-1) sequences :: Array SeqId [Symbol]
|
||||||
|
prods_map = IntMap.fromList prods
|
||||||
|
fid2catMap = IntMap.fromList ((fidVar,catVar) : [(fid,cat) | (cat,start,end,lbls) <- cnccats,
|
||||||
|
fid <- [start..end]])
|
||||||
|
|
||||||
|
fid2cat fid =
|
||||||
|
case IntMap.lookup fid fid2catMap of
|
||||||
|
Just cat -> cat
|
||||||
|
Nothing -> case [fid | Just set <- [IntMap.lookup fid prods_map], PCoerce fid <- set] of
|
||||||
|
(fid:_) -> fid2cat fid
|
||||||
|
_ -> error "unknown forest id"
|
||||||
|
|
||||||
|
starts =
|
||||||
|
[(startCat,lbl) | (cat,_,_,lbls) <- cnccats, cat==startCat, lbl <- [0..length lbls-1]]
|
||||||
|
|
||||||
|
allRelations =
|
||||||
|
Map.unionsWith Set.union
|
||||||
|
[rel fid prod | (fid,set) <- prods, prod <- set]
|
||||||
|
where
|
||||||
|
rel fid (PApply funid args) = Map.fromList [((fid2cat fid,lbl),deps args seqid) | (lbl,seqid) <- zip [0..] lin]
|
||||||
|
where
|
||||||
|
(_,lin) = cncfuns_array ! funid
|
||||||
|
rel fid _ = Map.empty
|
||||||
|
|
||||||
|
deps args seqid = Set.fromList [let PArg _ fid = args !! r in (fid2cat fid,d) | SymCat r d <- seq]
|
||||||
|
where
|
||||||
|
seq = sequences_array ! seqid
|
||||||
|
|
||||||
|
-- here we create a mapping from a category to an array of indices.
|
||||||
|
-- An element of the array is equal to -1 if the corresponding index
|
||||||
|
-- is not going to be used in the optimized grammar, or the new index
|
||||||
|
-- if it will be used
|
||||||
|
closure :: Map.Map Cat [Int]
|
||||||
|
closure = runST $ do
|
||||||
|
set <- initSet
|
||||||
|
addLitCat catString set
|
||||||
|
addLitCat catInt set
|
||||||
|
addLitCat catFloat set
|
||||||
|
addLitCat catVar set
|
||||||
|
closureSet set starts
|
||||||
|
doneSet set
|
||||||
|
where
|
||||||
|
initSet :: ST s (Map.Map Cat (STUArray s Int Int))
|
||||||
|
initSet =
|
||||||
|
fmap Map.fromList $ sequence
|
||||||
|
[fmap ((,) cat) (newArray (0,length lbls-1) (-1))
|
||||||
|
| (cat,_,_,lbls) <- cnccats]
|
||||||
|
|
||||||
|
addLitCat cat set =
|
||||||
|
case Map.lookup cat set of
|
||||||
|
Just indices -> writeArray indices 0 0
|
||||||
|
Nothing -> return ()
|
||||||
|
|
||||||
|
closureSet set [] = return ()
|
||||||
|
closureSet set (x@(cat,index):xs) =
|
||||||
|
case Map.lookup cat set of
|
||||||
|
Just indices -> do v <- readArray indices index
|
||||||
|
writeArray indices index 0
|
||||||
|
if v < 0
|
||||||
|
then case Map.lookup x allRelations of
|
||||||
|
Just ys -> closureSet set (Set.toList ys++xs)
|
||||||
|
Nothing -> closureSet set xs
|
||||||
|
else closureSet set xs
|
||||||
|
Nothing -> error "unknown cat"
|
||||||
|
|
||||||
|
doneSet :: Map.Map Cat (STUArray s Int Int) -> ST s (Map.Map Cat [Int])
|
||||||
|
doneSet set =
|
||||||
|
fmap Map.fromAscList $ mapM done (Map.toAscList set)
|
||||||
|
where
|
||||||
|
done (cat,indices) = do
|
||||||
|
indices <- fmap (reindex 0) (getElems indices)
|
||||||
|
return (cat,indices)
|
||||||
|
|
||||||
|
reindex k [] = []
|
||||||
|
reindex k (v:vs)
|
||||||
|
| v < 0 = v : reindex k vs
|
||||||
|
| otherwise = k : reindex (k+1) vs
|
||||||
|
|
||||||
|
optimizeProd res env (PApply funid args) =
|
||||||
|
let (env',funid') = optimizeFun res args env funid
|
||||||
|
in (env', PApply funid' args)
|
||||||
|
optimizeProd res env prod = (env,prod)
|
||||||
|
|
||||||
|
optimizeFun res args (seqs,funs) funid =
|
||||||
|
let (seqs',lin') = List.mapAccumL addUnique seqs [map updateSymbol (sequences_array ! seqid) |
|
||||||
|
(idx,seqid) <- zip (indicesOf res) lin, idx >= 0]
|
||||||
|
(funs',funid') = addUnique funs (fun, lin')
|
||||||
|
in ((seqs',funs'), funid')
|
||||||
|
where
|
||||||
|
(fun,lin) = cncfuns_array ! funid
|
||||||
|
|
||||||
|
indicesOf fid
|
||||||
|
| fid < 0 = [0]
|
||||||
|
| otherwise =
|
||||||
|
case Map.lookup (fid2cat fid) closure of
|
||||||
|
Just indices -> indices
|
||||||
|
Nothing -> error "unknown category"
|
||||||
|
|
||||||
|
addUnique seqs seq =
|
||||||
|
case Map.lookup seq seqs of
|
||||||
|
Just seqid -> (seqs,seqid)
|
||||||
|
Nothing -> let seqid = Map.size seqs
|
||||||
|
in (Map.insert seq seqid seqs, seqid)
|
||||||
|
|
||||||
|
updateSymbol (SymCat r d) = let PArg _ fid = args !! r in SymCat r (indicesOf fid !! d)
|
||||||
|
updateSymbol s = s
|
||||||
|
|
||||||
|
filterCatLabels (cat,start,end,lbls) =
|
||||||
|
case Map.lookup cat closure of
|
||||||
|
Just indices -> let lbls' = [lbl | (idx,lbl) <- zip indices lbls, idx >= 0]
|
||||||
|
in (cat,start,end,lbls')
|
||||||
|
Nothing -> error ("unknown category")
|
||||||
|
|
||||||
|
mkSetArray map = sortSnd (Map.toList map)
|
||||||
|
where
|
||||||
|
sortSnd = List.map fst . List.sortBy (\(_,i) (_,j) -> compare i j)
|
||||||
|
|
||||||
|
|
||||||
|
bottomUpFilter :: ConcrData -> ConcrData
|
||||||
|
bottomUpFilter (lindefs,linrefs,prods,cncfuns,sequences,cnccats) =
|
||||||
|
(lindefs,linrefs,filterProductions IntMap.empty IntSet.empty prods,cncfuns,sequences,cnccats)
|
||||||
|
|
||||||
|
filterProductions prods0 hoc0 prods
|
||||||
|
| prods0 == prods1 = IntMap.toList prods0
|
||||||
|
| otherwise = filterProductions prods1 hoc1 prods
|
||||||
|
where
|
||||||
|
(prods1,hoc1) = foldl foldProdSet (IntMap.empty,IntSet.empty) prods
|
||||||
|
|
||||||
|
foldProdSet (!prods,!hoc) (fid,set)
|
||||||
|
| null set1 = (prods,hoc)
|
||||||
|
| otherwise = (IntMap.insert fid set1 prods,hoc1)
|
||||||
|
where
|
||||||
|
set1 = filter filterRule set
|
||||||
|
hoc1 = foldl accumHOC hoc set1
|
||||||
|
|
||||||
|
filterRule (PApply funid args) = all (\(PArg _ fid) -> isLive fid) args
|
||||||
|
filterRule (PCoerce fid) = isLive fid
|
||||||
|
filterRule _ = True
|
||||||
|
|
||||||
|
isLive fid = isPredefFId fid || IntMap.member fid prods0 || IntSet.member fid hoc0
|
||||||
|
|
||||||
|
accumHOC hoc (PApply funid args) = List.foldl' (\hoc (PArg hypos _) -> List.foldl' (\hoc fid -> IntSet.insert fid hoc) hoc (map snd hypos)) hoc args
|
||||||
|
accumHOC hoc _ = hoc
|
||||||
@@ -16,13 +16,14 @@
|
|||||||
|
|
||||||
module GF.Compile.PGFtoHaskell (grammar2haskell) where
|
module GF.Compile.PGFtoHaskell (grammar2haskell) where
|
||||||
|
|
||||||
import PGF(showCId)
|
import PGF2
|
||||||
import PGF.Internal
|
import PGF2.Internal
|
||||||
|
|
||||||
import GF.Data.Operations
|
import GF.Data.Operations
|
||||||
import GF.Infra.Option
|
import GF.Infra.Option
|
||||||
|
|
||||||
import Data.List --(isPrefixOf, find, intersperse)
|
import Data.List
|
||||||
|
import Data.Maybe(mapMaybe)
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
|
|
||||||
type Prefix = String -> String
|
type Prefix = String -> String
|
||||||
@@ -39,7 +40,7 @@ grammar2haskell opts name gr = foldr (++++) [] $
|
|||||||
lexical cat = haskellOption opts HaskellLexical && isLexicalCat opts cat
|
lexical cat = haskellOption opts HaskellLexical && isLexicalCat opts cat
|
||||||
gId | haskellOption opts HaskellNoPrefix = id
|
gId | haskellOption opts HaskellNoPrefix = id
|
||||||
| otherwise = ("G"++)
|
| otherwise = ("G"++)
|
||||||
pragmas | gadt = ["{-# OPTIONS_GHC -fglasgow-exts #-}","{-# LANGUAGE GADTs #-}"]
|
pragmas | gadt = ["{-# OPTIONS_GHC -fglasgow-exts #-}"]
|
||||||
| otherwise = []
|
| otherwise = []
|
||||||
types | gadt = datatypesGADT gId lexical gr'
|
types | gadt = datatypesGADT gId lexical gr'
|
||||||
| otherwise = datatypes gId lexical gr'
|
| otherwise = datatypes gId lexical gr'
|
||||||
@@ -241,7 +242,7 @@ fInstance gId lexical m (cat,rules) =
|
|||||||
then " " ++ gId cat ++ " (fgs t) where\n fgs t = case unApp t of"
|
then " " ++ gId cat ++ " (fgs t) where\n fgs t = case unApp t of"
|
||||||
else " case unApp t of") ++++
|
else " case unApp t of") ++++
|
||||||
unlines [mkInst f xx | (f,xx) <- nonLexicalRules (lexical cat) rules] ++++
|
unlines [mkInst f xx | (f,xx) <- nonLexicalRules (lexical cat) rules] ++++
|
||||||
(if lexical cat then " Just (i,[]) -> " ++ lexicalConstructor cat +++ "(showCId i)" else "") ++++
|
(if lexical cat then " Just (i,[]) -> " ++ lexicalConstructor cat +++ "i" else "") ++++
|
||||||
" _ -> error (\"no" +++ cat ++ " \" ++ show t)"
|
" _ -> error (\"no" +++ cat ++ " \" ++ show t)"
|
||||||
where
|
where
|
||||||
isList = isListCat (cat,rules)
|
isList = isListCat (cat,rules)
|
||||||
@@ -262,18 +263,21 @@ fInstance gId lexical m (cat,rules) =
|
|||||||
--type HSkeleton = [(OIdent, [(OIdent, [OIdent])])]
|
--type HSkeleton = [(OIdent, [(OIdent, [OIdent])])]
|
||||||
hSkeleton :: PGF -> (String,HSkeleton)
|
hSkeleton :: PGF -> (String,HSkeleton)
|
||||||
hSkeleton gr =
|
hSkeleton gr =
|
||||||
(showCId (absname gr),
|
(abstractName gr,
|
||||||
let fs =
|
let fs =
|
||||||
[(showCId c, [(showCId f, map showCId cs) | (f, (cs,_)) <- fs]) |
|
[(c, [(f, cs) | (f, cs,_) <- fs]) |
|
||||||
fs@((_, (_,c)):_) <- fns]
|
fs@((_, _,c):_) <- fns]
|
||||||
in fs ++ [(sc, []) | c <- cts, let sc = showCId c, notElem sc (["Int", "Float", "String"] ++ map fst fs)]
|
in fs ++ [(c, []) | c <- cts, notElem c (["Int", "Float", "String"] ++ map fst fs)]
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
cts = Map.keys (cats (abstract gr))
|
cts = categories gr
|
||||||
fns = groupBy valtypg (sortBy valtyps (map jty (Map.assocs (funs (abstract gr)))))
|
fns = groupBy valtypg (sortBy valtyps (mapMaybe jty (functions gr)))
|
||||||
valtyps (_, (_,x)) (_, (_,y)) = compare x y
|
valtyps (_,_,x) (_,_,y) = compare x y
|
||||||
valtypg (_, (_,x)) (_, (_,y)) = x == y
|
valtypg (_,_,x) (_,_,y) = x == y
|
||||||
jty (f,(ty,_,_,_)) = (f,catSkeleton ty)
|
jty f = case functionType gr f of
|
||||||
|
Just ty -> let (hypos,valcat,_) = unType ty
|
||||||
|
in Just (f,[argcat | (_,_,ty) <- hypos, let (_,argcat,_) = unType ty],valcat)
|
||||||
|
Nothing -> Nothing
|
||||||
{-
|
{-
|
||||||
updateSkeleton :: OIdent -> HSkeleton -> (OIdent, [OIdent]) -> HSkeleton
|
updateSkeleton :: OIdent -> HSkeleton -> (OIdent, [OIdent]) -> HSkeleton
|
||||||
updateSkeleton cat skel rule =
|
updateSkeleton cat skel rule =
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
module GF.Compile.PGFtoJS (pgf2js) where
|
|
||||||
|
|
||||||
import PGF(showCId)
|
|
||||||
import PGF.Internal as M
|
|
||||||
import qualified GF.JavaScript.AbsJS as JS
|
|
||||||
import qualified GF.JavaScript.PrintJS as JS
|
|
||||||
|
|
||||||
--import GF.Data.ErrM
|
|
||||||
--import GF.Infra.Option
|
|
||||||
|
|
||||||
--import Control.Monad (mplus)
|
|
||||||
--import Data.Array.Unboxed (UArray)
|
|
||||||
import qualified Data.Array.IArray as Array
|
|
||||||
--import Data.Maybe (fromMaybe)
|
|
||||||
import Data.Map (Map)
|
|
||||||
import qualified Data.Set as Set
|
|
||||||
import qualified Data.Map as Map
|
|
||||||
import qualified Data.IntMap as IntMap
|
|
||||||
|
|
||||||
pgf2js :: PGF -> String
|
|
||||||
pgf2js pgf =
|
|
||||||
JS.printTree $ JS.Program [JS.ElStmt $ JS.SDeclOrExpr $ JS.Decl [JS.DInit (JS.Ident n) grammar]]
|
|
||||||
where
|
|
||||||
n = showCId $ absname pgf
|
|
||||||
as = abstract pgf
|
|
||||||
cs = Map.assocs (concretes pgf)
|
|
||||||
start = showCId $ M.lookStartCat pgf
|
|
||||||
grammar = new "GFGrammar" [js_abstract, js_concrete]
|
|
||||||
js_abstract = abstract2js start as
|
|
||||||
js_concrete = JS.EObj $ map concrete2js cs
|
|
||||||
|
|
||||||
abstract2js :: String -> Abstr -> JS.Expr
|
|
||||||
abstract2js start ds = new "GFAbstract" [JS.EStr start, JS.EObj $ map absdef2js (Map.assocs (funs ds))]
|
|
||||||
|
|
||||||
absdef2js :: (CId,(Type,Int,Maybe ([Equation],[[M.Instr]]),Double)) -> JS.Property
|
|
||||||
absdef2js (f,(typ,_,_,_)) =
|
|
||||||
let (args,cat) = M.catSkeleton typ in
|
|
||||||
JS.Prop (JS.IdentPropName (JS.Ident (showCId f))) (new "Type" [JS.EArray [JS.EStr (showCId x) | x <- args], JS.EStr (showCId cat)])
|
|
||||||
|
|
||||||
lit2js (LStr s) = JS.EStr s
|
|
||||||
lit2js (LInt n) = JS.EInt n
|
|
||||||
lit2js (LFlt d) = JS.EDbl d
|
|
||||||
|
|
||||||
concrete2js :: (CId,Concr) -> JS.Property
|
|
||||||
concrete2js (c,cnc) =
|
|
||||||
JS.Prop l (new "GFConcrete" [mapToJSObj (lit2js) $ cflags cnc,
|
|
||||||
JS.EObj $ [JS.Prop (JS.IntPropName cat) (JS.EArray (map frule2js (Set.toList set))) | (cat,set) <- IntMap.toList (productions cnc)],
|
|
||||||
JS.EArray $ (map ffun2js (Array.elems (cncfuns cnc))),
|
|
||||||
JS.EArray $ (map seq2js (Array.elems (sequences cnc))),
|
|
||||||
JS.EObj $ map cats (Map.assocs (cnccats cnc)),
|
|
||||||
JS.EInt (totalCats cnc)])
|
|
||||||
where
|
|
||||||
l = JS.IdentPropName (JS.Ident (showCId c))
|
|
||||||
{-
|
|
||||||
litslins = [JS.Prop (JS.StringPropName "Int") (JS.EFun [children] [JS.SReturn $ new "Arr" [JS.EIndex (JS.EVar children) (JS.EInt 0)]]),
|
|
||||||
JS.Prop (JS.StringPropName "Float") (JS.EFun [children] [JS.SReturn $ new "Arr" [JS.EIndex (JS.EVar children) (JS.EInt 0)]]),
|
|
||||||
JS.Prop (JS.StringPropName "String") (JS.EFun [children] [JS.SReturn $ new "Arr" [JS.EIndex (JS.EVar children) (JS.EInt 0)]])]
|
|
||||||
-}
|
|
||||||
cats (c,CncCat start end _) = JS.Prop (JS.IdentPropName (JS.Ident (showCId c))) (JS.EObj [JS.Prop (JS.IdentPropName (JS.Ident "s")) (JS.EInt start)
|
|
||||||
,JS.Prop (JS.IdentPropName (JS.Ident "e")) (JS.EInt end)])
|
|
||||||
{-
|
|
||||||
mkStr :: String -> JS.Expr
|
|
||||||
mkStr s = new "Str" [JS.EStr s]
|
|
||||||
|
|
||||||
mkSeq :: [JS.Expr] -> JS.Expr
|
|
||||||
mkSeq [x] = x
|
|
||||||
mkSeq xs = new "Seq" xs
|
|
||||||
|
|
||||||
argIdent :: Integer -> JS.Ident
|
|
||||||
argIdent n = JS.Ident ("x" ++ show n)
|
|
||||||
-}
|
|
||||||
children :: JS.Ident
|
|
||||||
children = JS.Ident "cs"
|
|
||||||
|
|
||||||
frule2js :: Production -> JS.Expr
|
|
||||||
frule2js (PApply funid args) = new "Apply" [JS.EInt funid, JS.EArray (map farg2js args)]
|
|
||||||
frule2js (PCoerce arg) = new "Coerce" [JS.EInt arg]
|
|
||||||
|
|
||||||
farg2js (PArg hypos fid) = new "PArg" (map (JS.EInt . snd) hypos ++ [JS.EInt fid])
|
|
||||||
|
|
||||||
ffun2js (CncFun f lins) = new "CncFun" [JS.EStr (showCId f), JS.EArray (map JS.EInt (Array.elems lins))]
|
|
||||||
|
|
||||||
seq2js :: Array.Array DotPos Symbol -> JS.Expr
|
|
||||||
seq2js seq = JS.EArray [sym2js s | s <- Array.elems seq]
|
|
||||||
|
|
||||||
sym2js :: Symbol -> JS.Expr
|
|
||||||
sym2js (SymCat n l) = new "SymCat" [JS.EInt n, JS.EInt l]
|
|
||||||
sym2js (SymLit n l) = new "SymLit" [JS.EInt n, JS.EInt l]
|
|
||||||
sym2js (SymVar n l) = new "SymVar" [JS.EInt n, JS.EInt l]
|
|
||||||
sym2js (SymKS t) = new "SymKS" [JS.EStr t]
|
|
||||||
sym2js (SymKP ts alts) = new "SymKP" [JS.EArray (map sym2js ts), JS.EArray (map alt2js alts)]
|
|
||||||
sym2js SymBIND = new "SymKS" [JS.EStr "&+"]
|
|
||||||
sym2js SymSOFT_BIND = new "SymKS" [JS.EStr "&+"]
|
|
||||||
sym2js SymSOFT_SPACE = new "SymKS" [JS.EStr "&+"]
|
|
||||||
sym2js SymCAPIT = new "SymKS" [JS.EStr "&|"]
|
|
||||||
sym2js SymALL_CAPIT = new "SymKS" [JS.EStr "&|"]
|
|
||||||
sym2js SymNE = new "SymNE" []
|
|
||||||
|
|
||||||
alt2js (ps,ts) = new "Alt" [JS.EArray (map sym2js ps), JS.EArray (map JS.EStr ts)]
|
|
||||||
|
|
||||||
new :: String -> [JS.Expr] -> JS.Expr
|
|
||||||
new f xs = JS.ENew (JS.Ident f) xs
|
|
||||||
|
|
||||||
mapToJSObj :: (a -> JS.Expr) -> Map CId a -> JS.Expr
|
|
||||||
mapToJSObj f m = JS.EObj [ JS.Prop (JS.IdentPropName (JS.Ident (showCId k))) (f v) | (k,v) <- Map.toList m ]
|
|
||||||
110
src/compiler/GF/Compile/PGFtoJSON.hs
Normal file
110
src/compiler/GF/Compile/PGFtoJSON.hs
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
module GF.Compile.PGFtoJSON (pgf2json) where
|
||||||
|
|
||||||
|
import PGF2
|
||||||
|
import PGF2.Internal
|
||||||
|
import Text.JSON
|
||||||
|
import qualified Data.Map as Map
|
||||||
|
|
||||||
|
pgf2json :: PGF -> String
|
||||||
|
pgf2json pgf =
|
||||||
|
encode $ makeObj
|
||||||
|
[ ("abstract", abstract2json pgf)
|
||||||
|
, ("concretes", makeObj $ map concrete2json
|
||||||
|
(Map.toList (languages pgf)))
|
||||||
|
]
|
||||||
|
|
||||||
|
abstract2json :: PGF -> JSValue
|
||||||
|
abstract2json pgf =
|
||||||
|
makeObj
|
||||||
|
[ ("name", showJSON (abstractName pgf))
|
||||||
|
, ("startcat", showJSON (showType [] (startCat pgf)))
|
||||||
|
, ("funs", makeObj $ map (absdef2json pgf) (functions pgf))
|
||||||
|
]
|
||||||
|
|
||||||
|
absdef2json :: PGF -> Fun -> (String,JSValue)
|
||||||
|
absdef2json pgf f = (f,sig)
|
||||||
|
where
|
||||||
|
Just (hypos,cat,_) = fmap unType (functionType pgf f)
|
||||||
|
sig = makeObj
|
||||||
|
[ ("args", showJSON $ map (\(_,_,ty) -> showType [] ty) hypos)
|
||||||
|
, ("cat", showJSON cat)
|
||||||
|
]
|
||||||
|
|
||||||
|
lit2json :: Literal -> JSValue
|
||||||
|
lit2json (LStr s) = showJSON s
|
||||||
|
lit2json (LInt n) = showJSON n
|
||||||
|
lit2json (LFlt d) = showJSON d
|
||||||
|
|
||||||
|
concrete2json :: (ConcName,Concr) -> (String,JSValue)
|
||||||
|
concrete2json (c,cnc) = (c,obj)
|
||||||
|
where
|
||||||
|
obj = makeObj
|
||||||
|
[ ("flags", makeObj [(k, lit2json v) | (k,v) <- concrFlags cnc])
|
||||||
|
, ("productions", makeObj [(show fid, showJSON (map frule2json (concrProductions cnc fid))) | (_,start,end,_) <- concrCategories cnc, fid <- [start..end]])
|
||||||
|
, ("functions", showJSON [ffun2json funid (concrFunction cnc funid) | funid <- [0..concrTotalFuns cnc-1]])
|
||||||
|
, ("sequences", showJSON [seq2json seqid (concrSequence cnc seqid) | seqid <- [0..concrTotalSeqs cnc-1]])
|
||||||
|
, ("categories", makeObj $ map cat2json (concrCategories cnc))
|
||||||
|
, ("totalfids", showJSON (concrTotalCats cnc))
|
||||||
|
]
|
||||||
|
|
||||||
|
cat2json :: (Cat,FId,FId,[String]) -> (String,JSValue)
|
||||||
|
cat2json (cat,start,end,_) = (cat, ixs)
|
||||||
|
where
|
||||||
|
ixs = makeObj
|
||||||
|
[ ("start", showJSON start)
|
||||||
|
, ("end", showJSON end)
|
||||||
|
]
|
||||||
|
|
||||||
|
frule2json :: Production -> JSValue
|
||||||
|
frule2json (PApply fid args) =
|
||||||
|
makeObj
|
||||||
|
[ ("type", showJSON "Apply")
|
||||||
|
, ("fid", showJSON fid)
|
||||||
|
, ("args", showJSON (map farg2json args))
|
||||||
|
]
|
||||||
|
frule2json (PCoerce arg) =
|
||||||
|
makeObj
|
||||||
|
[ ("type", showJSON "Coerce")
|
||||||
|
, ("arg", showJSON arg)
|
||||||
|
]
|
||||||
|
|
||||||
|
farg2json :: PArg -> JSValue
|
||||||
|
farg2json (PArg hypos fid) =
|
||||||
|
makeObj
|
||||||
|
[ ("type", showJSON "PArg")
|
||||||
|
, ("hypos", JSArray $ map (showJSON . snd) hypos)
|
||||||
|
, ("fid", showJSON fid)
|
||||||
|
]
|
||||||
|
|
||||||
|
ffun2json :: FunId -> (Fun,[SeqId]) -> JSValue
|
||||||
|
ffun2json funid (fun,seqids) =
|
||||||
|
makeObj
|
||||||
|
[ ("name", showJSON fun)
|
||||||
|
, ("lins", showJSON seqids)
|
||||||
|
]
|
||||||
|
|
||||||
|
seq2json :: SeqId -> [Symbol] -> JSValue
|
||||||
|
seq2json seqid seq = showJSON [sym2json sym | sym <- seq]
|
||||||
|
|
||||||
|
sym2json :: Symbol -> JSValue
|
||||||
|
sym2json (SymCat n l) = new "SymCat" [showJSON n, showJSON l]
|
||||||
|
sym2json (SymLit n l) = new "SymLit" [showJSON n, showJSON l]
|
||||||
|
sym2json (SymVar n l) = new "SymVar" [showJSON n, showJSON l]
|
||||||
|
sym2json (SymKS t) = new "SymKS" [showJSON t]
|
||||||
|
sym2json (SymKP ts alts) = new "SymKP" [JSArray (map sym2json ts), JSArray (map alt2json alts)]
|
||||||
|
sym2json SymBIND = new "SymKS" [showJSON "&+"]
|
||||||
|
sym2json SymSOFT_BIND = new "SymKS" [showJSON "&+"]
|
||||||
|
sym2json SymSOFT_SPACE = new "SymKS" [showJSON "&+"]
|
||||||
|
sym2json SymCAPIT = new "SymKS" [showJSON "&|"]
|
||||||
|
sym2json SymALL_CAPIT = new "SymKS" [showJSON "&|"]
|
||||||
|
sym2json SymNE = new "SymNE" []
|
||||||
|
|
||||||
|
alt2json :: ([Symbol],[String]) -> JSValue
|
||||||
|
alt2json (ps,ts) = new "Alt" [showJSON (map sym2json ps), showJSON ts]
|
||||||
|
|
||||||
|
new :: String -> [JSValue] -> JSValue
|
||||||
|
new f xs =
|
||||||
|
makeObj
|
||||||
|
[ ("type", showJSON f)
|
||||||
|
, ("args", showJSON xs)
|
||||||
|
]
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
module GF.Compile.PGFtoJava (grammar2java) where
|
module GF.Compile.PGFtoJava (grammar2java) where
|
||||||
|
|
||||||
import PGF
|
import PGF2
|
||||||
import Data.Maybe(maybe)
|
import Data.Maybe(maybe)
|
||||||
import Data.List(intercalate)
|
import Data.List(intercalate)
|
||||||
import GF.Infra.Option
|
import GF.Infra.Option
|
||||||
@@ -24,9 +24,8 @@ javaPreamble name =
|
|||||||
]
|
]
|
||||||
|
|
||||||
javaMethod gr fun =
|
javaMethod gr fun =
|
||||||
" public static Expr "++name++"("++arg_decls++") { return new Expr("++show name++args++"); }"
|
" public static Expr "++fun++"("++arg_decls++") { return new Expr("++show fun++args++"); }"
|
||||||
where
|
where
|
||||||
name = showCId fun
|
|
||||||
arity = maybe 0 getArrity (functionType gr fun)
|
arity = maybe 0 getArrity (functionType gr fun)
|
||||||
vars = ['e':show i | i <- [1..arity]]
|
vars = ['e':show i | i <- [1..arity]]
|
||||||
|
|
||||||
|
|||||||
@@ -1,262 +0,0 @@
|
|||||||
----------------------------------------------------------------------
|
|
||||||
-- |
|
|
||||||
-- Module : PGFtoProlog
|
|
||||||
-- Maintainer : Peter Ljunglöf
|
|
||||||
--
|
|
||||||
-- exports a GF grammar into a Prolog module
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
module GF.Compile.PGFtoProlog (grammar2prolog) where
|
|
||||||
|
|
||||||
import PGF(mkCId,wildCId,showCId)
|
|
||||||
import PGF.Internal
|
|
||||||
--import PGF.Macros
|
|
||||||
|
|
||||||
import GF.Data.Operations
|
|
||||||
|
|
||||||
import qualified Data.Array.IArray as Array
|
|
||||||
import qualified Data.Set as Set
|
|
||||||
import qualified Data.Map as Map
|
|
||||||
import qualified Data.IntMap as IntMap
|
|
||||||
import Data.Char (isAlphaNum, isAscii, isAsciiLower, isAsciiUpper, ord)
|
|
||||||
import Data.List (isPrefixOf, mapAccumL)
|
|
||||||
|
|
||||||
grammar2prolog :: PGF -> String
|
|
||||||
grammar2prolog pgf
|
|
||||||
= ("%% This file was automatically generated by GF" +++++
|
|
||||||
":- style_check(-singleton)." +++++
|
|
||||||
plFacts wildCId "abstract" 1 "(?AbstractName)"
|
|
||||||
[[plp name]] ++++
|
|
||||||
plFacts wildCId "concrete" 2 "(?AbstractName, ?ConcreteName)"
|
|
||||||
[[plp name, plp cncname] |
|
|
||||||
cncname <- Map.keys (concretes pgf)] ++++
|
|
||||||
plFacts wildCId "flag" 2 "(?Flag, ?Value): global flags"
|
|
||||||
[[plp f, plp v] |
|
|
||||||
(f, v) <- Map.assocs (gflags pgf)] ++++
|
|
||||||
plAbstract name (abstract pgf) ++++
|
|
||||||
unlines (map plConcrete (Map.assocs (concretes pgf)))
|
|
||||||
)
|
|
||||||
where name = absname pgf
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
-- abstract syntax
|
|
||||||
|
|
||||||
plAbstract :: CId -> Abstr -> String
|
|
||||||
plAbstract name abs
|
|
||||||
= (plHeader "Abstract syntax" ++++
|
|
||||||
plFacts name "flag" 2 "(?Flag, ?Value): flags for abstract syntax"
|
|
||||||
[[plp f, plp v] |
|
|
||||||
(f, v) <- Map.assocs (aflags abs)] ++++
|
|
||||||
plFacts name "cat" 2 "(?Type, ?[X:Type,...])"
|
|
||||||
[[plType cat args, plHypos hypos'] |
|
|
||||||
(cat, (hypos,_,_)) <- Map.assocs (cats abs),
|
|
||||||
let ((_, subst), hypos') = mapAccumL alphaConvertHypo emptyEnv hypos,
|
|
||||||
let args = reverse [EFun x | (_,x) <- subst]] ++++
|
|
||||||
plFacts name "fun" 3 "(?Fun, ?Type, ?[X:Type,...])"
|
|
||||||
[[plp fun, plType cat args, plHypos hypos] |
|
|
||||||
(fun, (typ, _, _, _)) <- Map.assocs (funs abs),
|
|
||||||
let (_, DTyp hypos cat args) = alphaConvert emptyEnv typ] ++++
|
|
||||||
plFacts name "def" 2 "(?Fun, ?Expr)"
|
|
||||||
[[plp fun, plp expr] |
|
|
||||||
(fun, (_, _, Just (eqs,_), _)) <- Map.assocs (funs abs),
|
|
||||||
let (_, expr) = alphaConvert emptyEnv eqs]
|
|
||||||
)
|
|
||||||
where plType cat args = plTerm (plp cat) (map plp args)
|
|
||||||
plHypos hypos = plList [plOper ":" (plp x) (plp ty) | (_, x, ty) <- hypos]
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
-- concrete syntax
|
|
||||||
|
|
||||||
plConcrete :: (CId, Concr) -> String
|
|
||||||
plConcrete (name, cnc)
|
|
||||||
= (plHeader ("Concrete syntax: " ++ plp name) ++++
|
|
||||||
plFacts name "flag" 2 "(?Flag, ?Value): flags for concrete syntax"
|
|
||||||
[[plp f, plp v] |
|
|
||||||
(f, v) <- Map.assocs (cflags cnc)] ++++
|
|
||||||
plFacts name "printname" 2 "(?AbsFun/AbsCat, ?Atom)"
|
|
||||||
[[plp f, plp n] |
|
|
||||||
(f, n) <- Map.assocs (printnames cnc)] ++++
|
|
||||||
plFacts name "lindef" 2 "(?CncCat, ?CncFun)"
|
|
||||||
[[plCat cat, plFun fun] |
|
|
||||||
(cat, funs) <- IntMap.assocs (lindefs cnc),
|
|
||||||
fun <- funs] ++++
|
|
||||||
plFacts name "prod" 3 "(?CncCat, ?CncFun, ?[CncCat])"
|
|
||||||
[[plCat cat, fun, plTerm "c" (map plCat args)] |
|
|
||||||
(cat, set) <- IntMap.toList (productions cnc),
|
|
||||||
(fun, args) <- map plProduction (Set.toList set)] ++++
|
|
||||||
plFacts name "cncfun" 3 "(?CncFun, ?[Seq,...], ?AbsFun)"
|
|
||||||
[[plFun fun, plTerm "s" (map plSeq (Array.elems lins)), plp absfun] |
|
|
||||||
(fun, CncFun absfun lins) <- Array.assocs (cncfuns cnc)] ++++
|
|
||||||
plFacts name "seq" 2 "(?Seq, ?[Term])"
|
|
||||||
[[plSeq seq, plp (Array.elems symbols)] |
|
|
||||||
(seq, symbols) <- Array.assocs (sequences cnc)] ++++
|
|
||||||
plFacts name "cnccat" 2 "(?AbsCat, ?[CnCCat])"
|
|
||||||
[[plp cat, plList (map plCat [start..end])] |
|
|
||||||
(cat, CncCat start end _) <- Map.assocs (cnccats cnc)]
|
|
||||||
)
|
|
||||||
where plProduction (PCoerce arg) = ("-", [arg])
|
|
||||||
plProduction (PApply funid args) = (plFun funid, [fid | PArg hypos fid <- args])
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
-- prolog-printing pgf datatypes
|
|
||||||
|
|
||||||
instance PLPrint Type where
|
|
||||||
plp (DTyp hypos cat args)
|
|
||||||
| null hypos = result
|
|
||||||
| otherwise = plOper " -> " plHypos result
|
|
||||||
where result = plTerm (plp cat) (map plp args)
|
|
||||||
plHypos = plList [plOper ":" (plp x) (plp ty) | (_,x,ty) <- hypos]
|
|
||||||
|
|
||||||
instance PLPrint Expr where
|
|
||||||
plp (EFun x) = plp x
|
|
||||||
plp (EAbs _ x e)= plOper "^" (plp x) (plp e)
|
|
||||||
plp (EApp e e') = plOper " * " (plp e) (plp e')
|
|
||||||
plp (ELit lit) = plp lit
|
|
||||||
plp (EMeta n) = "Meta_" ++ show n
|
|
||||||
|
|
||||||
instance PLPrint Patt where
|
|
||||||
plp (PVar x) = plp x
|
|
||||||
plp (PApp f ps) = plOper " * " (plp f) (plp ps)
|
|
||||||
plp (PLit lit) = plp lit
|
|
||||||
|
|
||||||
instance PLPrint Equation where
|
|
||||||
plp (Equ patterns result) = plOper ":" (plp patterns) (plp result)
|
|
||||||
|
|
||||||
instance PLPrint CId where
|
|
||||||
plp cid | isLogicalVariable str || cid == wildCId = plVar str
|
|
||||||
| otherwise = plAtom str
|
|
||||||
where str = showCId cid
|
|
||||||
|
|
||||||
instance PLPrint Literal where
|
|
||||||
plp (LStr s) = plp s
|
|
||||||
plp (LInt n) = plp (show n)
|
|
||||||
plp (LFlt f) = plp (show f)
|
|
||||||
|
|
||||||
instance PLPrint Symbol where
|
|
||||||
plp (SymCat n l) = plOper ":" (show n) (show l)
|
|
||||||
plp (SymLit n l) = plTerm "lit" [show n, show l]
|
|
||||||
plp (SymVar n l) = plTerm "var" [show n, show l]
|
|
||||||
plp (SymKS t) = plAtom t
|
|
||||||
plp (SymKP ts alts) = plTerm "pre" [plList (map plp ts), plList (map plAlt alts)]
|
|
||||||
where plAlt (ps,ts) = plOper "/" (plList (map plp ps)) (plList (map plAtom ts))
|
|
||||||
|
|
||||||
class PLPrint a where
|
|
||||||
plp :: a -> String
|
|
||||||
plps :: [a] -> String
|
|
||||||
plps = plList . map plp
|
|
||||||
|
|
||||||
instance PLPrint Char where
|
|
||||||
plp c = plAtom [c]
|
|
||||||
plps s = plAtom s
|
|
||||||
|
|
||||||
instance PLPrint a => PLPrint [a] where
|
|
||||||
plp = plps
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
-- other prolog-printing functions
|
|
||||||
|
|
||||||
plCat :: Int -> String
|
|
||||||
plCat n = plAtom ('c' : show n)
|
|
||||||
|
|
||||||
plFun :: Int -> String
|
|
||||||
plFun n = plAtom ('f' : show n)
|
|
||||||
|
|
||||||
plSeq :: Int -> String
|
|
||||||
plSeq n = plAtom ('s' : show n)
|
|
||||||
|
|
||||||
plHeader :: String -> String
|
|
||||||
plHeader hdr = "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%% " ++ hdr ++ "\n"
|
|
||||||
|
|
||||||
plFacts :: CId -> String -> Int -> String -> [[String]] -> String
|
|
||||||
plFacts mod pred arity comment facts = "%% " ++ pred ++ comment ++++ clauses
|
|
||||||
where clauses = (if facts == [] then ":- dynamic " ++ pred ++ "/" ++ show arity ++ ".\n"
|
|
||||||
else unlines [mod' ++ plTerm pred args ++ "." | args <- facts])
|
|
||||||
mod' = if mod == wildCId then "" else plp mod ++ ": "
|
|
||||||
|
|
||||||
plTerm :: String -> [String] -> String
|
|
||||||
plTerm fun args = plAtom fun ++ prParenth (prTList ", " args)
|
|
||||||
|
|
||||||
plList :: [String] -> String
|
|
||||||
plList xs = prBracket (prTList "," xs)
|
|
||||||
|
|
||||||
plOper :: String -> String -> String -> String
|
|
||||||
plOper op a b = prParenth (a ++ op ++ b)
|
|
||||||
|
|
||||||
plVar :: String -> String
|
|
||||||
plVar = varPrefix . concatMap changeNonAlphaNum
|
|
||||||
where varPrefix var@(c:_) | isAsciiUpper c || c=='_' = var
|
|
||||||
| otherwise = "_" ++ var
|
|
||||||
changeNonAlphaNum c | isAlphaNumUnderscore c = [c]
|
|
||||||
| otherwise = "_" ++ show (ord c) ++ "_"
|
|
||||||
|
|
||||||
plAtom :: String -> String
|
|
||||||
plAtom "" = "''"
|
|
||||||
plAtom atom@(c:cs) | isAsciiLower c && all isAlphaNumUnderscore cs
|
|
||||||
|| c == '\'' && cs /= "" && last cs == '\'' = atom
|
|
||||||
| otherwise = "'" ++ changeQuote atom ++ "'"
|
|
||||||
where changeQuote ('\'':cs) = '\\' : '\'' : changeQuote cs
|
|
||||||
changeQuote ('\\':cs) = '\\' : '\\' : changeQuote cs
|
|
||||||
changeQuote (c:cs) = c : changeQuote cs
|
|
||||||
changeQuote "" = ""
|
|
||||||
|
|
||||||
isAlphaNumUnderscore :: Char -> Bool
|
|
||||||
isAlphaNumUnderscore c = (isAscii c && isAlphaNum c) || c == '_'
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
-- prolog variables
|
|
||||||
|
|
||||||
createLogicalVariable :: Int -> CId
|
|
||||||
createLogicalVariable n = mkCId (logicalVariablePrefix ++ show n)
|
|
||||||
|
|
||||||
isLogicalVariable :: String -> Bool
|
|
||||||
isLogicalVariable = isPrefixOf logicalVariablePrefix
|
|
||||||
|
|
||||||
logicalVariablePrefix :: String
|
|
||||||
logicalVariablePrefix = "X"
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
-- alpha convert variables to (unique) logical variables
|
|
||||||
-- * this is needed if we want to translate variables to Prolog variables
|
|
||||||
-- * used for abstract syntax, not concrete
|
|
||||||
-- * not (yet?) used for variables bound in pattern equations
|
|
||||||
|
|
||||||
type ConvertEnv = (Int, [(CId,CId)])
|
|
||||||
|
|
||||||
emptyEnv :: ConvertEnv
|
|
||||||
emptyEnv = (0, [])
|
|
||||||
|
|
||||||
class AlphaConvert a where
|
|
||||||
alphaConvert :: ConvertEnv -> a -> (ConvertEnv, a)
|
|
||||||
|
|
||||||
instance AlphaConvert a => AlphaConvert [a] where
|
|
||||||
alphaConvert env [] = (env, [])
|
|
||||||
alphaConvert env (a:as) = (env'', a':as')
|
|
||||||
where (env', a') = alphaConvert env a
|
|
||||||
(env'', as') = alphaConvert env' as
|
|
||||||
|
|
||||||
instance AlphaConvert Type where
|
|
||||||
alphaConvert env@(_,subst) (DTyp hypos cat args)
|
|
||||||
= ((ctr,subst), DTyp hypos' cat args')
|
|
||||||
where (env', hypos') = mapAccumL alphaConvertHypo env hypos
|
|
||||||
((ctr,_), args') = alphaConvert env' args
|
|
||||||
|
|
||||||
alphaConvertHypo env (b,x,typ) = ((ctr+1,(x,x'):subst), (b,x',typ'))
|
|
||||||
where ((ctr,subst), typ') = alphaConvert env typ
|
|
||||||
x' = createLogicalVariable ctr
|
|
||||||
|
|
||||||
instance AlphaConvert Expr where
|
|
||||||
alphaConvert (ctr,subst) (EAbs b x e) = ((ctr',subst), EAbs b x' e')
|
|
||||||
where ((ctr',_), e') = alphaConvert (ctr+1,(x,x'):subst) e
|
|
||||||
x' = createLogicalVariable ctr
|
|
||||||
alphaConvert env (EApp e1 e2) = (env'', EApp e1' e2')
|
|
||||||
where (env', e1') = alphaConvert env e1
|
|
||||||
(env'', e2') = alphaConvert env' e2
|
|
||||||
alphaConvert env expr@(EFun i) = (env, maybe expr EFun (lookup i (snd env)))
|
|
||||||
alphaConvert env expr = (env, expr)
|
|
||||||
|
|
||||||
-- pattern variables are not alpha converted
|
|
||||||
-- (but they probably should be...)
|
|
||||||
instance AlphaConvert Equation where
|
|
||||||
alphaConvert env@(_,subst) (Equ patterns result)
|
|
||||||
= ((ctr,subst), Equ patterns result')
|
|
||||||
where ((ctr,_), result') = alphaConvert env result
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
----------------------------------------------------------------------
|
|
||||||
-- |
|
|
||||||
-- Module : PGFtoPython
|
|
||||||
-- Maintainer : Peter Ljunglöf
|
|
||||||
--
|
|
||||||
-- exports a GF grammar into a Python module
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
|
||||||
module GF.Compile.PGFtoPython (pgf2python) where
|
|
||||||
|
|
||||||
import PGF(showCId)
|
|
||||||
import PGF.Internal as M
|
|
||||||
|
|
||||||
import GF.Data.Operations
|
|
||||||
|
|
||||||
import qualified Data.Array.IArray as Array
|
|
||||||
import qualified Data.Set as Set
|
|
||||||
import qualified Data.Map as Map
|
|
||||||
import qualified Data.IntMap as IntMap
|
|
||||||
--import Data.List (intersperse)
|
|
||||||
|
|
||||||
pgf2python :: PGF -> String
|
|
||||||
pgf2python pgf = ("# -*- coding: utf-8 -*-" ++++
|
|
||||||
"# This file was automatically generated by GF" +++++
|
|
||||||
showCId name +++ "=" +++
|
|
||||||
pyDict 1 pyStr id [
|
|
||||||
("flags", pyDict 2 pyCId pyLiteral (Map.assocs (gflags pgf))),
|
|
||||||
("abstract", pyDict 2 pyStr id [
|
|
||||||
("name", pyCId name),
|
|
||||||
("start", pyCId start),
|
|
||||||
("flags", pyDict 3 pyCId pyLiteral (Map.assocs (aflags abs))),
|
|
||||||
("funs", pyDict 3 pyCId pyAbsdef (Map.assocs (funs abs)))
|
|
||||||
]),
|
|
||||||
("concretes", pyDict 2 pyCId pyConcrete (Map.assocs cncs))
|
|
||||||
] ++ "\n")
|
|
||||||
where
|
|
||||||
name = absname pgf
|
|
||||||
start = M.lookStartCat pgf
|
|
||||||
abs = abstract pgf
|
|
||||||
cncs = concretes pgf
|
|
||||||
|
|
||||||
pyAbsdef :: (Type, Int, Maybe ([Equation], [[M.Instr]]), Double) -> String
|
|
||||||
pyAbsdef (typ, _, _, _) = pyTuple 0 id [pyCId cat, pyList 0 pyCId args]
|
|
||||||
where (args, cat) = M.catSkeleton typ
|
|
||||||
|
|
||||||
pyLiteral :: Literal -> String
|
|
||||||
pyLiteral (LStr s) = pyStr s
|
|
||||||
pyLiteral (LInt n) = show n
|
|
||||||
pyLiteral (LFlt d) = show d
|
|
||||||
|
|
||||||
pyConcrete :: Concr -> String
|
|
||||||
pyConcrete cnc = pyDict 3 pyStr id [
|
|
||||||
("flags", pyDict 0 pyCId pyLiteral (Map.assocs (cflags cnc))),
|
|
||||||
("printnames", pyDict 4 pyCId pyStr (Map.assocs (printnames cnc))),
|
|
||||||
("lindefs", pyDict 4 pyCat (pyList 0 pyFun) (IntMap.assocs (lindefs cnc))),
|
|
||||||
("productions", pyDict 4 pyCat pyProds (IntMap.assocs (productions cnc))),
|
|
||||||
("cncfuns", pyDict 4 pyFun pyCncFun (Array.assocs (cncfuns cnc))),
|
|
||||||
("sequences", pyDict 4 pySeq pySymbols (Array.assocs (sequences cnc))),
|
|
||||||
("cnccats", pyDict 4 pyCId pyCncCat (Map.assocs (cnccats cnc))),
|
|
||||||
("size", show (totalCats cnc))
|
|
||||||
]
|
|
||||||
where pyProds prods = pyList 5 pyProduction (Set.toList prods)
|
|
||||||
pyCncCat (CncCat start end _) = pyList 0 pyCat [start..end]
|
|
||||||
pyCncFun (CncFun f lins) = pyTuple 0 id [pyList 0 pySeq (Array.elems lins), pyCId f]
|
|
||||||
pySymbols syms = pyList 0 pySymbol (Array.elems syms)
|
|
||||||
|
|
||||||
pyProduction :: Production -> String
|
|
||||||
pyProduction (PCoerce arg) = pyTuple 0 id [pyStr "", pyList 0 pyCat [arg]]
|
|
||||||
pyProduction (PApply funid args) = pyTuple 0 id [pyFun funid, pyList 0 pyPArg args]
|
|
||||||
where pyPArg (PArg [] fid) = pyCat fid
|
|
||||||
pyPArg (PArg hypos fid) = pyTuple 0 pyCat (fid : map snd hypos)
|
|
||||||
|
|
||||||
pySymbol :: Symbol -> String
|
|
||||||
pySymbol (SymCat n l) = pyTuple 0 show [n, l]
|
|
||||||
pySymbol (SymLit n l) = pyDict 0 pyStr id [("lit", pyTuple 0 show [n, l])]
|
|
||||||
pySymbol (SymVar n l) = pyDict 0 pyStr id [("var", pyTuple 0 show [n, l])]
|
|
||||||
pySymbol (SymKS t) = pyStr t
|
|
||||||
pySymbol (SymKP ts alts) = pyDict 0 pyStr id [("pre", pyList 0 pySymbol ts), ("alts", pyList 0 alt2py alts)]
|
|
||||||
where alt2py (ps,ts) = pyTuple 0 (pyList 0 pyStr) [map pySymbol ps, ts]
|
|
||||||
pySymbol SymBIND = pyStr "&+"
|
|
||||||
pySymbol SymSOFT_BIND = pyStr "&+"
|
|
||||||
pySymbol SymSOFT_SPACE = pyStr "&+"
|
|
||||||
pySymbol SymCAPIT = pyStr "&|"
|
|
||||||
pySymbol SymALL_CAPIT = pyStr "&|"
|
|
||||||
pySymbol SymNE = pyDict 0 pyStr id [("nonExist", pyTuple 0 id [])]
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
-- python helpers
|
|
||||||
|
|
||||||
pyDict :: Int -> (k -> String) -> (v -> String) -> [(k, v)] -> String
|
|
||||||
pyDict n pk pv [] = "{}"
|
|
||||||
pyDict n pk pv kvlist = prCurly (pyIndent n ++ prTList ("," ++ pyIndent n) (map pyKV kvlist) ++ pyIndent n)
|
|
||||||
where pyKV (k, v) = pk k ++ ":" ++ pv v
|
|
||||||
|
|
||||||
pyList :: Int -> (v -> String) -> [v] -> String
|
|
||||||
pyList n pv [] = "[]"
|
|
||||||
pyList n pv xs = prBracket (pyIndent n ++ prTList ("," ++ pyIndent n) (map pv xs) ++ pyIndent n)
|
|
||||||
|
|
||||||
pyTuple :: Int -> (v -> String) -> [v] -> String
|
|
||||||
pyTuple n pv [] = "()"
|
|
||||||
pyTuple n pv [x] = prParenth (pyIndent n ++ pv x ++ "," ++ pyIndent n)
|
|
||||||
pyTuple n pv xs = prParenth (pyIndent n ++ prTList ("," ++ pyIndent n) (map pv xs) ++ pyIndent n)
|
|
||||||
|
|
||||||
pyCat :: Int -> String
|
|
||||||
pyCat n = pyStr ('C' : show n)
|
|
||||||
|
|
||||||
pyFun :: Int -> String
|
|
||||||
pyFun n = pyStr ('F' : show n)
|
|
||||||
|
|
||||||
pySeq :: Int -> String
|
|
||||||
pySeq n = pyStr ('S' : show n)
|
|
||||||
|
|
||||||
pyStr :: String -> String
|
|
||||||
pyStr s = 'u' : prQuotedString s
|
|
||||||
|
|
||||||
pyCId :: CId -> String
|
|
||||||
pyCId = pyStr . showCId
|
|
||||||
|
|
||||||
pyIndent :: Int -> String
|
|
||||||
pyIndent n | n > 0 = "\n" ++ replicate n ' '
|
|
||||||
| otherwise = ""
|
|
||||||
@@ -27,19 +27,20 @@ module GF.Compile.Rename (
|
|||||||
renameModule
|
renameModule
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import GF.Infra.Ident
|
||||||
|
import GF.Infra.CheckM
|
||||||
import GF.Grammar.Grammar
|
import GF.Grammar.Grammar
|
||||||
import GF.Grammar.Values
|
import GF.Grammar.Values
|
||||||
import GF.Grammar.Predef
|
import GF.Grammar.Predef
|
||||||
import GF.Infra.Ident
|
import GF.Grammar.Lookup
|
||||||
import GF.Infra.CheckM
|
|
||||||
import GF.Grammar.Macros
|
import GF.Grammar.Macros
|
||||||
import GF.Grammar.Printer
|
import GF.Grammar.Printer
|
||||||
--import GF.Grammar.Lookup
|
|
||||||
--import GF.Grammar.Printer
|
|
||||||
import GF.Data.Operations
|
import GF.Data.Operations
|
||||||
|
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Data.List (nub,(\\))
|
import Data.List (nub,(\\))
|
||||||
|
import qualified Data.Map as Map
|
||||||
|
import Data.Maybe(mapMaybe)
|
||||||
import GF.Text.Pretty
|
import GF.Text.Pretty
|
||||||
|
|
||||||
-- | this gives top-level access to renaming term input in the cc command
|
-- | this gives top-level access to renaming term input in the cc command
|
||||||
@@ -55,9 +56,9 @@ renameModule cwd gr mo@(m,mi) = do
|
|||||||
js <- checkMapRecover (renameInfo cwd status mo) (jments mi)
|
js <- checkMapRecover (renameInfo cwd status mo) (jments mi)
|
||||||
return (m, mi{jments = js})
|
return (m, mi{jments = js})
|
||||||
|
|
||||||
type Status = (StatusTree, [(OpenSpec, StatusTree)])
|
type Status = (StatusMap, [(OpenSpec, StatusMap)])
|
||||||
|
|
||||||
type StatusTree = BinTree Ident StatusInfo
|
type StatusMap = Map.Map Ident StatusInfo
|
||||||
|
|
||||||
type StatusInfo = Ident -> Term
|
type StatusInfo = Ident -> Term
|
||||||
|
|
||||||
@@ -73,12 +74,12 @@ renameIdentTerm' env@(act,imps) t0 =
|
|||||||
Q (m',c) | m' == cPredef {- && isInPredefined c -} -> return t0
|
Q (m',c) | m' == cPredef {- && isInPredefined c -} -> return t0
|
||||||
Q (m',c) -> do
|
Q (m',c) -> do
|
||||||
m <- lookupErr m' qualifs
|
m <- lookupErr m' qualifs
|
||||||
f <- lookupTree showIdent c m
|
f <- lookupIdent c m
|
||||||
return $ f c
|
return $ f c
|
||||||
QC (m',c) | m' == cPredef {- && isInPredefined c -} -> return t0
|
QC (m',c) | m' == cPredef {- && isInPredefined c -} -> return t0
|
||||||
QC (m',c) -> do
|
QC (m',c) -> do
|
||||||
m <- lookupErr m' qualifs
|
m <- lookupErr m' qualifs
|
||||||
f <- lookupTree showIdent c m
|
f <- lookupIdent c m
|
||||||
return $ f c
|
return $ f c
|
||||||
_ -> return t0
|
_ -> return t0
|
||||||
where
|
where
|
||||||
@@ -93,41 +94,32 @@ renameIdentTerm' env@(act,imps) t0 =
|
|||||||
| otherwise = checkError s
|
| otherwise = checkError s
|
||||||
|
|
||||||
ident alt c =
|
ident alt c =
|
||||||
case lookupTree showIdent c act of
|
case Map.lookup c act of
|
||||||
Ok f -> return (f c)
|
Just f -> return (f c)
|
||||||
_ -> case lookupTreeManyAll showIdent opens c of
|
_ -> case mapMaybe (Map.lookup c) opens of
|
||||||
[f] -> return (f c)
|
[f] -> return (f c)
|
||||||
[] -> alt c ("constant not found:" <+> c $$
|
[] -> alt c ("constant not found:" <+> c $$
|
||||||
"given" <+> fsep (punctuate ',' (map fst qualifs)))
|
"given" <+> fsep (punctuate ',' (map fst qualifs)))
|
||||||
fs -> case nub [f c | f <- fs] of
|
fs -> case nub [f c | f <- fs] of
|
||||||
[tr] -> return tr
|
[tr] -> return tr
|
||||||
{-
|
ts@(t:_) -> do checkWarn ("atomic term" <+> ppTerm Qualified 0 t0 $$
|
||||||
ts -> return $ AdHocOverload ts
|
"conflict" <+> hsep (punctuate ',' (map (ppTerm Qualified 0) ts)) $$
|
||||||
-- name conflicts resolved as overloading in TypeCheck.RConcrete AR 31/1/2014
|
"given" <+> fsep (punctuate ',' (map fst qualifs)))
|
||||||
-- the old definition is below and still presupposed in TypeCheck.Concrete
|
return t
|
||||||
-}
|
|
||||||
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
|
|
||||||
|
|
||||||
-- a warning will be generated in CheckGrammar, and the head returned
|
info2status :: Maybe ModuleName -> Ident -> Info -> StatusInfo
|
||||||
-- in next V:
|
info2status mq c i = case i of
|
||||||
-- Bad $ "conflicting imports:" +++ unwords (map prt ts)
|
|
||||||
|
|
||||||
info2status :: Maybe ModuleName -> (Ident,Info) -> StatusInfo
|
|
||||||
info2status mq (c,i) = case i of
|
|
||||||
AbsFun _ _ Nothing _ -> maybe Con (curry QC) mq
|
AbsFun _ _ Nothing _ -> maybe Con (curry QC) mq
|
||||||
ResValue _ -> maybe Con (curry QC) mq
|
ResValue _ _ -> maybe Con (curry QC) mq
|
||||||
ResParam _ _ -> maybe Con (curry QC) mq
|
ResParam _ _ -> maybe Con (curry QC) mq
|
||||||
AnyInd True m -> maybe Con (const (curry QC m)) mq
|
AnyInd True m -> maybe Con (const (curry QC m)) mq
|
||||||
AnyInd False m -> maybe Cn (const (curry Q m)) mq
|
AnyInd False m -> maybe Cn (const (curry Q m)) mq
|
||||||
_ -> maybe Cn (curry Q) mq
|
_ -> maybe Cn (curry Q) mq
|
||||||
|
|
||||||
tree2status :: OpenSpec -> BinTree Ident Info -> BinTree Ident StatusInfo
|
tree2status :: OpenSpec -> Map.Map Ident Info -> StatusMap
|
||||||
tree2status o = case o of
|
tree2status o = case o of
|
||||||
OSimple i -> mapTree (info2status (Just i))
|
OSimple i -> Map.mapWithKey (info2status (Just i))
|
||||||
OQualif i j -> mapTree (info2status (Just j))
|
OQualif i j -> Map.mapWithKey (info2status (Just j))
|
||||||
|
|
||||||
buildStatus :: FilePath -> Grammar -> Module -> Check Status
|
buildStatus :: FilePath -> Grammar -> Module -> Check Status
|
||||||
buildStatus cwd gr mo@(m,mi) = checkInModule cwd mi NoLoc empty $ do
|
buildStatus cwd gr mo@(m,mi) = checkInModule cwd mi NoLoc empty $ do
|
||||||
@@ -136,14 +128,14 @@ buildStatus cwd gr mo@(m,mi) = checkInModule cwd mi NoLoc empty $ do
|
|||||||
ops <- mapM (\o -> lookupModule gr1 (openedModule o) >>= \mi -> return (o,mi)) (mopens mi)
|
ops <- mapM (\o -> lookupModule gr1 (openedModule o) >>= \mi -> return (o,mi)) (mopens mi)
|
||||||
let sts = map modInfo2status (exts++ops)
|
let sts = map modInfo2status (exts++ops)
|
||||||
return (if isModCnc mi
|
return (if isModCnc mi
|
||||||
then (emptyBinTree, reverse sts) -- the module itself does not define any names
|
then (Map.empty, reverse sts) -- the module itself does not define any names
|
||||||
else (self2status m mi,reverse sts)) -- so the empty ident is not needed
|
else (self2status m mi,reverse sts)) -- so the empty ident is not needed
|
||||||
|
|
||||||
modInfo2status :: (OpenSpec,ModuleInfo) -> (OpenSpec, StatusTree)
|
modInfo2status :: (OpenSpec,ModuleInfo) -> (OpenSpec, StatusMap)
|
||||||
modInfo2status (o,mo) = (o,tree2status o (jments mo))
|
modInfo2status (o,mo) = (o,tree2status o (jments mo))
|
||||||
|
|
||||||
self2status :: ModuleName -> ModuleInfo -> StatusTree
|
self2status :: ModuleName -> ModuleInfo -> StatusMap
|
||||||
self2status c m = mapTree (info2status (Just c)) (jments m)
|
self2status c m = Map.mapWithKey (info2status (Just c)) (jments m)
|
||||||
|
|
||||||
|
|
||||||
renameInfo :: FilePath -> Status -> Module -> Ident -> Info -> Check Info
|
renameInfo :: FilePath -> Status -> Module -> Ident -> Info -> Check Info
|
||||||
@@ -156,9 +148,9 @@ renameInfo cwd status (m,mi) i info =
|
|||||||
ResParam (Just pp) m -> do
|
ResParam (Just pp) m -> do
|
||||||
pp' <- renLoc (mapM (renParam status)) pp
|
pp' <- renLoc (mapM (renParam status)) pp
|
||||||
return (ResParam (Just pp') m)
|
return (ResParam (Just pp') m)
|
||||||
ResValue t -> do
|
ResValue ty offset -> do
|
||||||
t <- renLoc (renameTerm status []) t
|
t <- renLoc (renameTerm status []) ty
|
||||||
return (ResValue t)
|
return (ResValue ty offset)
|
||||||
CncCat mcat mdef mref mpr mpmcfg -> liftM5 CncCat (renTerm mcat) (renTerm mdef) (renTerm mref) (renTerm mpr) (return mpmcfg)
|
CncCat mcat mdef mref mpr mpmcfg -> liftM5 CncCat (renTerm mcat) (renTerm mdef) (renTerm mref) (renTerm mpr) (return mpmcfg)
|
||||||
CncFun mty mtr mpr mpmcfg -> liftM3 (CncFun mty) (renTerm mtr) (renTerm mpr) (return mpmcfg)
|
CncFun mty mtr mpr mpmcfg -> liftM3 (CncFun mty) (renTerm mtr) (renTerm mpr) (return mpmcfg)
|
||||||
_ -> return info
|
_ -> return info
|
||||||
@@ -186,9 +178,9 @@ renameInfo cwd status (m,mi) i info =
|
|||||||
return (ps',t')
|
return (ps',t')
|
||||||
|
|
||||||
renParam :: Status -> Param -> Check Param
|
renParam :: Status -> Param -> Check Param
|
||||||
renParam env (c,co) = do
|
renParam env (c,co,i) = do
|
||||||
co' <- renameContext env co
|
co' <- renameContext env co
|
||||||
return (c,co')
|
return (c,co',i)
|
||||||
|
|
||||||
renameTerm :: Status -> [Ident] -> Term -> Check Term
|
renameTerm :: Status -> [Ident] -> Term -> Check Term
|
||||||
renameTerm env vars = ren vars where
|
renameTerm env vars = ren vars where
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ getLocalTags x (m,mi) =
|
|||||||
getLocations (AbsFun mb_type _ mb_eqs _) = maybe (ltype "fun") mb_type ++
|
getLocations (AbsFun mb_type _ mb_eqs _) = maybe (ltype "fun") mb_type ++
|
||||||
maybe (list (loc "def")) mb_eqs
|
maybe (list (loc "def")) mb_eqs
|
||||||
getLocations (ResParam mb_params _) = maybe (loc "param") mb_params
|
getLocations (ResParam mb_params _) = maybe (loc "param") mb_params
|
||||||
getLocations (ResValue mb_type) = ltype "param-value" mb_type
|
getLocations (ResValue mb_type _) = ltype "param-value" mb_type
|
||||||
getLocations (ResOper mb_type mb_def) = maybe (ltype "oper-type") mb_type ++
|
getLocations (ResOper mb_type mb_def) = maybe (ltype "oper-type") mb_type ++
|
||||||
maybe (loc "oper-def") mb_def
|
maybe (loc "oper-def") mb_def
|
||||||
getLocations (ResOverload _ defs) = list (\(x,y) -> ltype "overload-type" x ++
|
getLocations (ResOverload _ defs) = list (\(x,y) -> ltype "overload-type" x ++
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user