forked from GitHub/gf-core
Compare commits
180 Commits
concrete-n
...
lpgf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b47eb18f86 | ||
|
|
1ce1cea068 | ||
|
|
48dba4ade5 | ||
|
|
b96fa7e08a | ||
|
|
42bdee1e5f | ||
|
|
e2ed512bbb | ||
|
|
265f08d6ee | ||
|
|
e47042424e | ||
|
|
ecf309a28e | ||
|
|
d0a881f903 | ||
|
|
810640822d | ||
|
|
ed79955931 | ||
|
|
1867bfc8a1 | ||
|
|
6ef4f27d32 | ||
|
|
3ab07ec58f | ||
|
|
b8324fe3e6 | ||
|
|
8814fde817 | ||
|
|
375b3cf285 | ||
|
|
3c4f42db15 | ||
|
|
0474a37af6 | ||
|
|
e3498d5ead | ||
|
|
4c5927c98c | ||
|
|
bb51224e8e | ||
|
|
9533edc3ca | ||
|
|
4df8999ed5 | ||
|
|
7fdbf3f400 | ||
|
|
0d6c67f6b1 | ||
|
|
2610219f6a | ||
|
|
7674f078d6 | ||
|
|
c67fe05c08 | ||
|
|
7b9bb780a2 | ||
|
|
4f256447e2 | ||
|
|
1b8a9b37b0 | ||
|
|
dfa5b9276d | ||
|
|
667bfd30bd | ||
|
|
66ae31e99e | ||
|
|
a677f0373c | ||
|
|
13f845d127 | ||
|
|
aa530233fb | ||
|
|
45bc5595c0 | ||
|
|
6d12754e4f | ||
|
|
a09d9bd006 | ||
|
|
fffe3161d4 | ||
|
|
743f5e55d4 | ||
|
|
9e209bbaba | ||
|
|
a1594e6a69 | ||
|
|
06e0a986d1 | ||
|
|
6f2a4bcd2c | ||
|
|
f345f615f4 | ||
|
|
80d16fcf94 | ||
|
|
7faf8c9dad | ||
|
|
c2ffa6763b | ||
|
|
b3881570c7 | ||
|
|
bd270b05ff | ||
|
|
e681e4dbb0 | ||
|
|
639f1f043a | ||
|
|
c02a3e0617 | ||
|
|
a1fd3ea142 | ||
|
|
d6e26e0577 | ||
|
|
89a01d81cc | ||
|
|
2315641e77 | ||
|
|
7dc396e841 | ||
|
|
cdbe73eb47 | ||
|
|
d6416089d6 | ||
|
|
6077d5dd5b | ||
|
|
7b0637850c | ||
|
|
0954b4cbab | ||
|
|
2b8d792e09 | ||
|
|
045def61d8 | ||
|
|
f2e52d6f2c | ||
|
|
a2b23d5897 | ||
|
|
2be54ffb12 | ||
|
|
4bd26eae6d | ||
|
|
0886eb520d | ||
|
|
ef42216415 | ||
|
|
0c3ca3d79a | ||
|
|
e2e5033075 | ||
|
|
84b4b6fab9 | ||
|
|
5e052ff499 | ||
|
|
e1a40640cd | ||
|
|
be231584f6 | ||
|
|
12c564f97c | ||
|
|
c1af40532c | ||
|
|
d0c27cdaae | ||
|
|
f7df62a445 | ||
|
|
2d066853f1 | ||
|
|
f900ea3885 | ||
|
|
d9c37fc093 | ||
|
|
c9f0867491 | ||
|
|
6c6a201d96 | ||
|
|
8f5033e4ce | ||
|
|
126b61ea03 | ||
|
|
99abb9b2a5 | ||
|
|
3e9d12854a | ||
|
|
fd07946a50 | ||
|
|
c76efcf916 | ||
|
|
785d6069e2 | ||
|
|
0f4b349b0b | ||
|
|
dbf369aae5 | ||
|
|
0d4659fe8c | ||
|
|
575a746a3e | ||
|
|
70581c2d8c | ||
|
|
bca1e2286d | ||
|
|
94f76b9e36 | ||
|
|
f5886bf447 | ||
|
|
0ba0438dc7 | ||
|
|
30b016032d | ||
|
|
4082c006c3 | ||
|
|
adc162b374 | ||
|
|
3beed2c49e | ||
|
|
a8e3dc8855 | ||
|
|
997d7c1694 | ||
|
|
4c09e4a340 | ||
|
|
33e0e98aec | ||
|
|
83bc3c9c6e | ||
|
|
f42b5ec9ef | ||
|
|
4771d9c356 | ||
|
|
9785f8351d | ||
|
|
6a5d735904 | ||
|
|
8324ad8801 | ||
|
|
20290be616 | ||
|
|
b4a393ac09 | ||
|
|
9942908df9 | ||
|
|
dca2ebaf72 | ||
|
|
5ad5789b31 | ||
|
|
9f3f4139b1 | ||
|
|
505c12c528 | ||
|
|
023b50557e | ||
|
|
2b0493eece | ||
|
|
51e543878b | ||
|
|
625386a14f | ||
|
|
5240749fad | ||
|
|
e6079523f1 | ||
|
|
866a2101e1 | ||
|
|
d8557e8433 | ||
|
|
7a5bc2dab3 | ||
|
|
9a263450f5 | ||
|
|
8e1fa4981f | ||
|
|
b4fce5db59 | ||
|
|
6a7ead0f84 | ||
|
|
d3988f93d5 | ||
|
|
236dbdbba3 | ||
|
|
768c3d9b2d | ||
|
|
29114ce606 | ||
|
|
5be21dba1c | ||
|
|
d5cf00f711 | ||
|
|
312cfeb69d | ||
|
|
2d03b9ee0c | ||
|
|
4c06c3f825 | ||
|
|
7227ede24b | ||
|
|
398b294734 | ||
|
|
d394cacddf | ||
|
|
21f14c2aa1 | ||
|
|
23e49cddb7 | ||
|
|
4d1217b06d | ||
|
|
4f0abe5540 | ||
|
|
109822675b | ||
|
|
d563abb928 | ||
|
|
a58a6c8a59 | ||
|
|
98f6136ebd | ||
|
|
8cfaa69b6e | ||
|
|
a12f58e7b0 | ||
|
|
d5f68970b9 | ||
|
|
9c2d8eb0b2 | ||
|
|
34f0fc0ba7 | ||
|
|
42b9e7036e | ||
|
|
132f693713 | ||
|
|
153bffdad7 | ||
|
|
d09838e97e | ||
|
|
c94bffe435 | ||
|
|
2a5850023b | ||
|
|
fe15aa0c00 | ||
|
|
cead0cc4c1 | ||
|
|
6f622b496b | ||
|
|
270e7f021f | ||
|
|
32b0860925 | ||
|
|
f24c50339b | ||
|
|
cd5881d83a | ||
|
|
93b81b9f13 | ||
|
|
8ad9cf1e09 |
28
.github/workflows/build-all-versions.yml
vendored
28
.github/workflows/build-all-versions.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
cabal: ["3.2"]
|
||||
cabal: ["latest"]
|
||||
ghc:
|
||||
- "8.6.5"
|
||||
- "8.8.3"
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
|
||||
|
||||
- uses: actions/setup-haskell@v1.1.4
|
||||
- uses: haskell/actions/setup@v1
|
||||
id: setup-haskell-cabal
|
||||
name: Setup Haskell
|
||||
with:
|
||||
@@ -53,19 +53,19 @@ jobs:
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cabal configure --enable-tests --enable-benchmarks --test-show-details=direct
|
||||
cabal build all
|
||||
cabal configure --enable-tests --test-show-details=direct
|
||||
cabal build
|
||||
|
||||
# - name: Test
|
||||
# run: |
|
||||
# cabal test all
|
||||
- name: Test
|
||||
run: |
|
||||
PATH="$PWD/dist/build/gf:$PATH" cabal test gf-tests
|
||||
|
||||
stack:
|
||||
name: stack / ghc ${{ matrix.ghc }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
stack: ["2.3.3"]
|
||||
stack: ["latest"]
|
||||
ghc: ["7.10.3","8.0.2", "8.2.2", "8.4.4", "8.6.5", "8.8.4"]
|
||||
# ghc: ["8.8.3"]
|
||||
|
||||
@@ -73,11 +73,12 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
|
||||
|
||||
- uses: actions/setup-haskell@v1.1.4
|
||||
- uses: haskell/actions/setup@v1
|
||||
name: Setup Haskell Stack
|
||||
with:
|
||||
# ghc-version: ${{ matrix.ghc }}
|
||||
stack-version: ${{ matrix.stack }}
|
||||
ghc-version: ${{ matrix.ghc }}
|
||||
stack-version: 'latest'
|
||||
enable-stack: true
|
||||
|
||||
- uses: actions/cache@v1
|
||||
name: Cache ~/.stack
|
||||
@@ -87,9 +88,8 @@ jobs:
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
stack build --system-ghc --stack-yaml stack-ghc${{ matrix.ghc }}.yaml
|
||||
# stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks
|
||||
stack build --system-ghc --stack-yaml stack-ghc${{ matrix.ghc }}.yaml --test --no-run-tests
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
stack test --system-ghc --stack-yaml stack-ghc${{ matrix.ghc }}.yaml
|
||||
stack test --system-ghc --stack-yaml stack-ghc${{ matrix.ghc }}.yaml gf:test:gf-tests
|
||||
|
||||
73
.github/workflows/build-binary-packages.yml
vendored
73
.github/workflows/build-binary-packages.yml
vendored
@@ -3,6 +3,7 @@ name: Build Binary Packages
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: ["created"]
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -10,11 +11,13 @@ jobs:
|
||||
|
||||
ubuntu:
|
||||
name: Build Ubuntu package
|
||||
runs-on: ubuntu-18.04
|
||||
# strategy:
|
||||
# matrix:
|
||||
# ghc: ["8.6.5"]
|
||||
# cabal: ["2.4"]
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-18.04
|
||||
- ubuntu-20.04
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
@@ -53,19 +56,33 @@ jobs:
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: gf-${{ github.sha }}-ubuntu
|
||||
name: gf-${{ github.event.release.tag_name }}-${{ matrix.os }}.deb
|
||||
path: dist/gf_*.deb
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Rename package for specific ubuntu version
|
||||
run: |
|
||||
mv dist/gf_*.deb dist/gf-${{ github.event.release.tag_name }}-${{ matrix.os }}.deb
|
||||
|
||||
- uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ github.event.release.upload_url }}
|
||||
asset_path: dist/gf-${{ github.event.release.tag_name }}-${{ matrix.os }}.deb
|
||||
asset_name: gf-${{ github.event.release.tag_name }}-${{ matrix.os }}.deb
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
# ---
|
||||
|
||||
macos:
|
||||
name: Build macOS package
|
||||
runs-on: macos-10.15
|
||||
strategy:
|
||||
matrix:
|
||||
ghc: ["8.6.5"]
|
||||
cabal: ["2.4"]
|
||||
os: ["macos-10.15"]
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
@@ -92,19 +109,33 @@ jobs:
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: gf-${{ github.sha }}-macos
|
||||
name: gf-${{ github.event.release.tag_name }}-macos
|
||||
path: dist/gf-*.pkg
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Rename package
|
||||
run: |
|
||||
mv dist/gf-*.pkg dist/gf-${{ github.event.release.tag_name }}-macos.pkg
|
||||
|
||||
- uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ github.event.release.upload_url }}
|
||||
asset_path: dist/gf-${{ github.event.release.tag_name }}-macos.pkg
|
||||
asset_name: gf-${{ github.event.release.tag_name }}-macos.pkg
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
# ---
|
||||
|
||||
windows:
|
||||
name: Build Windows package
|
||||
runs-on: windows-2019
|
||||
strategy:
|
||||
matrix:
|
||||
ghc: ["8.6.5"]
|
||||
cabal: ["2.4"]
|
||||
os: ["windows-2019"]
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
@@ -136,16 +167,18 @@ jobs:
|
||||
cp /mingw64/bin/libpgf-0.dll /c/tmp-dist/c
|
||||
cp /mingw64/bin/libgu-0.dll /c/tmp-dist/c
|
||||
|
||||
# JAVA_HOME_8_X64 = C:\hostedtoolcache\windows\Java_Adopt_jdk\8.0.292-10\x64
|
||||
- name: Build Java bindings
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
export PATH="${PATH}:/c/Program Files/Java/jdk8u275-b01/bin"
|
||||
export JDKPATH=/c/hostedtoolcache/windows/Java_Adopt_jdk/8.0.292-10/x64
|
||||
export PATH="${PATH}:${JDKPATH}/bin"
|
||||
cd src/runtime/java
|
||||
make \
|
||||
JNI_INCLUDES="-I \"/c/Program Files/Java/jdk8u275-b01/include\" -I \"/c/Program Files/Java/jdk8u275-b01/include/win32\" -I \"/mingw64/include\" -D__int64=int64_t" \
|
||||
JNI_INCLUDES="-I \"${JDKPATH}/include\" -I \"${JDKPATH}/include/win32\" -I \"/mingw64/include\" -D__int64=int64_t" \
|
||||
WINDOWS_LDFLAGS="-L\"/mingw64/lib\" -no-undefined"
|
||||
make install
|
||||
cp .libs//msys-jpgf-0.dll /c/tmp-dist/java/jpgf.dll
|
||||
cp .libs/msys-jpgf-0.dll /c/tmp-dist/java/jpgf.dll
|
||||
cp jpgf.jar /c/tmp-dist/java
|
||||
|
||||
- name: Build Python bindings
|
||||
@@ -157,7 +190,7 @@ jobs:
|
||||
cd src/runtime/python
|
||||
python setup.py build
|
||||
python setup.py install
|
||||
cp /usr/lib/python3.8/site-packages/pgf* /c/tmp-dist/python
|
||||
cp /usr/lib/python3.9/site-packages/pgf* /c/tmp-dist/python
|
||||
|
||||
- name: Setup Haskell
|
||||
uses: actions/setup-haskell@v1
|
||||
@@ -180,6 +213,18 @@ jobs:
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: gf-${{ github.sha }}-windows
|
||||
name: gf-${{ github.event.release.tag_name }}-windows
|
||||
path: C:\tmp-dist\*
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Create archive
|
||||
run: |
|
||||
Compress-Archive C:\tmp-dist C:\gf-${{ github.event.release.tag_name }}-windows.zip
|
||||
- uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ github.event.release.upload_url }}
|
||||
asset_path: C:\gf-${{ github.event.release.tag_name }}-windows.zip
|
||||
asset_name: gf-${{ github.event.release.tag_name }}-windows.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -5,6 +5,7 @@
|
||||
*.jar
|
||||
*.gfo
|
||||
*.pgf
|
||||
*.lpgf
|
||||
debian/.debhelper
|
||||
debian/debhelper-build-stamp
|
||||
debian/gf
|
||||
@@ -48,7 +49,7 @@ src/runtime/java/.libs/
|
||||
src/runtime/python/build/
|
||||
.cabal-sandbox
|
||||
cabal.sandbox.config
|
||||
.stack-work
|
||||
.stack-work*
|
||||
DATA_DIR
|
||||
|
||||
stack*.yaml.lock
|
||||
@@ -73,3 +74,10 @@ doc/icfp-2012.html
|
||||
download/*.html
|
||||
gf-book/index.html
|
||||
src/www/gf-web-api.html
|
||||
|
||||
DEBUG/
|
||||
PROF/
|
||||
*.aux
|
||||
*.hp
|
||||
*.prof
|
||||
*.ps
|
||||
|
||||
41
Makefile
41
Makefile
@@ -1,31 +1,48 @@
|
||||
.PHONY: all build install doc clean gf html deb pkg bintar sdist
|
||||
.PHONY: all build install doc clean html deb pkg bintar sdist
|
||||
|
||||
# This gets the numeric part of the version from the cabal file
|
||||
VERSION=$(shell sed -ne "s/^version: *\([0-9.]*\).*/\1/p" gf.cabal)
|
||||
|
||||
# Check if stack is installed
|
||||
STACK=$(shell if hash stack 2>/dev/null; then echo "1"; else echo "0"; fi)
|
||||
|
||||
# Check if cabal >= 2.4 is installed (with v1- and v2- commands)
|
||||
CABAL_NEW=$(shell if cabal v1-repl --help >/dev/null 2>&1 ; then echo "1"; else echo "0"; fi)
|
||||
|
||||
ifeq ($(STACK),1)
|
||||
CMD=stack
|
||||
else
|
||||
CMD=cabal
|
||||
ifeq ($(CABAL_NEW),1)
|
||||
CMD_PFX=v1-
|
||||
endif
|
||||
endif
|
||||
|
||||
all: build
|
||||
|
||||
dist/setup-config: gf.cabal Setup.hs WebSetup.hs
|
||||
cabal configure
|
||||
ifneq ($(STACK),1)
|
||||
cabal ${CMD_PFX}configure
|
||||
endif
|
||||
|
||||
build: dist/setup-config
|
||||
cabal build
|
||||
${CMD} ${CMD_PFX}build
|
||||
|
||||
install:
|
||||
cabal copy
|
||||
cabal register
|
||||
ifeq ($(STACK),1)
|
||||
stack install
|
||||
else
|
||||
cabal ${CMD_PFX}copy
|
||||
cabal ${CMD_PFX}register
|
||||
endif
|
||||
|
||||
doc:
|
||||
cabal haddock
|
||||
${CMD} ${CMD_PFX}haddock
|
||||
|
||||
clean:
|
||||
cabal clean
|
||||
${CMD} ${CMD_PFX}clean
|
||||
bash bin/clean_html
|
||||
|
||||
gf:
|
||||
cabal build rgl-none
|
||||
strip dist/build/gf/gf
|
||||
|
||||
html::
|
||||
bash bin/update_html
|
||||
|
||||
@@ -35,7 +52,7 @@ html::
|
||||
deb:
|
||||
dpkg-buildpackage -b -uc
|
||||
|
||||
# Make an OS X Installer package
|
||||
# Make a macOS installer package
|
||||
pkg:
|
||||
FMT=pkg bash bin/build-binary-dist.sh
|
||||
|
||||
|
||||
6
debian/changelog
vendored
6
debian/changelog
vendored
@@ -1,3 +1,9 @@
|
||||
gf (3.11) bionic focal; urgency=low
|
||||
|
||||
* GF 3.11
|
||||
|
||||
-- Inari Listenmaa <inari@digitalgrammars.com> Sun, 25 Jul 2021 10:27:40 +0800
|
||||
|
||||
gf (3.10.4-1) xenial bionic cosmic; urgency=low
|
||||
|
||||
* GF 3.10.4
|
||||
|
||||
10
debian/rules
vendored
10
debian/rules
vendored
@@ -16,9 +16,9 @@ override_dh_shlibdeps:
|
||||
override_dh_auto_configure:
|
||||
cd src/runtime/c && bash setup.sh configure --prefix=/usr
|
||||
cd src/runtime/c && bash setup.sh build
|
||||
cabal update
|
||||
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 v1-update
|
||||
cabal v1-install --only-dependencies
|
||||
cabal v1-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
|
||||
|
||||
@@ -26,10 +26,10 @@ 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
|
||||
echo $(SET_LDL)
|
||||
-$(SET_LDL) cabal build
|
||||
-$(SET_LDL) cabal v1-build
|
||||
|
||||
override_dh_auto_install:
|
||||
$(SET_LDL) cabal copy --destdir=$(CURDIR)/debian/gf
|
||||
$(SET_LDL) cabal v1-copy --destdir=$(CURDIR)/debian/gf
|
||||
cd src/runtime/c && bash setup.sh copy prefix=$(CURDIR)/debian/gf/usr
|
||||
cd src/runtime/python && python setup.py install --prefix=$(CURDIR)/debian/gf/usr
|
||||
cd src/runtime/java && make INSTALL_PATH=$(CURDIR)/debian/gf/usr install
|
||||
|
||||
201
doc/gf-developers-old-cabal.t2t
Normal file
201
doc/gf-developers-old-cabal.t2t
Normal file
@@ -0,0 +1,201 @@
|
||||
GF Developer's Guide: Old installation instructions with Cabal
|
||||
|
||||
|
||||
This page contains the old installation instructions from the [Developer's Guide ../doc/gf-developers.html].
|
||||
We recommend Stack as a primary installation method, because it's easier for a Haskell beginner, and we want to keep the main instructions short.
|
||||
But if you are an experienced Haskeller and want to keep using Cabal, here are the old instructions using ``cabal install``.
|
||||
|
||||
Note that some of these instructions may be outdated. Other parts may still be useful.
|
||||
|
||||
== Compilation from source with Cabal ==
|
||||
|
||||
The build system of GF is based on //Cabal//, which is part of the
|
||||
Haskell Platform, so no extra steps are needed to install it. In the simplest
|
||||
case, all you need to do to compile and install GF, after downloading the
|
||||
source code as described above, is
|
||||
|
||||
```
|
||||
$ cabal install
|
||||
```
|
||||
|
||||
This will automatically download any additional Haskell libraries needed to
|
||||
build GF. If this is the first time you use Cabal, you might need to run
|
||||
``cabal update`` first, to update the list of available libraries.
|
||||
|
||||
If you want more control, the process can also be split up into the usual
|
||||
//configure//, //build// and //install// steps.
|
||||
|
||||
=== Configure ===
|
||||
|
||||
During the configuration phase Cabal will check that you have all
|
||||
necessary tools and libraries needed for GF. The configuration is
|
||||
started by the command:
|
||||
|
||||
```
|
||||
$ cabal configure
|
||||
```
|
||||
|
||||
If you don't see any error message from the above command then you
|
||||
have everything that is needed for GF. You can also add the option
|
||||
``-v`` to see more details about the configuration.
|
||||
|
||||
You can use ``cabal configure --help`` to get a list of configuration options.
|
||||
|
||||
=== Build ===
|
||||
|
||||
The build phase does two things. First it builds the GF compiler from
|
||||
the Haskell source code and after that it builds the GF Resource Grammar
|
||||
Library using the already build compiler. The simplest command is:
|
||||
|
||||
```
|
||||
$ cabal build
|
||||
```
|
||||
|
||||
Again you can add the option ``-v`` if you want to see more details.
|
||||
|
||||
==== Parallel builds ====
|
||||
|
||||
If you have Cabal>=1.20 you can enable parallel compilation by using
|
||||
|
||||
```
|
||||
$ cabal build -j
|
||||
```
|
||||
|
||||
or by putting a line
|
||||
```
|
||||
jobs: $ncpus
|
||||
```
|
||||
in your ``.cabal/config`` file. Cabal
|
||||
will pass this option to GHC when building the GF compiler, if you
|
||||
have GHC>=7.8.
|
||||
|
||||
Cabal also passes ``-j`` to GF to enable parallel compilation of the
|
||||
Resource Grammar Library. This is done unconditionally to avoid
|
||||
causing problems for developers with Cabal<1.20. You can disable this
|
||||
by editing the last few lines in ``WebSetup.hs``.
|
||||
|
||||
=== Install ===
|
||||
|
||||
After you have compiled GF you need to install the executable and libraries
|
||||
to make the system usable.
|
||||
|
||||
```
|
||||
$ cabal copy
|
||||
$ cabal register
|
||||
```
|
||||
|
||||
This command installs the GF compiler for a single user, in the standard
|
||||
place used by Cabal.
|
||||
On Linux and Mac this could be ``$HOME/.cabal/bin``.
|
||||
On Mac it could also be ``$HOME/Library/Haskell/bin``.
|
||||
On Windows this is ``C:\Program Files\Haskell\bin``.
|
||||
|
||||
The compiled GF Resource Grammar Library will be installed
|
||||
under the same prefix, e.g. in
|
||||
``$HOME/.cabal/share/gf-3.3.3/lib`` on Linux and
|
||||
in ``C:\Program Files\Haskell\gf-3.3.3\lib`` on Windows.
|
||||
|
||||
If you want to install in some other place then use the ``--prefix``
|
||||
option during the configuration phase.
|
||||
|
||||
=== Clean ===
|
||||
|
||||
Sometimes you want to clean up the compilation and start again from clean
|
||||
sources. Use the clean command for this purpose:
|
||||
|
||||
```
|
||||
$ cabal clean
|
||||
```
|
||||
|
||||
|
||||
%=== SDist ===
|
||||
%
|
||||
%You can use the command:
|
||||
%
|
||||
%% This does *NOT* include everything that is needed // TH 2012-08-06
|
||||
%```
|
||||
%$ cabal sdist
|
||||
%```
|
||||
%
|
||||
%to prepare archive with all source codes needed to compile GF.
|
||||
|
||||
=== Known problems with Cabal ===
|
||||
|
||||
Some versions of Cabal (at least version 1.16) seem to have a bug that can
|
||||
cause the following error:
|
||||
|
||||
```
|
||||
Configuring gf-3.x...
|
||||
setup: Distribution/Simple/PackageIndex.hs:124:8-13: Assertion failed
|
||||
```
|
||||
|
||||
The exact cause of this problem is unclear, but it seems to happen
|
||||
during the configure phase if the same version of GF is already installed,
|
||||
so a workaround is to remove the existing installation with
|
||||
|
||||
```
|
||||
ghc-pkg unregister gf
|
||||
```
|
||||
|
||||
You can check with ``ghc-pkg list gf`` that it is gone.
|
||||
|
||||
== Compilation with make ==
|
||||
|
||||
If you feel more comfortable with Makefiles then there is a thin Makefile
|
||||
wrapper arround Cabal for you. If you just type:
|
||||
```
|
||||
$ make
|
||||
```
|
||||
the configuration phase will be run automatically if needed and after that
|
||||
the sources will be compiled.
|
||||
|
||||
%% cabal build rgl-none does not work with recent versions of Cabal
|
||||
%If you don't want to compile the resource library
|
||||
%every time then you can use:
|
||||
%```
|
||||
%$ make gf
|
||||
%```
|
||||
|
||||
For installation use:
|
||||
```
|
||||
$ make install
|
||||
```
|
||||
For cleaning:
|
||||
```
|
||||
$ make clean
|
||||
```
|
||||
%and to build source distribution archive run:
|
||||
%```
|
||||
%$ make sdist
|
||||
%```
|
||||
|
||||
|
||||
== Partial builds of RGL ==
|
||||
|
||||
**NOTE**: The following doesn't work with recent versions of ``cabal``. //(This comment was left in 2015, so make your own conclusions.)//
|
||||
%% // TH 2015-06-22
|
||||
|
||||
%Sometimes you just want to work on the GF compiler and don't want to
|
||||
%recompile the resource library after each change. In this case use
|
||||
%this extended command:
|
||||
|
||||
%```
|
||||
%$ cabal build rgl-none
|
||||
%```
|
||||
|
||||
The resource grammar library can be compiled in two modes: with present
|
||||
tense only and with all tenses. By default it is compiled with all
|
||||
tenses. If you want to use the library with only present tense you can
|
||||
compile it in this special mode with the command:
|
||||
|
||||
```
|
||||
$ cabal build present
|
||||
```
|
||||
|
||||
You could also control which languages you want to be recompiled by
|
||||
adding the option ``langs=list``. For example the following command
|
||||
will compile only the English and the Swedish language:
|
||||
|
||||
```
|
||||
$ cabal build langs=Eng,Swe
|
||||
```
|
||||
@@ -1,6 +1,6 @@
|
||||
GF Developers Guide
|
||||
|
||||
2018-07-26
|
||||
2021-07-15
|
||||
|
||||
%!options(html): --toc
|
||||
|
||||
@@ -15,388 +15,287 @@ you are a GF user who just wants to download and install GF
|
||||
== Setting up your system for building GF ==
|
||||
|
||||
To build GF from source you need to install some tools on your
|
||||
system: the //Haskell Platform//, //Git// and the //Haskeline library//.
|
||||
system: the Haskell build tool //Stack//, the version control software //Git// and the //Haskeline// library.
|
||||
|
||||
**On Linux** the best option is to install the tools via the standard
|
||||
software distribution channels, i.e. by using the //Software Center//
|
||||
in Ubuntu or the corresponding tool in other popular Linux distributions.
|
||||
Or, from a Terminal window, the following command should be enough:
|
||||
%**On Linux** the best option is to install the tools via the standard
|
||||
%software distribution channels, i.e. by using the //Software Center//
|
||||
%in Ubuntu or the corresponding tool in other popular Linux distributions.
|
||||
|
||||
- On Ubuntu: ``sudo apt-get install haskell-platform git libghc6-haskeline-dev``
|
||||
- On Fedora: ``sudo dnf install haskell-platform git ghc-haskeline-devel``
|
||||
%**On Mac OS and Windows**, the tools can be downloaded from their respective
|
||||
%web sites, as described below.
|
||||
|
||||
=== Stack ===
|
||||
The primary installation method is via //Stack//.
|
||||
(You can also use Cabal, but we recommend Stack to those who are new to Haskell.)
|
||||
|
||||
To install Stack:
|
||||
|
||||
- **On Linux and Mac OS**, do either
|
||||
|
||||
``$ curl -sSL https://get.haskellstack.org/ | sh``
|
||||
|
||||
or
|
||||
|
||||
``$ wget -qO- https://get.haskellstack.org/ | sh``
|
||||
|
||||
|
||||
**On Mac OS and Windows**, the tools can be downloaded from their respective
|
||||
web sites, as described below.
|
||||
- **On other operating systems**, see the [installation guide https://docs.haskellstack.org/en/stable/install_and_upgrade].
|
||||
|
||||
=== The Haskell Platform ===
|
||||
|
||||
GF is written in Haskell, so first of all you need
|
||||
the //Haskell Platform//, e.g. version 8.0.2 or 7.10.3. Downloads
|
||||
and installation instructions are available from here:
|
||||
%If you already have Stack installed, upgrade it to the latest version by running: ``stack upgrade``
|
||||
|
||||
http://hackage.haskell.org/platform/
|
||||
|
||||
Once you have installed the Haskell Platform, open a terminal
|
||||
(Command Prompt on Windows) and try to execute the following command:
|
||||
```
|
||||
$ ghc --version
|
||||
```
|
||||
This command should show you which version of GHC you have. If the installation
|
||||
of the Haskell Platform was successful you should see a message like:
|
||||
|
||||
```
|
||||
The Glorious Glasgow Haskell Compilation System, version 8.0.2
|
||||
```
|
||||
|
||||
Other required tools included in the Haskell Platform are
|
||||
[Cabal http://www.haskell.org/cabal/],
|
||||
[Alex http://www.haskell.org/alex/]
|
||||
and
|
||||
[Happy http://www.haskell.org/happy/].
|
||||
|
||||
=== Git ===
|
||||
|
||||
To get the GF source code, you also need //Git//.
|
||||
//Git// is a distributed version control system, see
|
||||
https://git-scm.com/downloads for more information.
|
||||
To get the GF source code, you also need //Git//, a distributed version control system.
|
||||
|
||||
=== The haskeline library ===
|
||||
- **On Linux**, the best option is to install the tools via the standard
|
||||
software distribution channels:
|
||||
|
||||
- On Ubuntu: ``sudo apt-get install git-all``
|
||||
- On Fedora: ``sudo dnf install git-all``
|
||||
|
||||
|
||||
- **On other operating systems**, see
|
||||
https://git-scm.com/book/en/v2/Getting-Started-Installing-Git for installation.
|
||||
|
||||
|
||||
|
||||
=== Haskeline ===
|
||||
|
||||
GF uses //haskeline// to enable command line editing in the GF shell.
|
||||
This should work automatically on Mac OS and Windows, but on Linux one
|
||||
extra step is needed to make sure the C libraries (terminfo)
|
||||
required by //haskeline// are installed. Here is one way to do this:
|
||||
|
||||
- On Ubuntu: ``sudo apt-get install libghc-haskeline-dev``
|
||||
- On Fedora: ``sudo dnf install ghc-haskeline-devel``
|
||||
- **On Mac OS and Windows**, this should work automatically.
|
||||
|
||||
- **On Linux**, an extra step is needed to make sure the C libraries (terminfo)
|
||||
required by //haskeline// are installed:
|
||||
|
||||
- On Ubuntu: ``sudo apt-get install libghc-haskeline-dev``
|
||||
- On Fedora: ``sudo dnf install ghc-haskeline-devel``
|
||||
|
||||
|
||||
== Getting the source ==
|
||||
== Getting the source ==[getting-source]
|
||||
|
||||
Once you have all tools in place you can get the GF source code. If you
|
||||
just want to compile and use GF then it is enough to have read-only
|
||||
access. It is also possible to make changes in the source code but if you
|
||||
want these changes to be applied back to the main source repository you will
|
||||
have to send the changes to us. If you plan to work continuously on
|
||||
GF then you should consider getting read-write access.
|
||||
Once you have all tools in place you can get the GF source code from
|
||||
[GitHub https://github.com/GrammaticalFramework/]:
|
||||
|
||||
=== Read-only access ===
|
||||
- https://github.com/GrammaticalFramework/gf-core for the GF compiler
|
||||
- https://github.com/GrammaticalFramework/gf-rgl for the Resource Grammar Library
|
||||
|
||||
==== Getting a fresh copy for read-only access ====
|
||||
|
||||
Anyone can get the latest development version of GF by running:
|
||||
=== Read-only access: clone the main repository ===
|
||||
|
||||
If you only want to compile and use GF, you can just clone the repositories as follows:
|
||||
|
||||
```
|
||||
$ git clone https://github.com/GrammaticalFramework/gf-core.git
|
||||
$ git clone https://github.com/GrammaticalFramework/gf-rgl.git
|
||||
$ git clone https://github.com/GrammaticalFramework/gf-core.git
|
||||
$ git clone https://github.com/GrammaticalFramework/gf-rgl.git
|
||||
```
|
||||
|
||||
This will create directories ``gf-core`` and ``gf-rgl`` in the current directory.
|
||||
|
||||
|
||||
==== Updating your copy ====
|
||||
|
||||
To get all new patches from each repo:
|
||||
```
|
||||
$ git pull
|
||||
```
|
||||
This can be done anywhere in your local repository.
|
||||
|
||||
|
||||
==== Recording local changes ====[record]
|
||||
|
||||
Since every copy is a repository, you can have local version control
|
||||
of your changes.
|
||||
|
||||
If you have added files, you first need to tell your local repository to
|
||||
keep them under revision control:
|
||||
To get new updates, run the following anywhere in your local copy of the repository:
|
||||
|
||||
```
|
||||
$ git add file1 file2 ...
|
||||
$ git pull
|
||||
```
|
||||
|
||||
To record changes, use:
|
||||
=== Contribute your changes: fork the main repository ===
|
||||
|
||||
If you want the possibility to contribute your changes,
|
||||
you should create your own fork, do your changes there,
|
||||
and then send a pull request to the main repository.
|
||||
|
||||
+ **Creating and cloning a fork —**
|
||||
See GitHub documentation for instructions how to [create your own fork https://docs.github.com/en/get-started/quickstart/fork-a-repo]
|
||||
of the repository. Once you've done it, clone the fork to your local computer.
|
||||
|
||||
```
|
||||
$ git commit file1 file2 ...
|
||||
$ git clone https://github.com/<YOUR_USERNAME>/gf-core.git
|
||||
```
|
||||
|
||||
This creates a patch against the previous version and stores it in your
|
||||
local repository. You can record any number of changes before
|
||||
pushing them to the main repo. In fact, you don't have to push them at
|
||||
all if you want to keep the changes only in your local repo.
|
||||
|
||||
Instead of enumerating all modified files on the command line,
|
||||
you can use the flag ``-a`` to automatically record //all// modified
|
||||
files. You still need to use ``git add`` to add new files.
|
||||
|
||||
|
||||
=== Read-write access ===
|
||||
|
||||
If you are a member of the GF project on GitHub, you can push your
|
||||
changes directly to the GF git repository on GitHub.
|
||||
+ **Updating your copy —**
|
||||
Once you have cloned your fork, you need to set up the main repository as a remote:
|
||||
|
||||
```
|
||||
$ git push
|
||||
$ git remote add upstream https://github.com/GrammaticalFramework/gf-core.git
|
||||
```
|
||||
|
||||
It is also possible for anyone else to contribute by
|
||||
Then you can get the latest updates by running the following:
|
||||
|
||||
- creating a fork of the GF repository on GitHub,
|
||||
- working with local clone of the fork (obtained with ``git clone``),
|
||||
- pushing changes to the fork,
|
||||
- and finally sending a pull request.
|
||||
```
|
||||
$ git pull upstream master
|
||||
```
|
||||
|
||||
+ **Recording local changes —**
|
||||
See Git tutorial on how to [record and push your changes https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository] to your fork.
|
||||
|
||||
+ **Pull request —**
|
||||
When you want to contribute your changes to the main gf-core repository,
|
||||
[create a pull request https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request]
|
||||
from your fork.
|
||||
|
||||
|
||||
|
||||
== Compilation from source with Cabal ==
|
||||
If you want to contribute to the RGL as well, do the same process for the RGL repository.
|
||||
|
||||
The build system of GF is based on //Cabal//, which is part of the
|
||||
Haskell Platform, so no extra steps are needed to install it. In the simplest
|
||||
case, all you need to do to compile and install GF, after downloading the
|
||||
source code as described above, is
|
||||
|
||||
== Compilation from source ==
|
||||
|
||||
By now you should have installed Stack and Haskeline, and cloned the Git repository on your own computer, in a directory called ``gf-core``.
|
||||
|
||||
=== Primary recommendation: use Stack ===
|
||||
|
||||
Open a terminal, go to the top directory (``gf-core``), and type the following command.
|
||||
|
||||
```
|
||||
$ stack install
|
||||
```
|
||||
|
||||
It will install GF and all necessary tools and libraries to do that.
|
||||
|
||||
|
||||
=== Alternative: use Cabal ===
|
||||
You can also install GF using Cabal, if you prefer Cabal to Stack. In that case, you may need to install some prerequisites yourself.
|
||||
|
||||
The actual installation process is similar to Stack: open a terminal, go to the top directory (``gf-core``), and type the following command.
|
||||
|
||||
```
|
||||
$ cabal install
|
||||
```
|
||||
|
||||
This will automatically download any additional Haskell libraries needed to
|
||||
build GF. If this is the first time you use Cabal, you might need to run
|
||||
``cabal update`` first, to update the list of available libraries.
|
||||
//The old (potentially outdated) instructions for Cabal are moved to a [separate page ../doc/gf-developers-old-cabal.html]. If you run into trouble with ``cabal install``, you may want to take a look.//
|
||||
|
||||
If you want more control, the process can also be split up into the usual
|
||||
//configure//, //build// and //install// steps.
|
||||
== Compiling GF with C runtime system support ==
|
||||
|
||||
=== Configure ===
|
||||
|
||||
During the configuration phase Cabal will check that you have all
|
||||
necessary tools and libraries needed for GF. The configuration is
|
||||
started by the command:
|
||||
|
||||
```
|
||||
$ cabal configure
|
||||
```
|
||||
|
||||
If you don't see any error message from the above command then you
|
||||
have everything that is needed for GF. You can also add the option
|
||||
``-v`` to see more details about the configuration.
|
||||
|
||||
You can use ``cabal configure --help`` to get a list of configuration options.
|
||||
|
||||
=== Build ===
|
||||
|
||||
The build phase does two things. First it builds the GF compiler from
|
||||
the Haskell source code and after that it builds the GF Resource Grammar
|
||||
Library using the already build compiler. The simplest command is:
|
||||
|
||||
```
|
||||
$ cabal build
|
||||
```
|
||||
|
||||
Again you can add the option ``-v`` if you want to see more details.
|
||||
|
||||
==== Parallel builds ====
|
||||
|
||||
If you have Cabal>=1.20 you can enable parallel compilation by using
|
||||
|
||||
```
|
||||
$ cabal build -j
|
||||
```
|
||||
|
||||
or by putting a line
|
||||
```
|
||||
jobs: $ncpus
|
||||
```
|
||||
in your ``.cabal/config`` file. Cabal
|
||||
will pass this option to GHC when building the GF compiler, if you
|
||||
have GHC>=7.8.
|
||||
|
||||
Cabal also passes ``-j`` to GF to enable parallel compilation of the
|
||||
Resource Grammar Library. This is done unconditionally to avoid
|
||||
causing problems for developers with Cabal<1.20. You can disable this
|
||||
by editing the last few lines in ``WebSetup.hs``.
|
||||
|
||||
|
||||
==== Partial builds ====
|
||||
|
||||
**NOTE**: The following doesn't work with recent versions of ``cabal``.
|
||||
%% // TH 2015-06-22
|
||||
|
||||
Sometimes you just want to work on the GF compiler and don't want to
|
||||
recompile the resource library after each change. In this case use
|
||||
this extended command:
|
||||
|
||||
```
|
||||
$ cabal build rgl-none
|
||||
```
|
||||
|
||||
The resource library could also be compiled in two modes: with present
|
||||
tense only and with all tenses. By default it is compiled with all
|
||||
tenses. If you want to use the library with only present tense you can
|
||||
compile it in this special mode with the command:
|
||||
|
||||
```
|
||||
$ cabal build present
|
||||
```
|
||||
|
||||
You could also control which languages you want to be recompiled by
|
||||
adding the option ``langs=list``. For example the following command
|
||||
will compile only the English and the Swedish language:
|
||||
|
||||
```
|
||||
$ cabal build langs=Eng,Swe
|
||||
```
|
||||
|
||||
=== Install ===
|
||||
|
||||
After you have compiled GF you need to install the executable and libraries
|
||||
to make the system usable.
|
||||
|
||||
```
|
||||
$ cabal copy
|
||||
$ cabal register
|
||||
```
|
||||
|
||||
This command installs the GF compiler for a single user, in the standard
|
||||
place used by Cabal.
|
||||
On Linux and Mac this could be ``$HOME/.cabal/bin``.
|
||||
On Mac it could also be ``$HOME/Library/Haskell/bin``.
|
||||
On Windows this is ``C:\Program Files\Haskell\bin``.
|
||||
|
||||
The compiled GF Resource Grammar Library will be installed
|
||||
under the same prefix, e.g. in
|
||||
``$HOME/.cabal/share/gf-3.3.3/lib`` on Linux and
|
||||
in ``C:\Program Files\Haskell\gf-3.3.3\lib`` on Windows.
|
||||
|
||||
If you want to install in some other place then use the ``--prefix``
|
||||
option during the configuration phase.
|
||||
|
||||
=== Clean ===
|
||||
|
||||
Sometimes you want to clean up the compilation and start again from clean
|
||||
sources. Use the clean command for this purpose:
|
||||
|
||||
```
|
||||
$ cabal clean
|
||||
```
|
||||
|
||||
|
||||
%=== SDist ===
|
||||
%
|
||||
%You can use the command:
|
||||
%
|
||||
%% This does *NOT* include everything that is needed // TH 2012-08-06
|
||||
%```
|
||||
%$ cabal sdist
|
||||
%```
|
||||
%
|
||||
%to prepare archive with all source codes needed to compile GF.
|
||||
|
||||
=== Known problems with Cabal ===
|
||||
|
||||
Some versions of Cabal (at least version 1.16) seem to have a bug that can
|
||||
cause the following error:
|
||||
|
||||
```
|
||||
Configuring gf-3.x...
|
||||
setup: Distribution/Simple/PackageIndex.hs:124:8-13: Assertion failed
|
||||
```
|
||||
|
||||
The exact cause of this problem is unclear, but it seems to happen
|
||||
during the configure phase if the same version of GF is already installed,
|
||||
so a workaround is to remove the existing installation with
|
||||
|
||||
```
|
||||
ghc-pkg unregister gf
|
||||
```
|
||||
|
||||
You can check with ``ghc-pkg list gf`` that it is gone.
|
||||
|
||||
== Compilation with make ==
|
||||
|
||||
If you feel more comfortable with Makefiles then there is a thin Makefile
|
||||
wrapper arround Cabal for you. If you just type:
|
||||
```
|
||||
$ make
|
||||
```
|
||||
the configuration phase will be run automatically if needed and after that
|
||||
the sources will be compiled.
|
||||
|
||||
%% cabal build rgl-none does not work with recent versions of Cabal
|
||||
%If you don't want to compile the resource library
|
||||
%every time then you can use:
|
||||
%```
|
||||
%$ make gf
|
||||
%```
|
||||
|
||||
For installation use:
|
||||
```
|
||||
$ make install
|
||||
```
|
||||
For cleaning:
|
||||
```
|
||||
$ make clean
|
||||
```
|
||||
%and to build source distribution archive run:
|
||||
%```
|
||||
%$ make sdist
|
||||
%```
|
||||
|
||||
== Compiling GF with C run-time system support ==
|
||||
|
||||
The C run-time system is a separate implementation of the PGF run-time services.
|
||||
The C runtime system is a separate implementation of the PGF runtime services.
|
||||
It makes it possible to work with very large, ambiguous grammars, using
|
||||
probabilistic models to obtain probable parses. The C run-time system might
|
||||
also be easier to use than the Haskell run-time system on certain platforms,
|
||||
probabilistic models to obtain probable parses. The C runtime system might
|
||||
also be easier to use than the Haskell runtime system on certain platforms,
|
||||
e.g. Android and iOS.
|
||||
|
||||
To install the C run-time system, go to the ``src/runtime/c`` directory
|
||||
%and follow the instructions in the ``INSTALL`` file.
|
||||
and use the ``install.sh`` script:
|
||||
```
|
||||
bash setup.sh configure
|
||||
bash setup.sh build
|
||||
bash setup.sh install
|
||||
```
|
||||
This will install
|
||||
the C header files and libraries need to write C programs that use PGF grammars.
|
||||
Some example C programs are included in the ``utils`` subdirectory, e.g.
|
||||
``pgf-translate.c``.
|
||||
To install the C runtime system, go to the ``src/runtime/c`` directory.
|
||||
|
||||
When the C run-time system is installed, you can install GF with C run-time
|
||||
support by doing
|
||||
- **On Linux and Mac OS —**
|
||||
You should have autoconf, automake, libtool and make.
|
||||
If you are missing some of them, follow the
|
||||
instructions in the [INSTALL https://github.com/GrammaticalFramework/gf-core/blob/master/src/runtime/c/INSTALL] file.
|
||||
|
||||
Once you have the required libraries, the easiest way to install the C runtime is to use the ``install.sh`` script. Just type
|
||||
|
||||
``$ bash install.sh``
|
||||
|
||||
This will install the C header files and libraries need to write C programs
|
||||
that use PGF grammars.
|
||||
|
||||
% If this doesn't work for you, follow the manual instructions in the [INSTALL https://github.com/GrammaticalFramework/gf-core/blob/master/src/runtime/c/INSTALL] file under your operating system.
|
||||
|
||||
- **On other operating systems —** Follow the instructions in the
|
||||
[INSTALL https://github.com/GrammaticalFramework/gf-core/blob/master/src/runtime/c/INSTALL] file under your operating system.
|
||||
|
||||
|
||||
|
||||
Depending on what you want to do with the C runtime, you can follow one or more of the following steps.
|
||||
|
||||
=== Use the C runtime from another programming language ===[bindings]
|
||||
|
||||
% **If you just want to use the C runtime from Python, Java, or Haskell, you don't need to change your GF installation.**
|
||||
|
||||
- **What —**
|
||||
This is the most common use case for the C runtime: compile
|
||||
your GF grammars into PGF with the standard GF executable,
|
||||
and manipulate the PGFs from another programming language,
|
||||
using the bindings to the C runtime.
|
||||
|
||||
|
||||
- **How —**
|
||||
The Python, Java and Haskell bindings are found in the
|
||||
``src/runtime/{python,java,haskell-bind}`` directories,
|
||||
respecively. Compile them by following the instructions
|
||||
in the ``INSTALL`` or ``README`` files in those directories.
|
||||
|
||||
The Python library can also be installed from PyPI using ``pip install pgf``.
|
||||
|
||||
|
||||
//If you are on Mac and get an error about ``clang`` version, you can try some of [these solutions https://stackoverflow.com/questions/63972113/big-sur-clang-invalid-version-error-due-to-macosx-deployment-target]—but be careful before removing any existing installations.//
|
||||
|
||||
|
||||
=== Use GF shell with C runtime support ===
|
||||
|
||||
- **What —**
|
||||
If you want to use the GF shell with C runtime functionalities, then you need to (re)compile GF with special flags.
|
||||
|
||||
The GF shell can be started with ``gf -cshell`` or ``gf -crun`` to use
|
||||
the C run-time system instead of the Haskell run-time system.
|
||||
Only limited functionality is available when running the shell in these
|
||||
modes (use the ``help`` command in the shell for details).
|
||||
|
||||
(Re)compiling your GF with these flags will also give you
|
||||
Haskell bindings to the C runtime, as a library called ``PGF2``,
|
||||
but if you want Python or Java bindings, you need to do [the previous step #bindings].
|
||||
|
||||
% ``PGF2``: a module to import in Haskell programs, providing a binding to the C run-time system.
|
||||
|
||||
- **How —**
|
||||
If you use cabal, run the following command:
|
||||
|
||||
```
|
||||
cabal install -fserver -fc-runtime
|
||||
cabal install -fc-runtime
|
||||
```
|
||||
from the top directory. This give you three new things:
|
||||
|
||||
- ``PGF2``: a module to import in Haskell programs, providing a binding to
|
||||
the C run-time system.
|
||||
from the top directory (``gf-core``).
|
||||
|
||||
- The GF shell can be started with ``gf -cshell`` or ``gf -crun`` to use
|
||||
the C run-time system instead of the Haskell run-time system.
|
||||
Only limited functionality is available when running the shell in these
|
||||
modes (use the ``help`` command in the shell for details).
|
||||
If you use stack, uncomment the following lines in the ``stack.yaml`` file:
|
||||
|
||||
- ``gf -server`` mode is extended with new requests to call the C run-time
|
||||
system, e.g. ``c-parse``, ``c-linearize`` and ``c-translate``.
|
||||
```
|
||||
flags:
|
||||
gf:
|
||||
c-runtime: true
|
||||
extra-lib-dirs:
|
||||
- /usr/local/lib
|
||||
```
|
||||
and then run ``stack install`` from the top directory (``gf-core``).
|
||||
|
||||
|
||||
=== Python and Java bindings ===
|
||||
//If you get an "``error while loading shared libraries``" when trying to run GF with C runtime, remember to declare your ``LD_LIBRARY_PATH``.//
|
||||
//Add ``export LD_LIBRARY_PATH="/usr/local/lib"`` to either your ``.bashrc`` or ``.profile``. You should now be able to start GF with C runtime.//
|
||||
|
||||
|
||||
=== Use GF server mode with C runtime ===
|
||||
|
||||
- **What —**
|
||||
With this feature, ``gf -server`` mode is extended with new requests to call the C run-time
|
||||
system, e.g. ``c-parse``, ``c-linearize`` and ``c-translate``.
|
||||
|
||||
- **How —**
|
||||
If you use cabal, run the following command:
|
||||
|
||||
```
|
||||
cabal install -fc-runtime -fserver
|
||||
```
|
||||
from the top directory.
|
||||
|
||||
If you use stack, add the following lines in the ``stack.yaml`` file:
|
||||
|
||||
```
|
||||
flags:
|
||||
gf:
|
||||
c-runtime: true
|
||||
server: true
|
||||
extra-lib-dirs:
|
||||
- /usr/local/lib
|
||||
```
|
||||
|
||||
and then run ``stack install``, also from the top directory.
|
||||
|
||||
The C run-time system can also be used from Python and Java. Python and Java
|
||||
bindings are found in the ``src/runtime/python`` and ``src/runtime/java``
|
||||
directories, respecively. Compile them by following the instructions in
|
||||
the ``INSTALL`` files in those directories.
|
||||
|
||||
The Python library can also be installed from PyPI using `pip install pgf`.
|
||||
|
||||
== Compilation of RGL ==
|
||||
|
||||
As of 2018-07-26, the RGL is distributed separately from the GF compiler and runtimes.
|
||||
|
||||
To get the source, follow the previous instructions on [how to clone a repository with Git #getting-source].
|
||||
|
||||
After cloning the RGL, you should have a directory named ``gf-rgl`` on your computer.
|
||||
|
||||
=== Simple ===
|
||||
To install the RGL, you can use the following commands from within the ``gf-rgl`` repository:
|
||||
```
|
||||
@@ -418,103 +317,68 @@ If you do not have Haskell installed, you can use the simple build script ``Setu
|
||||
|
||||
== Creating binary distribution packages ==
|
||||
|
||||
=== Creating .deb packages for Ubuntu ===
|
||||
The binaries are generated with Github Actions. More details can be viewed here:
|
||||
|
||||
This was tested on Ubuntu 14.04 for the release of GF 3.6, and the
|
||||
resulting ``.deb`` packages appears to work on Ubuntu 12.04, 13.10 and 14.04.
|
||||
For the release of GF 3.7, we generated ``.deb`` packages on Ubuntu 15.04 and
|
||||
tested them on Ubuntu 12.04 and 14.04.
|
||||
https://github.com/GrammaticalFramework/gf-core/actions/workflows/build-binary-packages.yml
|
||||
|
||||
Under Ubuntu, Haskell executables are statically linked against other Haskell
|
||||
libraries, so the .deb packages are fairly self-contained.
|
||||
|
||||
==== Preparations ====
|
||||
== Running the test suite ==
|
||||
|
||||
The GF test suite is run with one of the following commands from the top directory:
|
||||
|
||||
```
|
||||
sudo apt-get install dpkg-dev debhelper
|
||||
$ cabal test
|
||||
```
|
||||
|
||||
==== Creating the package ====
|
||||
|
||||
Make sure the ``debian/changelog`` starts with an entry that describes the
|
||||
version you are building. Then run
|
||||
or
|
||||
|
||||
```
|
||||
make deb
|
||||
$ stack test
|
||||
```
|
||||
|
||||
If get error messages about missing dependencies
|
||||
(e.g. ``autoconf``, ``automake``, ``libtool-bin``, ``python-dev``,
|
||||
``java-sdk``, ``txt2tags``)
|
||||
use ``apt-get intall`` to install them, then try again.
|
||||
|
||||
|
||||
=== Creating OS X Installer packages ===
|
||||
|
||||
Run
|
||||
|
||||
```
|
||||
make pkg
|
||||
```
|
||||
|
||||
=== Creating binary tar distributions ===
|
||||
|
||||
Run
|
||||
|
||||
```
|
||||
make bintar
|
||||
```
|
||||
|
||||
=== Creating .rpm packages for Fedora ===
|
||||
|
||||
This is possible, but the procedure has not been automated.
|
||||
It involves using the cabal-rpm tool,
|
||||
|
||||
```
|
||||
sudo dnf install cabal-rpm
|
||||
```
|
||||
|
||||
and following the Fedora guide
|
||||
[How to create an RPM package http://fedoraproject.org/wiki/How_to_create_an_RPM_package].
|
||||
|
||||
Under Fedora, Haskell executables are dynamically linked against other Haskell
|
||||
libraries, so ``.rpm`` packages for all Haskell libraries that GF depends on
|
||||
are required. Most of them are already available in the Fedora distribution,
|
||||
but a few of them might have to be built and distributed along with
|
||||
the GF ``.rpm`` package.
|
||||
When building ``.rpm`` packages for GF 3.4, we also had to build ``.rpm``s for
|
||||
``fst`` and ``httpd-shed``.
|
||||
|
||||
== Running the testsuite ==
|
||||
|
||||
**NOTE:** The test suite has not been maintained recently, so expect many
|
||||
tests to fail.
|
||||
%% // TH 2012-08-06
|
||||
|
||||
GF has testsuite. It is run with the following command:
|
||||
```
|
||||
$ cabal test
|
||||
```
|
||||
The testsuite architecture for GF is very simple but still very flexible.
|
||||
GF by itself is an interpreter and could execute commands in batch mode.
|
||||
This is everything that we need to organize a testsuite. The root of the
|
||||
testsuite is the testsuite/ directory. It contains subdirectories which
|
||||
themself contain GF batch files (with extension .gfs). The above command
|
||||
searches the subdirectories of the testsuite/ directory for files with extension
|
||||
.gfs and when it finds one it is executed with the GF interpreter.
|
||||
The output of the script is stored in file with extension .out and is compared
|
||||
with the content of the corresponding file with extension .gold, if there is one.
|
||||
If the contents are identical the command reports that the test was passed successfully.
|
||||
Otherwise the test had failed.
|
||||
testsuite is the ``testsuite/`` directory. It contains subdirectories
|
||||
which themselves contain GF batch files (with extension ``.gfs``).
|
||||
The above command searches the subdirectories of the ``testsuite/`` directory
|
||||
for files with extension ``.gfs`` and when it finds one, it is executed with
|
||||
the GF interpreter. The output of the script is stored in file with extension ``.out``
|
||||
and is compared with the content of the corresponding file with extension ``.gold``, if there is one.
|
||||
|
||||
Every time when you make some changes to GF that have to be tested, instead of
|
||||
writing the commands by hand in the GF shell, add them to one .gfs file in the testsuite
|
||||
and run the test. In this way you can use the same test later and we will be sure
|
||||
that we will not incidentaly break your code later.
|
||||
Every time when you make some changes to GF that have to be tested,
|
||||
instead of writing the commands by hand in the GF shell, add them to one ``.gfs``
|
||||
file in the testsuite subdirectory where its ``.gf`` file resides and run the test.
|
||||
In this way you can use the same test later and we will be sure that we will not
|
||||
accidentally break your code later.
|
||||
|
||||
**Test Outcome - Passed:** If the contents of the files with the ``.out`` extension
|
||||
are identical to their correspondingly-named files with the extension ``.gold``,
|
||||
the command will report that the tests passed successfully, e.g.
|
||||
|
||||
If you don't want to run the whole testsuite you can write the path to the subdirectory
|
||||
in which you are interested. For example:
|
||||
```
|
||||
$ cabal test testsuite/compiler
|
||||
Running 1 test suites...
|
||||
Test suite gf-tests: RUNNING...
|
||||
Test suite gf-tests: PASS
|
||||
1 of 1 test suites (1 of 1 test cases) passed.
|
||||
```
|
||||
will run only the testsuite for the compiler.
|
||||
|
||||
**Test Outcome - Failed:** If there is a contents mismatch between the files
|
||||
with the ``.out`` extension and their corresponding files with the extension ``.gold``,
|
||||
the test diagnostics will show a fail and the areas that failed. e.g.
|
||||
|
||||
```
|
||||
testsuite/compiler/compute/Records.gfs: OK
|
||||
testsuite/compiler/compute/Variants.gfs: FAIL
|
||||
testsuite/compiler/params/params.gfs: OK
|
||||
Test suite gf-tests: FAIL
|
||||
0 of 1 test suites (0 of 1 test cases) passed.
|
||||
```
|
||||
|
||||
The fail results overview is available in gf-tests.html which shows 4 columns:
|
||||
|
||||
+ __Results__ - only areas that fail will appear. (Note: There are 3 failures in the gf-tests.html which are labelled as (expected). These failures should be ignored.)
|
||||
+ __Input__ - which is the test written in the .gfs file
|
||||
+ __Gold__ - the expected output from running the test set out in the .gfs file. This column refers to the contents from the .gold extension files.
|
||||
+ __Output__ - This column refers to the contents from the .out extension files which are generated as test output.
|
||||
After fixing the areas which fail, rerun the test command. Repeat the entire process of fix-and-test until the test suite passes before submitting a pull request to include your changes.
|
||||
|
||||
@@ -15,6 +15,12 @@ instructions inside.
|
||||
==Atom==
|
||||
[language-gf https://atom.io/packages/language-gf], by John J. Camilleri
|
||||
|
||||
==Visual Studio Code==
|
||||
|
||||
[Grammatical Framework Language Server https://marketplace.visualstudio.com/items?itemName=anka-213.gf-vscode] by Andreas Källberg.
|
||||
|
||||
This provides syntax highlighting and a client for the Grammatical Framework language server. Follow the installation instructions in the link.
|
||||
|
||||
==Eclipse==
|
||||
|
||||
[GF Eclipse Plugin https://github.com/GrammaticalFramework/gf-eclipse-plugin/], by John J. Camilleri
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
---
|
||||
title: Grammatical Framework Download and Installation
|
||||
...
|
||||
date: 25 July 2021
|
||||
---
|
||||
|
||||
**GF 3.11** was released on ... December 2020.
|
||||
**GF 3.11** was released on 25 July 2021.
|
||||
|
||||
What's new? See the [release notes](release-3.11.html).
|
||||
|
||||
@@ -24,22 +25,25 @@ Binary packages are available for Debian/Ubuntu, macOS, and Windows and include:
|
||||
|
||||
Unlike in previous versions, the binaries **do not** include the RGL.
|
||||
|
||||
[Binary packages on GitHub](https://github.com/GrammaticalFramework/gf-core/releases/tag/RELEASE-3.11)
|
||||
[Binary packages on GitHub](https://github.com/GrammaticalFramework/gf-core/releases/tag/3.11)
|
||||
|
||||
#### Debian/Ubuntu
|
||||
|
||||
There are two versions: `gf-3.11-ubuntu-18.04.deb` for Ubuntu 18.04 (Cosmic), and `gf-3.11-ubuntu-20.04.deb` for Ubuntu 20.04 (Focal).
|
||||
|
||||
To install the package use:
|
||||
|
||||
```
|
||||
sudo dpkg -i gf_3.11.deb
|
||||
sudo apt-get install ./gf-3.11-ubuntu-*.deb
|
||||
```
|
||||
|
||||
The Ubuntu `.deb` packages should work on Ubuntu 16.04, 18.04 and similar Linux distributions.
|
||||
<!-- The Ubuntu `.deb` packages should work on Ubuntu 16.04, 18.04 and similar Linux distributions. -->
|
||||
|
||||
#### macOS
|
||||
|
||||
To install the package, just double-click it and follow the installer instructions.
|
||||
|
||||
The packages should work on at least 10.13 (High Sierra) and 10.14 (Mojave).
|
||||
The packages should work on at least Catalina and Big Sur.
|
||||
|
||||
#### Windows
|
||||
|
||||
@@ -49,7 +53,7 @@ You will probably need to update the `PATH` environment variable to include your
|
||||
|
||||
For more information, see [Using GF on Windows](https://www.grammaticalframework.org/~inari/gf-windows.html) (latest updated for Windows 10).
|
||||
|
||||
## Installing the latest Hackage release (macOS, Linux, and WSL2 on Windows)
|
||||
<!--## Installing the latest Hackage release (macOS, Linux, and WSL2 on Windows)
|
||||
|
||||
[GF is on Hackage](http://hackage.haskell.org/package/gf), so under
|
||||
normal circumstances the procedure is fairly simple:
|
||||
@@ -89,7 +93,7 @@ Here is one way to do this:
|
||||
**GHC version**
|
||||
|
||||
The GF source code has been updated to compile with GHC versions 7.10 through to 8.8.
|
||||
|
||||
-->
|
||||
## Installing from the latest developer source code
|
||||
|
||||
If you haven't already, clone the repository with:
|
||||
@@ -116,7 +120,7 @@ or, if you're a Stack user:
|
||||
stack install
|
||||
```
|
||||
|
||||
The above notes for installing from source apply also in these cases.
|
||||
<!--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).
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL=/download/index-3.10.html" />
|
||||
<meta http-equiv="refresh" content="0; URL=/download/index-3.11.html" />
|
||||
</head>
|
||||
<body>
|
||||
You are being redirected to <a href="index-3.10.html">the current version</a> of this page.
|
||||
You are being redirected to <a href="index-3.11.html">the current version</a> of this page.
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: GF 3.11 Release Notes
|
||||
date: ... December 2020
|
||||
...
|
||||
date: 25 July 2021
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -12,24 +12,27 @@ See the [download page](index-3.11.html).
|
||||
From this release, the binary GF core packages do not contain the RGL.
|
||||
The RGL's release cycle is now completely separate from GF's. See [RGL releases](https://github.com/GrammaticalFramework/gf-rgl/releases).
|
||||
|
||||
Over 400 changes have been pushed to GF core
|
||||
Over 500 changes have been pushed to GF core
|
||||
since the release of GF 3.10 in December 2018.
|
||||
|
||||
## General
|
||||
|
||||
- Make the test suite work again.
|
||||
- Compatibility with new versions of GHC, including multiple Stack files for the different versions.
|
||||
- Updates to build scripts and CI.
|
||||
- Bug fixes.
|
||||
- Support for newer version of Ubuntu 20.04 in the precompiled binaries.
|
||||
- Updates to build scripts and CI workflows.
|
||||
- Bug fixes and code cleanup.
|
||||
|
||||
## GF compiler and run-time library
|
||||
|
||||
- Huge improvements in time & space requirements for grammar compilation (pending [#87](https://github.com/GrammaticalFramework/gf-core/pull/87)).
|
||||
- Add CoNLL output to `visualize_tree` shell command.
|
||||
- Add canonical GF as output format in the compiler.
|
||||
- Add PGF JSON as output format in the compiler.
|
||||
- Deprecate JavaScript runtime in favour of updated [TypeScript runtime](https://github.com/GrammaticalFramework/gf-typescript).
|
||||
- Improvements in time & space requirements when compiling certain grammars.
|
||||
- Improvements to Haskell export.
|
||||
- Improvements to the GF shell.
|
||||
- Improvements to canonical GF compilation.
|
||||
- Improvements to the C runtime.
|
||||
- Improvements to `gf -server` mode.
|
||||
- Clearer compiler error messages.
|
||||
|
||||
567
gf.cabal
567
gf.cabal
@@ -1,17 +1,16 @@
|
||||
name: gf
|
||||
version: 3.10.4-git
|
||||
version: 3.11.0-git
|
||||
|
||||
cabal-version: >= 1.22
|
||||
cabal-version: 1.22
|
||||
build-type: Custom
|
||||
license: OtherLicense
|
||||
license-file: LICENSE
|
||||
category: Natural Language Processing, Compiler
|
||||
synopsis: Grammatical Framework
|
||||
description: GF, Grammatical Framework, is a programming language for multilingual grammar applications
|
||||
homepage: http://www.grammaticalframework.org/
|
||||
homepage: https://www.grammaticalframework.org/
|
||||
bug-reports: https://github.com/GrammaticalFramework/gf-core/issues
|
||||
maintainer: Thomas Hallgren
|
||||
tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.3
|
||||
tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.10.4
|
||||
|
||||
data-dir: src
|
||||
extra-source-files: WebSetup.hs
|
||||
@@ -42,11 +41,11 @@ data-files:
|
||||
|
||||
custom-setup
|
||||
setup-depends:
|
||||
base,
|
||||
Cabal >=1.22.0.0,
|
||||
directory,
|
||||
filepath,
|
||||
process >=1.0.1.1
|
||||
base >= 4.9.1 && < 4.15,
|
||||
Cabal >= 1.22.0.0,
|
||||
directory >= 1.3.0 && < 1.4,
|
||||
filepath >= 1.4.1 && < 1.5,
|
||||
process >= 1.0.1.1 && < 1.7
|
||||
|
||||
source-repository head
|
||||
type: git
|
||||
@@ -74,20 +73,28 @@ flag c-runtime
|
||||
|
||||
library
|
||||
default-language: Haskell2010
|
||||
build-depends: base >= 4.6 && <5,
|
||||
array,
|
||||
containers,
|
||||
bytestring,
|
||||
utf8-string,
|
||||
random,
|
||||
pretty,
|
||||
mtl,
|
||||
exceptions,
|
||||
fail,
|
||||
-- For compatability with ghc < 8
|
||||
build-depends:
|
||||
-- GHC 8.0.2 to GHC 8.10.4
|
||||
array >= 0.5.1 && < 0.6,
|
||||
base >= 4.9.1 && < 4.15,
|
||||
bytestring >= 0.10.8 && < 0.11,
|
||||
containers >= 0.5.7 && < 0.7,
|
||||
exceptions >= 0.8.3 && < 0.11,
|
||||
ghc-prim >= 0.5.0 && < 0.7,
|
||||
hashable >= 1.2.6 && < 1.4,
|
||||
mtl >= 2.2.1 && < 2.3,
|
||||
pretty >= 1.1.3 && < 1.2,
|
||||
random >= 1.1 && < 1.3,
|
||||
text >= 1.2.2 && < 1.3,
|
||||
unordered-containers >= 0.2.8 && < 0.3,
|
||||
utf8-string >= 1.0.1.1 && < 1.1,
|
||||
-- We need transformers-compat >= 0.6.3, but that is only in newer snapshots where it is redundant.
|
||||
transformers-compat,
|
||||
ghc-prim
|
||||
transformers-compat >= 0.5.1.4 && < 0.7
|
||||
|
||||
if impl(ghc<8.0)
|
||||
build-depends:
|
||||
fail >= 4.9.0 && < 4.10
|
||||
|
||||
hs-source-dirs: src/runtime/haskell
|
||||
|
||||
other-modules:
|
||||
@@ -105,11 +112,13 @@ library
|
||||
ghc-prof-options: -fprof-auto
|
||||
|
||||
exposed-modules:
|
||||
LPGF
|
||||
PGF
|
||||
PGF.Internal
|
||||
PGF.Haskell
|
||||
|
||||
other-modules:
|
||||
LPGF.Internal
|
||||
PGF.Data
|
||||
PGF.Macros
|
||||
PGF.Binary
|
||||
@@ -136,8 +145,12 @@ library
|
||||
|
||||
if flag(c-runtime)
|
||||
exposed-modules: PGF2
|
||||
other-modules: PGF2.FFI PGF2.Expr PGF2.Type
|
||||
GF.Interactive2 GF.Command.Commands2
|
||||
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
|
||||
@@ -146,8 +159,14 @@ library
|
||||
|
||||
---- GF compiler as a library:
|
||||
|
||||
build-depends: filepath, directory>=1.2, time,
|
||||
process, haskeline, parallel>=3, json
|
||||
build-depends:
|
||||
directory >= 1.3.0 && < 1.4,
|
||||
filepath >= 1.4.1 && < 1.5,
|
||||
haskeline >= 0.7.3 && < 0.9,
|
||||
json >= 0.9.1 && < 0.11,
|
||||
parallel >= 3.2.1.1 && < 3.3,
|
||||
process >= 1.4.3 && < 1.7,
|
||||
time >= 1.6.0 && < 1.10
|
||||
|
||||
hs-source-dirs: src/compiler
|
||||
exposed-modules:
|
||||
@@ -158,12 +177,19 @@ library
|
||||
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
|
||||
GF.Grammar
|
||||
|
||||
GF.Data.Operations GF.Infra.Option GF.Infra.UseIO
|
||||
GF.Data.Operations
|
||||
GF.Infra.Option
|
||||
GF.Infra.UseIO
|
||||
|
||||
GF.Command.Abstract
|
||||
GF.Command.CommandInfo
|
||||
@@ -185,6 +211,7 @@ library
|
||||
GF.Compile.Export
|
||||
GF.Compile.GenerateBC
|
||||
GF.Compile.GeneratePMCFG
|
||||
GF.Compile.GrammarToLPGF
|
||||
GF.Compile.GrammarToPGF
|
||||
GF.Compile.Multi
|
||||
GF.Compile.Optimize
|
||||
@@ -213,6 +240,7 @@ library
|
||||
GF.Data.ErrM
|
||||
GF.Data.Graph
|
||||
GF.Data.Graphviz
|
||||
GF.Data.IntMapBuilder
|
||||
GF.Data.Relation
|
||||
GF.Data.Str
|
||||
GF.Data.Utilities
|
||||
@@ -273,12 +301,17 @@ library
|
||||
cpp-options: -DC_RUNTIME
|
||||
|
||||
if flag(server)
|
||||
build-depends: httpd-shed>=0.4.0.3, network>=2.3 && <2.7,
|
||||
cgi>=3001.2.2.0
|
||||
build-depends:
|
||||
cgi >= 3001.3.0.2 && < 3001.6,
|
||||
httpd-shed >= 0.4.0 && < 0.5,
|
||||
network>=2.3 && <2.7
|
||||
if flag(network-uri)
|
||||
build-depends: network-uri>=2.6, network>=2.6
|
||||
build-depends:
|
||||
network-uri >= 2.6.1.0 && < 2.7,
|
||||
network>=2.6 && <2.7
|
||||
else
|
||||
build-depends: network<2.6
|
||||
build-depends:
|
||||
network >= 2.5 && <2.6
|
||||
|
||||
cpp-options: -DSERVER_MODE
|
||||
other-modules:
|
||||
@@ -295,7 +328,10 @@ library
|
||||
Fold
|
||||
ExampleDemo
|
||||
ExampleService
|
||||
hs-source-dirs: src/server src/server/transfer src/example-based
|
||||
hs-source-dirs:
|
||||
src/server
|
||||
src/server/transfer
|
||||
src/example-based
|
||||
|
||||
if flag(interrupt)
|
||||
cpp-options: -DUSE_INTERRUPT
|
||||
@@ -304,17 +340,24 @@ library
|
||||
other-modules: GF.System.NoSignal
|
||||
|
||||
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
|
||||
build-tools: happy, alex>=3
|
||||
build-tools:
|
||||
happy,
|
||||
alex>=3
|
||||
|
||||
ghc-options: -fno-warn-tabs
|
||||
|
||||
if os(windows)
|
||||
build-depends: Win32
|
||||
build-depends:
|
||||
Win32 >= 2.3.1.1 && < 2.7
|
||||
else
|
||||
build-depends: unix, terminfo>=0.4
|
||||
build-depends:
|
||||
terminfo >=0.4.0 && < 0.5,
|
||||
unix >= 2.7.2 && < 2.8
|
||||
|
||||
if impl(ghc>=8.2)
|
||||
ghc-options: -fhide-source-paths
|
||||
@@ -323,7 +366,9 @@ executable gf
|
||||
hs-source-dirs: src/programs
|
||||
main-is: gf-main.hs
|
||||
default-language: Haskell2010
|
||||
build-depends: gf, base
|
||||
build-depends:
|
||||
gf,
|
||||
base
|
||||
ghc-options: -threaded
|
||||
--ghc-options: -fwarn-unused-imports
|
||||
|
||||
@@ -337,20 +382,442 @@ executable gf
|
||||
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
|
||||
-- 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
|
||||
type: exitcode-stdio-1.0
|
||||
main-is: run.hs
|
||||
hs-source-dirs: testsuite
|
||||
build-depends: base>=4.3 && <5, Cabal>=1.8, directory, filepath, process
|
||||
build-depends:
|
||||
base >= 4.9.1 && < 4.15,
|
||||
Cabal >= 1.8,
|
||||
directory >= 1.3.0 && < 1.4,
|
||||
filepath >= 1.4.1 && < 1.5,
|
||||
process >= 1.4.3 && < 1.7
|
||||
build-tool-depends: gf:gf
|
||||
default-language: Haskell2010
|
||||
|
||||
test-suite lpgf
|
||||
type: exitcode-stdio-1.0
|
||||
main-is: test.hs
|
||||
hs-source-dirs:
|
||||
src/compiler
|
||||
src/runtime/haskell
|
||||
testsuite/lpgf
|
||||
other-modules:
|
||||
Data.Binary
|
||||
Data.Binary.Builder
|
||||
Data.Binary.Get
|
||||
Data.Binary.IEEE754
|
||||
Data.Binary.Put
|
||||
GF
|
||||
GF.Command.Abstract
|
||||
GF.Command.CommandInfo
|
||||
GF.Command.Commands
|
||||
GF.Command.CommonCommands
|
||||
GF.Command.Help
|
||||
GF.Command.Importing
|
||||
GF.Command.Interpreter
|
||||
GF.Command.Messages
|
||||
GF.Command.Parse
|
||||
GF.Command.SourceCommands
|
||||
GF.Command.TreeOperations
|
||||
GF.Compile
|
||||
GF.Compile.CFGtoPGF
|
||||
GF.Compile.CheckGrammar
|
||||
GF.Compile.Compute.Concrete
|
||||
GF.Compile.Compute.Predef
|
||||
GF.Compile.Compute.Value
|
||||
GF.Compile.ConcreteToHaskell
|
||||
GF.Compile.ExampleBased
|
||||
GF.Compile.Export
|
||||
GF.Compile.GenerateBC
|
||||
GF.Compile.GeneratePMCFG
|
||||
GF.Compile.GetGrammar
|
||||
GF.Compile.GrammarToCanonical
|
||||
GF.Compile.GrammarToLPGF
|
||||
GF.Compile.GrammarToPGF
|
||||
GF.Compile.Multi
|
||||
GF.Compile.Optimize
|
||||
GF.Compile.PGFtoHaskell
|
||||
GF.Compile.PGFtoJava
|
||||
GF.Compile.PGFtoJS
|
||||
GF.Compile.PGFtoJSON
|
||||
GF.Compile.PGFtoProlog
|
||||
GF.Compile.PGFtoPython
|
||||
GF.Compile.ReadFiles
|
||||
GF.Compile.Rename
|
||||
GF.Compile.SubExOpt
|
||||
GF.Compile.Tags
|
||||
GF.Compile.ToAPI
|
||||
GF.Compile.TypeCheck.Abstract
|
||||
GF.Compile.TypeCheck.Concrete
|
||||
GF.Compile.TypeCheck.ConcreteNew
|
||||
GF.Compile.TypeCheck.Primitives
|
||||
GF.Compile.TypeCheck.TC
|
||||
GF.Compile.Update
|
||||
GF.CompileInParallel
|
||||
GF.CompileOne
|
||||
GF.Compiler
|
||||
GF.Data.BacktrackM
|
||||
GF.Data.ErrM
|
||||
GF.Data.Graph
|
||||
GF.Data.Graphviz
|
||||
GF.Data.IntMapBuilder
|
||||
GF.Data.Operations
|
||||
GF.Data.Relation
|
||||
GF.Data.Str
|
||||
GF.Data.Utilities
|
||||
GF.Data.XML
|
||||
GF.Grammar
|
||||
GF.Grammar.Analyse
|
||||
GF.Grammar.Binary
|
||||
GF.Grammar.BNFC
|
||||
GF.Grammar.Canonical
|
||||
GF.Grammar.CanonicalJSON
|
||||
GF.Grammar.CFG
|
||||
GF.Grammar.EBNF
|
||||
GF.Grammar.Grammar
|
||||
GF.Grammar.Lexer
|
||||
GF.Grammar.Lockfield
|
||||
GF.Grammar.Lookup
|
||||
GF.Grammar.Macros
|
||||
GF.Grammar.Parser
|
||||
GF.Grammar.PatternMatch
|
||||
GF.Grammar.Predef
|
||||
GF.Grammar.Printer
|
||||
GF.Grammar.ShowTerm
|
||||
GF.Grammar.Unify
|
||||
GF.Grammar.Values
|
||||
GF.Haskell
|
||||
GF.Infra.BuildInfo
|
||||
GF.Infra.CheckM
|
||||
GF.Infra.Concurrency
|
||||
GF.Infra.Dependencies
|
||||
GF.Infra.GetOpt
|
||||
GF.Infra.Ident
|
||||
GF.Infra.Location
|
||||
GF.Infra.Option
|
||||
GF.Infra.SIO
|
||||
GF.Infra.UseIO
|
||||
GF.Interactive
|
||||
GF.JavaScript.AbsJS
|
||||
GF.JavaScript.PrintJS
|
||||
GF.Main
|
||||
GF.Quiz
|
||||
GF.Speech.CFGToFA
|
||||
GF.Speech.FiniteState
|
||||
GF.Speech.GSL
|
||||
GF.Speech.JSGF
|
||||
GF.Speech.PGFToCFG
|
||||
GF.Speech.PrRegExp
|
||||
GF.Speech.RegExp
|
||||
GF.Speech.SISR
|
||||
GF.Speech.SLF
|
||||
GF.Speech.SRG
|
||||
GF.Speech.SRGS_ABNF
|
||||
GF.Speech.SRGS_XML
|
||||
GF.Speech.VoiceXML
|
||||
GF.Support
|
||||
GF.System.Catch
|
||||
GF.System.Concurrency
|
||||
GF.System.Console
|
||||
GF.System.Directory
|
||||
GF.System.Process
|
||||
GF.System.Signal
|
||||
GF.Text.Clitics
|
||||
GF.Text.Coding
|
||||
GF.Text.Lexing
|
||||
GF.Text.Pretty
|
||||
GF.Text.Transliterations
|
||||
LPGF
|
||||
LPGF.Internal
|
||||
PGF
|
||||
PGF.Binary
|
||||
PGF.ByteCode
|
||||
PGF.CId
|
||||
PGF.Data
|
||||
PGF.Expr
|
||||
PGF.Forest
|
||||
PGF.Generate
|
||||
PGF.Internal
|
||||
PGF.Linearize
|
||||
PGF.Macros
|
||||
PGF.Morphology
|
||||
PGF.OldBinary
|
||||
PGF.Optimize
|
||||
PGF.Paraphrase
|
||||
PGF.Parse
|
||||
PGF.Printer
|
||||
PGF.Probabilistic
|
||||
PGF.Tree
|
||||
PGF.TrieMap
|
||||
PGF.Type
|
||||
PGF.TypeCheck
|
||||
PGF.Utilities
|
||||
PGF.VisualizeTree
|
||||
Paths_gf
|
||||
if flag(interrupt)
|
||||
cpp-options: -DUSE_INTERRUPT
|
||||
other-modules: GF.System.UseSignal
|
||||
else
|
||||
other-modules: GF.System.NoSignal
|
||||
build-depends:
|
||||
ansi-terminal >= 0.6.3 && < 0.12,
|
||||
array >= 0.5.1 && < 0.6,
|
||||
base >=4.6 && < 5,
|
||||
bytestring >= 0.10.8 && < 0.11,
|
||||
containers >= 0.5.7 && < 0.7,
|
||||
directory >= 1.3.0 && < 1.4,
|
||||
filepath >= 1.4.1 && < 1.5,
|
||||
ghc-prim >= 0.5.0 && < 0.7,
|
||||
hashable >= 1.2.6 && < 1.4,
|
||||
haskeline >= 0.7.3 && < 0.9,
|
||||
json >= 0.9.1 && < 0.11,
|
||||
mtl >= 2.2.1 && < 2.3,
|
||||
parallel >= 3.2.1.1 && < 3.3,
|
||||
pretty >= 1.1.3 && < 1.2,
|
||||
process >= 1.4.3 && < 1.7,
|
||||
random >= 1.1 && < 1.3,
|
||||
text >= 1.2.2 && < 1.3,
|
||||
time >= 1.6.0 && < 1.10,
|
||||
transformers-compat >= 0.5.1.4 && < 0.7,
|
||||
unordered-containers >= 0.2.8 && < 0.3,
|
||||
utf8-string >= 1.0.1.1 && < 1.1
|
||||
|
||||
if impl(ghc<8.0)
|
||||
build-depends:
|
||||
fail >= 4.9.0 && < 4.10
|
||||
|
||||
if os(windows)
|
||||
build-depends:
|
||||
Win32 >= 2.3.1.1 && < 2.7
|
||||
else
|
||||
build-depends:
|
||||
unix >= 2.7.2 && < 2.8,
|
||||
terminfo >=0.4.0 && < 0.5
|
||||
|
||||
default-language: Haskell2010
|
||||
|
||||
benchmark lpgf-bench
|
||||
type: exitcode-stdio-1.0
|
||||
main-is: bench.hs
|
||||
hs-source-dirs:
|
||||
src/compiler
|
||||
src/runtime/haskell
|
||||
testsuite/lpgf
|
||||
other-modules:
|
||||
Data.Binary
|
||||
Data.Binary.Builder
|
||||
Data.Binary.Get
|
||||
Data.Binary.IEEE754
|
||||
Data.Binary.Put
|
||||
GF
|
||||
GF.Command.Abstract
|
||||
GF.Command.CommandInfo
|
||||
GF.Command.Commands
|
||||
GF.Command.CommonCommands
|
||||
GF.Command.Help
|
||||
GF.Command.Importing
|
||||
GF.Command.Interpreter
|
||||
GF.Command.Messages
|
||||
GF.Command.Parse
|
||||
GF.Command.SourceCommands
|
||||
GF.Command.TreeOperations
|
||||
GF.Compile
|
||||
GF.Compile.CFGtoPGF
|
||||
GF.Compile.CheckGrammar
|
||||
GF.Compile.Compute.Concrete
|
||||
GF.Compile.Compute.Predef
|
||||
GF.Compile.Compute.Value
|
||||
GF.Compile.ConcreteToHaskell
|
||||
GF.Compile.ExampleBased
|
||||
GF.Compile.Export
|
||||
GF.Compile.GenerateBC
|
||||
GF.Compile.GeneratePMCFG
|
||||
GF.Compile.GetGrammar
|
||||
GF.Compile.GrammarToCanonical
|
||||
GF.Compile.GrammarToLPGF
|
||||
GF.Compile.GrammarToPGF
|
||||
GF.Compile.Multi
|
||||
GF.Compile.Optimize
|
||||
GF.Compile.PGFtoHaskell
|
||||
GF.Compile.PGFtoJS
|
||||
GF.Compile.PGFtoJSON
|
||||
GF.Compile.PGFtoJava
|
||||
GF.Compile.PGFtoProlog
|
||||
GF.Compile.PGFtoPython
|
||||
GF.Compile.ReadFiles
|
||||
GF.Compile.Rename
|
||||
GF.Compile.SubExOpt
|
||||
GF.Compile.Tags
|
||||
GF.Compile.ToAPI
|
||||
GF.Compile.TypeCheck.Abstract
|
||||
GF.Compile.TypeCheck.Concrete
|
||||
GF.Compile.TypeCheck.ConcreteNew
|
||||
GF.Compile.TypeCheck.Primitives
|
||||
GF.Compile.TypeCheck.TC
|
||||
GF.Compile.Update
|
||||
GF.CompileInParallel
|
||||
GF.CompileOne
|
||||
GF.Compiler
|
||||
GF.Data.BacktrackM
|
||||
GF.Data.ErrM
|
||||
GF.Data.Graph
|
||||
GF.Data.Graphviz
|
||||
GF.Data.IntMapBuilder
|
||||
GF.Data.Operations
|
||||
GF.Data.Relation
|
||||
GF.Data.Str
|
||||
GF.Data.Utilities
|
||||
GF.Data.XML
|
||||
GF.Grammar
|
||||
GF.Grammar.Analyse
|
||||
GF.Grammar.BNFC
|
||||
GF.Grammar.Binary
|
||||
GF.Grammar.CFG
|
||||
GF.Grammar.Canonical
|
||||
GF.Grammar.CanonicalJSON
|
||||
GF.Grammar.EBNF
|
||||
GF.Grammar.Grammar
|
||||
GF.Grammar.Lexer
|
||||
GF.Grammar.Lockfield
|
||||
GF.Grammar.Lookup
|
||||
GF.Grammar.Macros
|
||||
GF.Grammar.Parser
|
||||
GF.Grammar.PatternMatch
|
||||
GF.Grammar.Predef
|
||||
GF.Grammar.Printer
|
||||
GF.Grammar.ShowTerm
|
||||
GF.Grammar.Unify
|
||||
GF.Grammar.Values
|
||||
GF.Haskell
|
||||
GF.Infra.BuildInfo
|
||||
GF.Infra.CheckM
|
||||
GF.Infra.Concurrency
|
||||
GF.Infra.Dependencies
|
||||
GF.Infra.GetOpt
|
||||
GF.Infra.Ident
|
||||
GF.Infra.Location
|
||||
GF.Infra.Option
|
||||
GF.Infra.SIO
|
||||
GF.Infra.UseIO
|
||||
GF.Interactive
|
||||
GF.JavaScript.AbsJS
|
||||
GF.JavaScript.PrintJS
|
||||
GF.Main
|
||||
GF.Quiz
|
||||
GF.Speech.CFGToFA
|
||||
GF.Speech.FiniteState
|
||||
GF.Speech.GSL
|
||||
GF.Speech.JSGF
|
||||
GF.Speech.PGFToCFG
|
||||
GF.Speech.PrRegExp
|
||||
GF.Speech.RegExp
|
||||
GF.Speech.SISR
|
||||
GF.Speech.SLF
|
||||
GF.Speech.SRG
|
||||
GF.Speech.SRGS_ABNF
|
||||
GF.Speech.SRGS_XML
|
||||
GF.Speech.VoiceXML
|
||||
GF.Support
|
||||
GF.System.Catch
|
||||
GF.System.Concurrency
|
||||
GF.System.Console
|
||||
GF.System.Directory
|
||||
GF.System.Process
|
||||
GF.System.Signal
|
||||
GF.Text.Clitics
|
||||
GF.Text.Coding
|
||||
GF.Text.Lexing
|
||||
GF.Text.Pretty
|
||||
GF.Text.Transliterations
|
||||
LPGF
|
||||
LPGF.Internal
|
||||
PGF
|
||||
PGF.Binary
|
||||
PGF.ByteCode
|
||||
PGF.CId
|
||||
PGF.Data
|
||||
PGF.Expr
|
||||
PGF.Expr
|
||||
PGF.Forest
|
||||
PGF.Generate
|
||||
PGF.Internal
|
||||
PGF.Linearize
|
||||
PGF.Macros
|
||||
PGF.Morphology
|
||||
PGF.OldBinary
|
||||
PGF.Optimize
|
||||
PGF.Paraphrase
|
||||
PGF.Parse
|
||||
PGF.Printer
|
||||
PGF.Probabilistic
|
||||
PGF.Tree
|
||||
PGF.TrieMap
|
||||
PGF.Type
|
||||
PGF.TypeCheck
|
||||
PGF.Utilities
|
||||
PGF.VisualizeTree
|
||||
PGF2
|
||||
PGF2.Expr
|
||||
PGF2.Type
|
||||
PGF2.FFI
|
||||
Paths_gf
|
||||
if flag(interrupt)
|
||||
cpp-options: -DUSE_INTERRUPT
|
||||
other-modules: GF.System.UseSignal
|
||||
else
|
||||
other-modules: GF.System.NoSignal
|
||||
|
||||
hs-source-dirs:
|
||||
src/runtime/haskell-bind
|
||||
other-modules:
|
||||
PGF2
|
||||
PGF2.FFI
|
||||
PGF2.Expr
|
||||
PGF2.Type
|
||||
build-tools: hsc2hs
|
||||
extra-libraries: pgf gu
|
||||
c-sources: src/runtime/haskell-bind/utils.c
|
||||
cc-options: -std=c99
|
||||
|
||||
build-depends:
|
||||
ansi-terminal,
|
||||
array,
|
||||
base>=4.6 && <5,
|
||||
bytestring,
|
||||
containers,
|
||||
deepseq,
|
||||
directory,
|
||||
filepath,
|
||||
ghc-prim,
|
||||
hashable,
|
||||
haskeline,
|
||||
json,
|
||||
mtl,
|
||||
parallel>=3,
|
||||
pretty,
|
||||
process,
|
||||
random,
|
||||
terminfo,
|
||||
text,
|
||||
time,
|
||||
transformers-compat,
|
||||
unix,
|
||||
unordered-containers,
|
||||
utf8-string
|
||||
default-language: Haskell2010
|
||||
|
||||
14
index.html
14
index.html
@@ -214,9 +214,9 @@ least one, it may help you to get a first idea of what GF is.
|
||||
</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>.
|
||||
We run the IRC channel <strong><code>#gf</code></strong> on the Libera network, where you are welcome to look for help with small questions or just start a general discussion.
|
||||
You can <a href="https://web.libera.chat/?channels=#gf">open a web chat</a>
|
||||
or <a href="https://www.grammaticalframework.org/irc/?C=M;O=D">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>.
|
||||
@@ -226,7 +226,11 @@ least one, it may help you to get a first idea of what GF is.
|
||||
|
||||
<div class="col-md-6">
|
||||
<h2>News</h2>
|
||||
|
||||
<dt class="col-sm-3 text-center text-nowrap">2021-07-25</dt>
|
||||
<dd class="col-sm-9">
|
||||
<strong>GF 3.11 released.</strong>
|
||||
<a href="download/release-3.11.html">Release notes</a>
|
||||
</dd>
|
||||
<dl class="row">
|
||||
<dt class="col-sm-3 text-center text-nowrap">2021-05-05</dt>
|
||||
<dd class="col-sm-9">
|
||||
@@ -234,7 +238,7 @@ least one, it may help you to get a first idea of what GF is.
|
||||
</dd>
|
||||
<dt class="col-sm-3 text-center text-nowrap">2021-03-01</dt>
|
||||
<dd class="col-sm-9">
|
||||
<a href="//school.grammaticalframework.org/2020/">Seventh GF Summer School</a>, in Singapore and online, 26 July – 8 August 2021.
|
||||
<a href="//school.grammaticalframework.org/2020/">Seventh GF Summer School</a>, in Singapore and online, 26 July – 6 August 2021.
|
||||
</dd>
|
||||
<dt class="col-sm-3 text-center text-nowrap">2020-09-29</dt>
|
||||
<dd class="col-sm-9">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
module GF.Compile (compileToPGF, link, batchCompile, srcAbsName) where
|
||||
module GF.Compile (compileToPGF, compileToLPGF, link, linkl, batchCompile, srcAbsName) where
|
||||
|
||||
import GF.Compile.GrammarToPGF(mkCanon2pgf)
|
||||
import GF.Compile.GrammarToLPGF(mkCanon2lpgf)
|
||||
import GF.Compile.ReadFiles(ModEnv,getOptionsFromFile,getAllFiles,
|
||||
importsOfModule)
|
||||
import GF.CompileOne(compileOne)
|
||||
@@ -14,7 +15,7 @@ import GF.Infra.UseIO(IOE,FullPath,liftIO,getLibraryDirectory,putIfVerb,
|
||||
justModuleName,extendPathEnv,putStrE,putPointE)
|
||||
import GF.Data.Operations(raise,(+++),err)
|
||||
|
||||
import Control.Monad(foldM,when,(<=<),filterM,liftM)
|
||||
import Control.Monad(foldM,when,(<=<),filterM)
|
||||
import GF.System.Directory(doesFileExist,getModificationTime)
|
||||
import System.FilePath((</>),isRelative,dropFileName)
|
||||
import qualified Data.Map as Map(empty,insert,elems) --lookup
|
||||
@@ -24,12 +25,16 @@ import GF.Text.Pretty(render,($$),(<+>),nest)
|
||||
|
||||
import PGF.Internal(optimizePGF)
|
||||
import PGF(PGF,defaultProbabilities,setProbabilities,readProbabilitiesFromFile)
|
||||
import LPGF(LPGF)
|
||||
|
||||
-- | Compiles a number of source files and builds a 'PGF' structure for them.
|
||||
-- This is a composition of 'link' and 'batchCompile'.
|
||||
compileToPGF :: Options -> [FilePath] -> IOE PGF
|
||||
compileToPGF opts fs = link opts . snd =<< batchCompile opts fs
|
||||
|
||||
compileToLPGF :: Options -> [FilePath] -> IOE LPGF
|
||||
compileToLPGF opts fs = linkl opts . snd =<< batchCompile opts fs
|
||||
|
||||
-- | Link a grammar into a 'PGF' that can be used to 'PGF.linearize' and
|
||||
-- 'PGF.parse' with the "PGF" run-time system.
|
||||
link :: Options -> (ModuleName,Grammar) -> IOE PGF
|
||||
@@ -42,6 +47,14 @@ link opts (cnc,gr) =
|
||||
return $ setProbabilities probs
|
||||
$ if flag optOptimizePGF opts then optimizePGF pgf else pgf
|
||||
|
||||
-- | Link a grammar into a 'LPGF' that can be used for linearization only.
|
||||
linkl :: Options -> (ModuleName,Grammar) -> IOE LPGF
|
||||
linkl opts (cnc,gr) =
|
||||
putPointE Normal opts "linking ... " $ do
|
||||
let abs = srcAbsName gr cnc
|
||||
lpgf <- mkCanon2lpgf opts gr abs
|
||||
return lpgf
|
||||
|
||||
-- | Returns the name of the abstract syntax corresponding to the named concrete syntax
|
||||
srcAbsName gr cnc = err (const cnc) id $ abstractOfConcrete gr cnc
|
||||
|
||||
|
||||
@@ -30,11 +30,12 @@ import Debug.Trace(trace)
|
||||
normalForm :: GlobalEnv -> L Ident -> Term -> Term
|
||||
normalForm (GE gr rv opts _) loc = err (bugloc loc) id . nfx (GE gr rv opts loc)
|
||||
|
||||
nfx :: GlobalEnv -> Term -> Err Term
|
||||
nfx env@(GE _ _ _ loc) t = do
|
||||
v <- eval env [] t
|
||||
case value2term loc [] v of
|
||||
Left i -> fail ("variable #"++show i++" is out of scope")
|
||||
Right t -> return t
|
||||
return (value2term loc [] v)
|
||||
-- Old value2term error message:
|
||||
-- Left i -> fail ("variable #"++show i++" is out of scope")
|
||||
|
||||
eval :: GlobalEnv -> Env -> Term -> Err Value
|
||||
eval (GE gr rvs opts loc) env t = ($ (map snd env)) # value cenv t
|
||||
@@ -288,9 +289,9 @@ glue env (v1,v2) = glu v1 v2
|
||||
(v1,v2) -> if flag optPlusAsBind (opts env)
|
||||
then VC v1 (VC (VApp BIND []) v2)
|
||||
else let loc = gloc env
|
||||
vt v = case value2term loc (local env) v of
|
||||
Left i -> Error ('#':show i)
|
||||
Right t -> t
|
||||
vt v = value2term loc (local env) v
|
||||
-- Old value2term error message:
|
||||
-- Left i -> Error ('#':show i)
|
||||
originalMsg = render $ ppL loc (hang "unsupported token gluing" 4
|
||||
(Glue (vt v1) (vt v2)))
|
||||
term = render $ pp $ Glue (vt v1) (vt v2)
|
||||
@@ -355,9 +356,9 @@ select env vv =
|
||||
(v1,v2) -> ok2 VS v1 v2
|
||||
|
||||
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)
|
||||
err bad return (matchPattern cs (value2term loc [] v))
|
||||
-- Old value2term error message:
|
||||
-- Left i -> bad ("variable #"++show i++" is out of scope")
|
||||
where
|
||||
bad = fail . ("In pattern matching: "++)
|
||||
|
||||
@@ -383,9 +384,8 @@ valueTable env i cs =
|
||||
wild = case i of TWild _ -> True; _ -> False
|
||||
|
||||
convertv cs' vty =
|
||||
case value2term (gloc env) [] vty of
|
||||
Left i -> fail ("variable #"++show i++" is out of scope")
|
||||
Right pty -> convert' cs' =<< paramValues'' env pty
|
||||
convert' cs' =<< paramValues'' env (value2term (gloc env) [] vty)
|
||||
-- Old value2term error message: Left i -> fail ("variable #"++show i++" is out of scope")
|
||||
|
||||
convert cs' ty = convert' cs' =<< paramValues' env ty
|
||||
|
||||
@@ -492,58 +492,60 @@ vtrace loc arg res = trace (render (hang (pv arg) 4 ("->"<+>pv res))) res
|
||||
pf (_,VString n) = pp n
|
||||
pf (_,v) = ppV v
|
||||
pa (_,v) = ppV v
|
||||
ppV v = case value2term' True loc [] v of
|
||||
Left i -> "variable #" <> pp i <+> "is out of scope"
|
||||
Right t -> ppTerm Unqualified 10 t
|
||||
ppV v = ppTerm Unqualified 10 (value2term' True loc [] v)
|
||||
-- Old value2term error message:
|
||||
-- Left i -> "variable #" <> pp i <+> "is out of scope"
|
||||
|
||||
-- | Convert a value back to a term
|
||||
value2term :: GLocation -> [Ident] -> Value -> Either Int Term
|
||||
value2term :: GLocation -> [Ident] -> Value -> Term
|
||||
value2term = value2term' False
|
||||
|
||||
value2term' :: Bool -> p -> [Ident] -> Value -> Term
|
||||
value2term' stop loc xs v0 =
|
||||
case v0 of
|
||||
VApp pre vs -> liftM (foldl App (Q (cPredef,predefName pre))) (mapM v2t vs)
|
||||
VCApp f vs -> liftM (foldl App (QC f)) (mapM v2t vs)
|
||||
VGen j vs -> liftM2 (foldl App) (var j) (mapM v2t vs)
|
||||
VMeta j env vs -> liftM (foldl App (Meta j)) (mapM v2t vs)
|
||||
VProd bt v x f -> liftM2 (Prod bt x) (v2t v) (v2t' x f)
|
||||
VAbs bt x f -> liftM (Abs bt x) (v2t' x f)
|
||||
VInt n -> return (EInt n)
|
||||
VFloat f -> return (EFloat f)
|
||||
VString s -> return (if null s then Empty else K s)
|
||||
VSort s -> return (Sort s)
|
||||
VImplArg v -> liftM ImplArg (v2t v)
|
||||
VTblType p res -> liftM2 Table (v2t p) (v2t res)
|
||||
VRecType rs -> liftM RecType (mapM (\(l,v) -> fmap ((,) l) (v2t v)) rs)
|
||||
VRec as -> liftM R (mapM (\(l,v) -> v2t v >>= \t -> return (l,(Nothing,t))) as)
|
||||
VV t _ vs -> liftM (V t) (mapM v2t vs)
|
||||
VT wild v cs -> v2t v >>= \t -> liftM (T ((if wild then TWild else TTyped) t)) (mapM nfcase cs)
|
||||
VFV vs -> liftM FV (mapM v2t vs)
|
||||
VC v1 v2 -> liftM2 C (v2t v1) (v2t v2)
|
||||
VS v1 v2 -> liftM2 S (v2t v1) (v2t v2)
|
||||
VP v l -> v2t v >>= \t -> return (P t l)
|
||||
VPatt p -> return (EPatt p)
|
||||
VPattType v -> v2t v >>= return . EPattType
|
||||
VAlts v vvs -> liftM2 Alts (v2t v) (mapM (\(x,y) -> liftM2 (,) (v2t x) (v2t y)) vvs)
|
||||
VStrs vs -> liftM Strs (mapM v2t vs)
|
||||
VApp pre vs -> applyMany (Q (cPredef,predefName pre)) vs
|
||||
VCApp f vs -> applyMany (QC f) vs
|
||||
VGen j vs -> applyMany (var j) vs
|
||||
VMeta j env vs -> applyMany (Meta j) vs
|
||||
VProd bt v x f -> Prod bt x (v2t v) (v2t' x f)
|
||||
VAbs bt x f -> Abs bt x (v2t' x f)
|
||||
VInt n -> EInt n
|
||||
VFloat f -> EFloat f
|
||||
VString s -> if null s then Empty else K s
|
||||
VSort s -> Sort s
|
||||
VImplArg v -> ImplArg (v2t v)
|
||||
VTblType p res -> Table (v2t p) (v2t res)
|
||||
VRecType rs -> RecType [(l, v2t v) | (l,v) <- rs]
|
||||
VRec as -> R [(l, (Nothing, v2t v)) | (l,v) <- as]
|
||||
VV t _ vs -> V t (map v2t vs)
|
||||
VT wild v cs -> T ((if wild then TWild else TTyped) (v2t v)) (map nfcase cs)
|
||||
VFV vs -> FV (map v2t vs)
|
||||
VC v1 v2 -> C (v2t v1) (v2t v2)
|
||||
VS v1 v2 -> S (v2t v1) (v2t v2)
|
||||
VP v l -> P (v2t v) l
|
||||
VPatt p -> EPatt p
|
||||
VPattType v -> EPattType $ v2t v
|
||||
VAlts v vvs -> Alts (v2t v) [(v2t x, v2t y) | (x,y) <- vvs]
|
||||
VStrs vs -> Strs (map v2t vs)
|
||||
-- VGlue v1 v2 -> Glue (v2t v1) (v2t v2)
|
||||
-- VExtR v1 v2 -> ExtR (v2t v1) (v2t v2)
|
||||
VError err -> return (Error err)
|
||||
|
||||
VError err -> Error err
|
||||
where
|
||||
applyMany f vs = foldl App f (map v2t vs)
|
||||
v2t = v2txs xs
|
||||
v2txs = value2term' stop loc
|
||||
v2t' x f = v2txs (x:xs) (bind f (gen xs))
|
||||
|
||||
var j
|
||||
| j<length xs = Right (Vr (reverse xs !! j))
|
||||
| otherwise = Left j
|
||||
| j<length xs = Vr (reverse xs !! j)
|
||||
| otherwise = error ("variable #"++show j++" is out of scope")
|
||||
|
||||
|
||||
pushs xs e = foldr push e xs
|
||||
push x (env,xs) = ((x,gen xs):env,x:xs)
|
||||
gen xs = VGen (length xs) []
|
||||
|
||||
nfcase (p,f) = liftM ((,) p) (v2txs xs' (bind f env'))
|
||||
nfcase (p,f) = (,) p (v2txs xs' (bind f env'))
|
||||
where (env',xs') = pushs (pattVars p) ([],xs)
|
||||
|
||||
bind (Bind f) x = if stop
|
||||
|
||||
@@ -27,6 +27,10 @@ instance Predef Int where
|
||||
|
||||
instance Predef Bool where
|
||||
toValue = boolV
|
||||
fromValue v = case v of
|
||||
VCApp (mn,i) [] | mn == cPredef && i == cPTrue -> return True
|
||||
VCApp (mn,i) [] | mn == cPredef && i == cPFalse -> return False
|
||||
_ -> verror "Bool" v
|
||||
|
||||
instance Predef String where
|
||||
toValue = string
|
||||
|
||||
429
src/compiler/GF/Compile/GrammarToLPGF.hs
Normal file
429
src/compiler/GF/Compile/GrammarToLPGF.hs
Normal file
@@ -0,0 +1,429 @@
|
||||
module GF.Compile.GrammarToLPGF (mkCanon2lpgf) where
|
||||
|
||||
import LPGF.Internal (LPGF (..))
|
||||
import qualified LPGF.Internal as L
|
||||
|
||||
import PGF.CId
|
||||
import GF.Grammar.Grammar
|
||||
import qualified GF.Grammar.Canonical as C
|
||||
import GF.Compile.GrammarToCanonical (grammar2canonical)
|
||||
|
||||
import GF.Data.Operations (ErrorMonad (..))
|
||||
import qualified GF.Data.IntMapBuilder as IntMapBuilder
|
||||
import GF.Infra.Ident (rawIdentS, showRawIdent)
|
||||
import GF.Infra.Option (Options)
|
||||
import GF.Infra.UseIO (IOE)
|
||||
import GF.Text.Pretty (pp, render)
|
||||
|
||||
import Control.Applicative ((<|>))
|
||||
import Control.Monad (when, unless, forM, forM_)
|
||||
import qualified Control.Monad.State.Strict as CMS
|
||||
import Data.Either (lefts, rights)
|
||||
import Data.List (elemIndex)
|
||||
import qualified Data.List as L
|
||||
import qualified Data.Map.Strict as Map
|
||||
import Data.Maybe (fromJust, isJust)
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text as T
|
||||
import System.Environment (lookupEnv)
|
||||
import System.FilePath ((</>), (<.>))
|
||||
import Text.Printf (printf)
|
||||
|
||||
import qualified Debug.Trace
|
||||
trace x = Debug.Trace.trace ("> " ++ show x) (return ())
|
||||
|
||||
mkCanon2lpgf :: Options -> SourceGrammar -> ModuleName -> IOE LPGF
|
||||
mkCanon2lpgf opts gr am = do
|
||||
debug <- isJust <$> lookupEnv "DEBUG"
|
||||
when debug $ do
|
||||
ppCanonical debugDir canon
|
||||
dumpCanonical debugDir canon
|
||||
(an,abs) <- mkAbstract ab
|
||||
cncs <- mapM (mkConcrete debug ab) cncs
|
||||
let lpgf = LPGF {
|
||||
L.absname = an,
|
||||
L.abstract = abs,
|
||||
L.concretes = Map.fromList cncs
|
||||
}
|
||||
when debug $ ppLPGF debugDir lpgf
|
||||
return lpgf
|
||||
where
|
||||
canon@(C.Grammar ab cncs) = grammar2canonical opts am gr
|
||||
|
||||
mkAbstract :: (ErrorMonad err) => C.Abstract -> err (CId, L.Abstract)
|
||||
mkAbstract (C.Abstract modId flags cats funs) = return (mdi2i modId, L.Abstract {})
|
||||
|
||||
mkConcrete :: (ErrorMonad err) => Bool -> C.Abstract -> C.Concrete -> err (CId, L.Concrete)
|
||||
mkConcrete debug (C.Abstract _ _ _ funs) (C.Concrete modId absModId flags params0 lincats0 lindefs0) = do
|
||||
let
|
||||
-- Some transformations on canonical grammar
|
||||
|
||||
params :: [C.ParamDef]
|
||||
params = inlineParamAliases params0
|
||||
|
||||
lincats :: [C.LincatDef]
|
||||
lincats = s:i:f:lincats0
|
||||
where
|
||||
ss = C.RecordType [C.RecordRow (C.LabelId (rawIdentS "s")) C.StrType]
|
||||
s = C.LincatDef (C.CatId (rawIdentS "String")) ss
|
||||
i = C.LincatDef (C.CatId (rawIdentS "Int")) ss
|
||||
f = C.LincatDef (C.CatId (rawIdentS "Float")) ss
|
||||
|
||||
lindefs :: [C.LinDef]
|
||||
lindefs =
|
||||
[ C.LinDef funId varIds linValue
|
||||
| (C.LinDef funId varIds linValue) <- lindefs0
|
||||
, let Right linType = lookupLinType funId
|
||||
]
|
||||
|
||||
-- Builds maps for lookups
|
||||
|
||||
paramValueMap :: Map.Map C.ParamId C.ParamDef -- constructor -> definition
|
||||
paramValueMap = Map.fromList [ (v,d) | d@(C.ParamDef _ vs) <- params, (C.Param v _) <- vs ]
|
||||
|
||||
lincatMap :: Map.Map C.CatId C.LincatDef
|
||||
lincatMap = Map.fromList [ (cid,d) | d@(C.LincatDef cid _) <- lincats ]
|
||||
|
||||
funMap :: Map.Map C.FunId C.FunDef
|
||||
funMap = Map.fromList [ (fid,d) | d@(C.FunDef fid _) <- funs ]
|
||||
|
||||
-- | Lookup paramdef
|
||||
lookupParamDef :: C.ParamId -> Either String C.ParamDef
|
||||
lookupParamDef pid = m2e (printf "Cannot find param definition: %s" (show pid)) (Map.lookup pid paramValueMap)
|
||||
|
||||
-- | Lookup lintype for a function
|
||||
lookupLinType :: C.FunId -> Either String C.LinType
|
||||
lookupLinType funId = do
|
||||
fun <- m2e (printf "Cannot find type for: %s" (show funId)) (Map.lookup funId funMap)
|
||||
let (C.FunDef _ (C.Type _ (C.TypeApp catId _))) = fun
|
||||
lincat <- m2e (printf "Cannot find lincat for: %s" (show catId)) (Map.lookup catId lincatMap)
|
||||
let (C.LincatDef _ lt) = lincat
|
||||
return lt
|
||||
|
||||
-- | Lookup lintype for a function's argument
|
||||
lookupLinTypeArg :: C.FunId -> Int -> Either String C.LinType
|
||||
lookupLinTypeArg funId argIx = do
|
||||
fun <- m2e (printf "Cannot find type for: %s" (show funId)) (Map.lookup funId funMap)
|
||||
let (C.FunDef _ (C.Type args _)) = fun
|
||||
let (C.TypeBinding _ (C.Type _ (C.TypeApp catId _))) = args !! argIx
|
||||
lincat <- m2e (printf "Cannot find lincat for: %s" (show catId)) (Map.lookup catId lincatMap)
|
||||
let (C.LincatDef _ lt) = lincat
|
||||
return lt
|
||||
|
||||
-- Code generation
|
||||
|
||||
-- | Main code generation function
|
||||
mkLin :: C.LinDef -> CodeGen (CId, L.LinFun)
|
||||
mkLin (C.LinDef funId varIds linValue) = do
|
||||
-- when debug $ trace funId
|
||||
(lf, _) <- val2lin linValue
|
||||
return (fi2i funId, lf)
|
||||
where
|
||||
val2lin :: C.LinValue -> CodeGen (L.LinFun, Maybe C.LinType)
|
||||
val2lin lv = case lv of
|
||||
|
||||
C.ConcatValue v1 v2 -> do
|
||||
(v1',t1) <- val2lin v1
|
||||
(v2',t2) <- val2lin v2
|
||||
return (L.Concat v1' v2', t1 <|> t2) -- t1 else t2
|
||||
|
||||
C.LiteralValue ll -> case ll of
|
||||
C.FloatConstant f -> return (L.Token $ T.pack $ show f, Just C.FloatType)
|
||||
C.IntConstant i -> return (L.Token $ T.pack $ show i, Just C.IntType)
|
||||
C.StrConstant s -> return (L.Token $ T.pack s, Just C.StrType)
|
||||
|
||||
C.ErrorValue err -> return (L.Error err, Nothing)
|
||||
|
||||
C.ParamConstant (C.Param pid lvs) -> do
|
||||
let
|
||||
collectProjections :: C.LinValue -> CodeGen [L.LinFun]
|
||||
collectProjections (C.ParamConstant (C.Param pid lvs)) = do
|
||||
def <- lookupParamDef pid
|
||||
let (C.ParamDef tpid defpids) = def
|
||||
pidIx <- eitherElemIndex pid [ p | C.Param p _ <- defpids ]
|
||||
rest <- mapM collectProjections lvs
|
||||
return $ L.Ix (pidIx+1) : concat rest
|
||||
collectProjections lv = do
|
||||
(lf,_) <- val2lin lv
|
||||
return [lf]
|
||||
lfs <- collectProjections lv
|
||||
let term = L.Tuple lfs
|
||||
def <- lookupParamDef pid
|
||||
let (C.ParamDef tpid _) = def
|
||||
return (term, Just $ C.ParamType (C.ParamTypeId tpid))
|
||||
|
||||
C.PredefValue (C.PredefId pid) -> case showRawIdent pid of
|
||||
"BIND" -> return (L.Bind, Nothing)
|
||||
"SOFT_BIND" -> return (L.Bind, Nothing)
|
||||
"SOFT_SPACE" -> return (L.Space, Nothing)
|
||||
"CAPIT" -> return (L.Capit, Nothing)
|
||||
"ALL_CAPIT" -> return (L.AllCapit, Nothing)
|
||||
x -> Left $ printf "Unknown predef function: %s" x
|
||||
|
||||
C.RecordValue rrvs -> do
|
||||
ts <- sequence [ val2lin lv | C.RecordRow lid lv <- rrvs ]
|
||||
return (L.Tuple (map fst ts), Just $ C.RecordType [ C.RecordRow lid lt | (C.RecordRow lid _, (_, Just lt)) <- zip rrvs ts])
|
||||
|
||||
C.TableValue lt trvs -> do
|
||||
-- group the rows by "left-most" value
|
||||
let
|
||||
groupRow :: C.TableRowValue -> C.TableRowValue -> Bool
|
||||
groupRow (C.TableRow p1 _) (C.TableRow p2 _) = groupPattern p1 p2
|
||||
|
||||
groupPattern :: C.LinPattern -> C.LinPattern -> Bool
|
||||
groupPattern p1 p2 = case (p1,p2) of
|
||||
(C.ParamPattern (C.Param pid1 _), C.ParamPattern (C.Param pid2 _)) -> pid1 == pid2 -- compare only constructors
|
||||
(C.RecordPattern (C.RecordRow lid1 patt1:_), C.RecordPattern (C.RecordRow lid2 patt2:_)) -> groupPattern patt1 patt2 -- lid1 == lid2 necessarily
|
||||
_ -> error $ printf "Mismatched patterns in grouping:\n%s\n%s" (show p1) (show p2)
|
||||
|
||||
grps :: [[C.TableRowValue]]
|
||||
grps = L.groupBy groupRow trvs
|
||||
|
||||
-- remove one level of depth and recurse
|
||||
let
|
||||
handleGroup :: [C.TableRowValue] -> CodeGen (L.LinFun, Maybe C.LinType)
|
||||
handleGroup [C.TableRow patt lv] =
|
||||
case reducePattern patt of
|
||||
Just patt' -> do
|
||||
(lf,lt) <- handleGroup [C.TableRow patt' lv]
|
||||
return (L.Tuple [lf],lt)
|
||||
Nothing -> val2lin lv
|
||||
handleGroup rows = do
|
||||
let rows' = map reduceRow rows
|
||||
val2lin (C.TableValue lt rows') -- lt is wrong here, but is unused
|
||||
|
||||
reducePattern :: C.LinPattern -> Maybe C.LinPattern
|
||||
reducePattern patt =
|
||||
case patt of
|
||||
C.ParamPattern (C.Param _ []) -> Nothing
|
||||
C.ParamPattern (C.Param _ patts) -> Just $ C.ParamPattern (C.Param pid' patts')
|
||||
where
|
||||
C.ParamPattern (C.Param pid1 patts1) = head patts
|
||||
pid' = pid1
|
||||
patts' = patts1 ++ tail patts
|
||||
|
||||
C.RecordPattern [] -> Nothing
|
||||
C.RecordPattern (C.RecordRow lid patt:rrs) ->
|
||||
case reducePattern patt of
|
||||
Just patt' -> Just $ C.RecordPattern (C.RecordRow lid patt':rrs)
|
||||
Nothing -> if null rrs then Nothing else Just $ C.RecordPattern rrs
|
||||
|
||||
_ -> error $ printf "Unhandled pattern in reducing: %s" (show patt)
|
||||
|
||||
reduceRow :: C.TableRowValue -> C.TableRowValue
|
||||
reduceRow (C.TableRow patt lv) =
|
||||
let Just patt' = reducePattern patt
|
||||
in C.TableRow patt' lv
|
||||
|
||||
-- ts :: [(L.LinFun, Maybe C.LinType)]
|
||||
ts <- mapM handleGroup grps
|
||||
|
||||
-- return
|
||||
let typ = case ts of
|
||||
(_, Just tst):_ -> Just $ C.TableType lt tst
|
||||
_ -> Nothing
|
||||
return (L.Tuple (map fst ts), typ)
|
||||
|
||||
-- TODO TuplePattern, WildPattern?
|
||||
|
||||
C.TupleValue lvs -> do
|
||||
ts <- mapM val2lin lvs
|
||||
return (L.Tuple (map fst ts), Just $ C.TupleType (map (fromJust.snd) ts))
|
||||
|
||||
C.VariantValue [] -> return (L.Empty, Nothing) -- TODO Just C.StrType ?
|
||||
C.VariantValue (vr:_) -> val2lin vr -- NOTE variants not supported, just pick first
|
||||
|
||||
C.VarValue (C.VarValueId (C.Unqual v)) -> do
|
||||
ix <- eitherElemIndex (C.VarId v) varIds
|
||||
lt <- lookupLinTypeArg funId ix
|
||||
return (L.Argument (ix+1), Just lt)
|
||||
|
||||
C.PreValue pts df -> do
|
||||
pts' <- forM pts $ \(pfxs, lv) -> do
|
||||
(lv', _) <- val2lin lv
|
||||
return (map T.pack pfxs, lv')
|
||||
(df', lt) <- val2lin df
|
||||
return (L.Pre pts' df', lt)
|
||||
|
||||
C.Projection v1 lblId -> do
|
||||
(v1', mtyp) <- val2lin v1
|
||||
-- find label index in argument type
|
||||
let Just (C.RecordType rrs) = mtyp
|
||||
let rrs' = [ lid | C.RecordRow lid _ <- rrs ]
|
||||
-- lblIx <- eitherElemIndex lblId rrs'
|
||||
let
|
||||
lblIx = case eitherElemIndex lblId rrs' of
|
||||
Right x -> x
|
||||
Left _ -> 0 -- corresponds to Prelude.False
|
||||
-- lookup lintype for record row
|
||||
let C.RecordRow _ lt = rrs !! lblIx
|
||||
return (L.Projection v1' (L.Ix (lblIx+1)), Just lt)
|
||||
|
||||
C.Selection v1 v2 -> do
|
||||
(v1', t1) <- val2lin v1
|
||||
(v2', t2) <- val2lin v2
|
||||
let Just (C.TableType t11 t12) = t1 -- t11 == t2
|
||||
return (L.Projection v1' v2', Just t12)
|
||||
|
||||
-- C.CommentedValue cmnt lv -> val2lin lv
|
||||
C.CommentedValue cmnt lv -> case cmnt of
|
||||
"impossible" -> return (L.Empty, Nothing)
|
||||
-- "impossible" -> val2lin lv >>= \(_, typ) -> return (L.Empty, typ)
|
||||
_ -> val2lin lv
|
||||
|
||||
v -> Left $ printf "val2lin not implemented for: %s" (show v)
|
||||
|
||||
-- Invoke code generation
|
||||
|
||||
let es = map mkLin lindefs
|
||||
unless (null $ lefts es) (raise $ unlines (lefts es))
|
||||
|
||||
let maybeOptimise = if debug then id else extractStrings
|
||||
let concr = maybeOptimise $ L.Concrete {
|
||||
L.toks = IntMapBuilder.emptyIntMap,
|
||||
L.lins = Map.fromList (rights es)
|
||||
}
|
||||
return (mdi2i modId, concr)
|
||||
|
||||
type CodeGen a = Either String a
|
||||
|
||||
-- | Remove ParamAliasDefs by inlining their definitions
|
||||
inlineParamAliases :: [C.ParamDef] -> [C.ParamDef]
|
||||
inlineParamAliases defs = if null aliases then defs else map rp' pdefs
|
||||
where
|
||||
(aliases,pdefs) = L.partition isParamAliasDef defs
|
||||
|
||||
rp' :: C.ParamDef -> C.ParamDef
|
||||
rp' (C.ParamDef pid pids) = C.ParamDef pid (map rp'' pids)
|
||||
rp' (C.ParamAliasDef _ _) = error "inlineParamAliases called on ParamAliasDef" -- impossible
|
||||
|
||||
rp'' :: C.ParamValueDef -> C.ParamValueDef
|
||||
rp'' (C.Param pid pids) = C.Param pid (map rp''' pids)
|
||||
|
||||
rp''' :: C.ParamId -> C.ParamId
|
||||
rp''' pid = case L.find (\(C.ParamAliasDef p _) -> p == pid) aliases of
|
||||
Just (C.ParamAliasDef _ (C.ParamType (C.ParamTypeId p))) -> p
|
||||
_ -> pid
|
||||
|
||||
isParamAliasDef :: C.ParamDef -> Bool
|
||||
isParamAliasDef (C.ParamAliasDef _ _) = True
|
||||
isParamAliasDef _ = False
|
||||
|
||||
isParamType :: C.LinType -> Bool
|
||||
isParamType (C.ParamType _) = True
|
||||
isParamType _ = False
|
||||
|
||||
isRecordType :: C.LinType -> Bool
|
||||
isRecordType (C.RecordType _) = True
|
||||
isRecordType _ = False
|
||||
|
||||
-- | Find all token strings, put them in a map and replace with token indexes
|
||||
extractStrings :: L.Concrete -> L.Concrete
|
||||
extractStrings concr = L.Concrete { L.toks = toks', L.lins = lins' }
|
||||
where
|
||||
imb = IntMapBuilder.fromIntMap (L.toks concr)
|
||||
(lins',imb') = CMS.runState (go0 (L.lins concr)) imb
|
||||
toks' = IntMapBuilder.toIntMap imb'
|
||||
|
||||
go0 :: Map.Map CId L.LinFun -> CMS.State (IntMapBuilder.IMB Text) (Map.Map CId L.LinFun)
|
||||
go0 mp = do
|
||||
xs <- mapM (\(cid,lin) -> go lin >>= \lin' -> return (cid,lin')) (Map.toList mp)
|
||||
return $ Map.fromList xs
|
||||
|
||||
go :: L.LinFun -> CMS.State (IntMapBuilder.IMB Text) L.LinFun
|
||||
go lf = case lf of
|
||||
L.Token str -> do
|
||||
imb <- CMS.get
|
||||
let (ix,imb') = IntMapBuilder.insert' str imb
|
||||
CMS.put imb'
|
||||
return $ L.TokenIx ix
|
||||
|
||||
L.Pre pts df -> do
|
||||
-- pts' <- mapM (\(pfxs,lv) -> go lv >>= \lv' -> return (pfxs,lv')) pts
|
||||
pts' <- forM pts $ \(pfxs,lv) -> do
|
||||
imb <- CMS.get
|
||||
let str = T.pack $ show pfxs
|
||||
let (ix,imb') = IntMapBuilder.insert' str imb
|
||||
CMS.put imb'
|
||||
lv' <- go lv
|
||||
return (ix,lv')
|
||||
df' <- go df
|
||||
return $ L.PreIx pts' df'
|
||||
L.Concat s t -> do
|
||||
s' <- go s
|
||||
t' <- go t
|
||||
return $ L.Concat s' t'
|
||||
L.Tuple ts -> do
|
||||
ts' <- mapM go ts
|
||||
return $ L.Tuple ts'
|
||||
L.Projection t u -> do
|
||||
t' <- go t
|
||||
u' <- go u
|
||||
return $ L.Projection t' u'
|
||||
t -> return t
|
||||
|
||||
-- | Convert Maybe to Either value with error
|
||||
m2e :: String -> Maybe a -> Either String a
|
||||
m2e err = maybe (Left err) Right
|
||||
|
||||
-- | Wrap elemIndex into Either value
|
||||
eitherElemIndex :: (Eq a, Show a) => a -> [a] -> Either String Int
|
||||
eitherElemIndex x xs = m2e (printf "Cannot find: %s in %s" (show x) (show xs)) (elemIndex x xs)
|
||||
|
||||
mdi2s :: C.ModId -> String
|
||||
mdi2s (C.ModId i) = showRawIdent i
|
||||
|
||||
mdi2i :: C.ModId -> CId
|
||||
mdi2i (C.ModId i) = mkCId (showRawIdent i)
|
||||
|
||||
fi2i :: C.FunId -> CId
|
||||
fi2i (C.FunId i) = mkCId (showRawIdent i)
|
||||
|
||||
-- Debugging
|
||||
|
||||
debugDir :: FilePath
|
||||
debugDir = "DEBUG"
|
||||
|
||||
-- | Pretty-print canonical grammars to file
|
||||
ppCanonical :: FilePath -> C.Grammar -> IO ()
|
||||
ppCanonical path (C.Grammar ab cncs) = do
|
||||
let (C.Abstract modId flags cats funs) = ab
|
||||
writeFile (path </> mdi2s modId <.> "canonical.gf") (render $ pp ab)
|
||||
forM_ cncs $ \cnc@(C.Concrete modId absModId flags params lincats lindefs) ->
|
||||
writeFile' (path </> mdi2s modId <.> "canonical.gf") (render $ pp cnc)
|
||||
|
||||
-- | Dump canonical grammars to file
|
||||
dumpCanonical :: FilePath -> C.Grammar -> IO ()
|
||||
dumpCanonical path (C.Grammar ab cncs) = do
|
||||
let (C.Abstract modId flags cats funs) = ab
|
||||
let body = unlines $ map show cats ++ [""] ++ map show funs
|
||||
writeFile' (path </> mdi2s modId <.> "canonical.dump") body
|
||||
|
||||
forM_ cncs $ \(C.Concrete modId absModId flags params lincats lindefs) -> do
|
||||
let body = unlines $ concat [
|
||||
map show params,
|
||||
[""],
|
||||
map show lincats,
|
||||
[""],
|
||||
map show lindefs
|
||||
]
|
||||
writeFile' (path </> mdi2s modId <.> "canonical.dump") body
|
||||
|
||||
-- | Pretty-print LPGF to file
|
||||
ppLPGF :: FilePath -> LPGF -> IO ()
|
||||
ppLPGF path lpgf =
|
||||
forM_ (Map.toList $ L.concretes lpgf) $ \(cid,concr) ->
|
||||
writeFile' (path </> showCId cid <.> "lpgf.txt") (L.render $ L.pp concr)
|
||||
|
||||
-- | Dump LPGF to file
|
||||
dumpLPGF :: FilePath -> LPGF -> IO ()
|
||||
dumpLPGF path lpgf =
|
||||
forM_ (Map.toList $ L.concretes lpgf) $ \(cid,concr) -> do
|
||||
let body = unlines $ map show (Map.toList $ L.lins concr)
|
||||
writeFile' (path </> showCId cid <.> "lpgf.dump") body
|
||||
|
||||
-- | Write a file and report it to console
|
||||
writeFile' :: FilePath -> String -> IO ()
|
||||
writeFile' p b = do
|
||||
writeFile p b
|
||||
putStrLn $ "Wrote " ++ p
|
||||
@@ -69,7 +69,6 @@ computeLType gr g0 t = comp (reverse [(b,x, Vr x) | (b,x,_) <- g0] ++ g0) t
|
||||
lockRecType c t' ---- locking to be removed AR 20/6/2009
|
||||
|
||||
_ | ty == typeTok -> return typeStr
|
||||
_ | isPredefConstant ty -> return ty
|
||||
|
||||
_ -> composOp (comp g) ty
|
||||
|
||||
|
||||
@@ -568,9 +568,9 @@ unifyVar ge scope i env vs ty2 = do -- Check whether i is bound
|
||||
Bound ty1 -> do v <- liftErr (eval ge env ty1)
|
||||
unify ge scope (vapply (geLoc ge) v vs) ty2
|
||||
Unbound scope' _ -> case value2term (geLoc ge) (scopeVars scope') ty2 of
|
||||
Left i -> let (v,_) = reverse scope !! i
|
||||
in tcError ("Variable" <+> pp v <+> "has escaped")
|
||||
Right ty2' -> do ms2 <- getMetaVars (geLoc ge) [(scope,ty2)]
|
||||
-- Left i -> let (v,_) = reverse scope !! i
|
||||
-- in tcError ("Variable" <+> pp v <+> "has escaped")
|
||||
ty2' -> do ms2 <- getMetaVars (geLoc ge) [(scope,ty2)]
|
||||
if i `elem` ms2
|
||||
then tcError ("Occurs check for" <+> ppMeta i <+> "in:" $$
|
||||
nest 2 (ppTerm Unqualified 0 ty2'))
|
||||
@@ -765,9 +765,9 @@ zonkTerm (Meta i) = do
|
||||
zonkTerm t = composOp zonkTerm t
|
||||
|
||||
tc_value2term loc xs v =
|
||||
case value2term loc xs v of
|
||||
Left i -> tcError ("Variable #" <+> pp i <+> "has escaped")
|
||||
Right t -> return t
|
||||
return $ value2term loc xs v
|
||||
-- Old value2term error message:
|
||||
-- Left i -> tcError ("Variable #" <+> pp i <+> "has escaped")
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
-- Thierry Coquand's type checking algorithm that creates a trace
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
module GF.Compile.TypeCheck.TC (AExp(..),
|
||||
module GF.Compile.TypeCheck.TC (
|
||||
AExp(..),
|
||||
Theory,
|
||||
checkExp,
|
||||
inferExp,
|
||||
@@ -321,4 +322,3 @@ mkAnnot :: (Val -> AExp) -> Err (Val,[(Val,Val)]) -> Err (AExp,Val,[(Val,Val)])
|
||||
mkAnnot a ti = do
|
||||
(v,cs) <- ti
|
||||
return (a v, v, cs)
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ buildAnyTree :: Fail.MonadFail m => ModuleName -> [(Ident,Info)] -> m (Map.Map I
|
||||
buildAnyTree m = go Map.empty
|
||||
where
|
||||
go map [] = return map
|
||||
go map ((c,j):is) = do
|
||||
go map ((c,j):is) =
|
||||
case Map.lookup c map of
|
||||
Just i -> case unifyAnyInfo m i j of
|
||||
Ok k -> go (Map.insert c k map) is
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
module GF.Compiler (mainGFC, linkGrammars, writePGF, writeOutputs) where
|
||||
module GF.Compiler (mainGFC, linkGrammars, writePGF, writeLPGF, writeOutputs) where
|
||||
|
||||
import PGF
|
||||
import PGF.Internal(concretes,optimizePGF,unionPGF)
|
||||
import PGF.Internal(putSplitAbs,encodeFile,runPut)
|
||||
import GF.Compile as S(batchCompile,link,srcAbsName)
|
||||
import LPGF(LPGF)
|
||||
import qualified LPGF.Internal as LPGF
|
||||
import GF.Compile as S(batchCompile,link,linkl,srcAbsName)
|
||||
import GF.CompileInParallel as P(parallelBatchCompile)
|
||||
import GF.Compile.Export
|
||||
import GF.Compile.ConcreteToHaskell(concretes2haskell)
|
||||
@@ -11,7 +13,8 @@ import GF.Compile.GrammarToCanonical--(concretes2canonical)
|
||||
import GF.Compile.CFGtoPGF
|
||||
import GF.Compile.GetGrammar
|
||||
import GF.Grammar.BNFC
|
||||
import GF.Grammar.CFG
|
||||
import GF.Grammar.CFG hiding (Grammar)
|
||||
import GF.Grammar.Grammar (Grammar, ModuleName)
|
||||
|
||||
--import GF.Infra.Ident(showIdent)
|
||||
import GF.Infra.UseIO
|
||||
@@ -23,10 +26,11 @@ import GF.Text.Pretty(render,render80)
|
||||
import Data.Maybe
|
||||
import qualified Data.Map as Map
|
||||
import qualified Data.Set as Set
|
||||
import Data.Time(UTCTime)
|
||||
import qualified Data.ByteString.Lazy as BSL
|
||||
import GF.Grammar.CanonicalJSON (encodeJSON)
|
||||
import System.FilePath
|
||||
import Control.Monad(when,unless,forM_)
|
||||
import Control.Monad(when,unless,forM,void)
|
||||
|
||||
-- | Compile the given GF grammar files. The result is a number of @.gfo@ files
|
||||
-- and, depending on the options, a @.pgf@ file. (@gf -batch@, @gf -make@)
|
||||
@@ -93,6 +97,10 @@ compileSourceFiles opts fs =
|
||||
-- If a @.pgf@ file by the same name already exists and it is newer than the
|
||||
-- source grammar files (as indicated by the 'UTCTime' argument), it is not
|
||||
-- recreated. Calls 'writePGF' and 'writeOutputs'.
|
||||
linkGrammars :: Options -> (UTCTime,[(ModuleName, Grammar)]) -> IOE ()
|
||||
linkGrammars opts (_,cnc_grs) | FmtLPGF `elem` flag optOutputFormats opts = do
|
||||
lpgf <- linkl opts (head cnc_grs)
|
||||
void $ writeLPGF opts lpgf
|
||||
linkGrammars opts (t_src,~cnc_grs@(~(cnc,gr):_)) =
|
||||
do let abs = render (srcAbsName gr cnc)
|
||||
pgfFile = outputPath opts (grammarName' opts abs<.>"pgf")
|
||||
@@ -145,7 +153,7 @@ unionPGFFiles opts fs =
|
||||
pgfFile = outputPath opts (grammarName opts pgf <.> "pgf")
|
||||
if pgfFile `elem` fs
|
||||
then putStrLnE $ "Refusing to overwrite " ++ pgfFile
|
||||
else writePGF opts pgf
|
||||
else void $ writePGF opts pgf
|
||||
writeOutputs opts pgf
|
||||
|
||||
readPGFVerbose f =
|
||||
@@ -162,26 +170,39 @@ writeOutputs opts pgf = do
|
||||
-- | Write the result of compiling a grammar (e.g. with 'compileToPGF' or
|
||||
-- 'link') to a @.pgf@ file.
|
||||
-- A split PGF file is output if the @-split-pgf@ option is used.
|
||||
writePGF :: Options -> PGF -> IOE ()
|
||||
writePGF :: Options -> PGF -> IOE [FilePath]
|
||||
writePGF opts pgf =
|
||||
if flag optSplitPGF opts then writeSplitPGF else writeNormalPGF
|
||||
where
|
||||
writeNormalPGF =
|
||||
do let outfile = outputPath opts (grammarName opts pgf <.> "pgf")
|
||||
writing opts outfile $ encodeFile outfile pgf
|
||||
return [outfile]
|
||||
|
||||
writeSplitPGF =
|
||||
do let outfile = outputPath opts (grammarName opts pgf <.> "pgf")
|
||||
writing opts outfile $ BSL.writeFile outfile (runPut (putSplitAbs pgf))
|
||||
--encodeFile_ outfile (putSplitAbs pgf)
|
||||
forM_ (Map.toList (concretes pgf)) $ \cnc -> do
|
||||
outfiles <- forM (Map.toList (concretes pgf)) $ \cnc -> do
|
||||
let outfile = outputPath opts (showCId (fst cnc) <.> "pgf_c")
|
||||
writing opts outfile $ encodeFile outfile cnc
|
||||
return outfile
|
||||
|
||||
return (outfile:outfiles)
|
||||
|
||||
writeOutput :: Options -> FilePath-> String -> IOE ()
|
||||
writeOutput opts file str = writing opts path $ writeUTF8File path str
|
||||
where path = outputPath opts file
|
||||
writeLPGF :: Options -> LPGF -> IOE FilePath
|
||||
writeLPGF opts lpgf = do
|
||||
let
|
||||
grammarName = fromMaybe (showCId (LPGF.absname lpgf)) (flag optName opts)
|
||||
outfile = outputPath opts (grammarName <.> "lpgf")
|
||||
writing opts outfile $ liftIO $ LPGF.encodeFile outfile lpgf
|
||||
return outfile
|
||||
|
||||
writeOutput :: Options -> FilePath-> String -> IOE FilePath
|
||||
writeOutput opts file str = do
|
||||
let outfile = outputPath opts file
|
||||
writing opts outfile $ writeUTF8File outfile str
|
||||
return outfile
|
||||
|
||||
-- * Useful helper functions
|
||||
|
||||
|
||||
61
src/compiler/GF/Data/IntMapBuilder.hs
Normal file
61
src/compiler/GF/Data/IntMapBuilder.hs
Normal file
@@ -0,0 +1,61 @@
|
||||
-- | In order to build an IntMap in one pass, we need a map data structure with
|
||||
-- fast lookup in both keys and values.
|
||||
-- This is achieved by keeping a separate reversed map of values to keys during building.
|
||||
module GF.Data.IntMapBuilder where
|
||||
|
||||
import Data.IntMap (IntMap)
|
||||
import qualified Data.IntMap as IntMap
|
||||
import Data.Hashable (Hashable)
|
||||
import Data.HashMap.Strict (HashMap)
|
||||
import qualified Data.HashMap.Strict as HashMap
|
||||
import Data.Tuple (swap)
|
||||
import Prelude hiding (lookup)
|
||||
|
||||
data IMB a = IMB {
|
||||
intMap :: IntMap a,
|
||||
valMap :: HashMap a Int
|
||||
}
|
||||
|
||||
-- | An empty IMB
|
||||
empty :: (Eq a, Hashable a) => IMB a
|
||||
empty = IMB {
|
||||
intMap = IntMap.empty,
|
||||
valMap = HashMap.empty
|
||||
}
|
||||
|
||||
-- | An empty IntMap
|
||||
emptyIntMap :: IntMap a
|
||||
emptyIntMap = IntMap.empty
|
||||
|
||||
-- | Lookup a value
|
||||
lookup :: (Eq a, Hashable a) => a -> IMB a -> Maybe Int
|
||||
lookup a IMB { valMap = vm } = HashMap.lookup a vm
|
||||
|
||||
-- | Insert without any lookup
|
||||
insert :: (Eq a, Hashable a) => a -> IMB a -> (Int, IMB a)
|
||||
insert a IMB { intMap = im, valMap = vm } =
|
||||
let
|
||||
ix = IntMap.size im
|
||||
im' = IntMap.insert ix a im
|
||||
vm' = HashMap.insert a ix vm
|
||||
imb' = IMB { intMap = im', valMap = vm' }
|
||||
in
|
||||
(ix, imb')
|
||||
|
||||
-- | Insert only when lookup fails
|
||||
insert' :: (Eq a, Hashable a) => a -> IMB a -> (Int, IMB a)
|
||||
insert' a imb =
|
||||
case lookup a imb of
|
||||
Just ix -> (ix, imb)
|
||||
Nothing -> insert a imb
|
||||
|
||||
-- | Build IMB from existing IntMap
|
||||
fromIntMap :: (Eq a, Hashable a) => IntMap a -> IMB a
|
||||
fromIntMap im = IMB {
|
||||
intMap = im,
|
||||
valMap = HashMap.fromList (map swap (IntMap.toList im))
|
||||
}
|
||||
|
||||
-- | Get IntMap from IMB
|
||||
toIntMap :: (Eq a, Hashable a) => IMB a -> IntMap a
|
||||
toIntMap = intMap
|
||||
@@ -31,7 +31,7 @@ data TypeApp = TypeApp CatId [Type] deriving Show
|
||||
data TypeBinding = TypeBinding VarId Type deriving Show
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- ** Concreate syntax
|
||||
-- ** Concrete syntax
|
||||
|
||||
-- | Concrete Syntax
|
||||
data Concrete = Concrete ModId ModId Flags [ParamDef] [LincatDef] [LinDef]
|
||||
@@ -105,7 +105,7 @@ data TableRow rhs = TableRow LinPattern rhs
|
||||
|
||||
newtype PredefId = PredefId Id deriving (Eq,Ord,Show)
|
||||
newtype LabelId = LabelId Id deriving (Eq,Ord,Show)
|
||||
data VarValueId = VarValueId QualId deriving (Eq,Ord,Show)
|
||||
newtype VarValueId = VarValueId QualId deriving (Eq,Ord,Show)
|
||||
|
||||
-- | Name of param type or param value
|
||||
newtype ParamId = ParamId QualId deriving (Eq,Ord,Show)
|
||||
@@ -116,9 +116,9 @@ newtype ParamId = ParamId QualId deriving (Eq,Ord,Show)
|
||||
newtype ModId = ModId Id deriving (Eq,Ord,Show)
|
||||
|
||||
newtype CatId = CatId Id deriving (Eq,Ord,Show)
|
||||
newtype FunId = FunId Id deriving (Eq,Show)
|
||||
newtype FunId = FunId Id deriving (Eq,Ord,Show)
|
||||
|
||||
data VarId = Anonymous | VarId Id deriving Show
|
||||
data VarId = Anonymous | VarId Id deriving (Eq,Show)
|
||||
|
||||
newtype Flags = Flags [(FlagName,FlagValue)] deriving Show
|
||||
type FlagName = Id
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
-- pattern matching for both concrete and abstract syntax. AR -- 16\/6\/2003
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
module GF.Grammar.PatternMatch (matchPattern,
|
||||
module GF.Grammar.PatternMatch (
|
||||
matchPattern,
|
||||
testOvershadow,
|
||||
findMatch,
|
||||
measurePatt
|
||||
|
||||
@@ -362,4 +362,3 @@ getLet :: Term -> ([LocalDef], Term)
|
||||
getLet (Let l e) = let (ls,e') = getLet e
|
||||
in (l:ls,e')
|
||||
getLet e = ([],e)
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
-- (Description of the module)
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
module GF.Grammar.Values (-- ** Values used in TC type checking
|
||||
module GF.Grammar.Values (
|
||||
-- ** Values used in TC type checking
|
||||
Val(..), Env,
|
||||
-- ** Annotated tree used in editing
|
||||
Binds, Constraints, MetaSubst,
|
||||
|
||||
@@ -87,7 +87,8 @@ data Verbosity = Quiet | Normal | Verbose | Debug
|
||||
data Phase = Preproc | Convert | Compile | Link
|
||||
deriving (Show,Eq,Ord)
|
||||
|
||||
data OutputFormat = FmtPGFPretty
|
||||
data OutputFormat = FmtLPGF
|
||||
| FmtPGFPretty
|
||||
| FmtCanonicalGF
|
||||
| FmtCanonicalJson
|
||||
| FmtJavaScript
|
||||
@@ -335,7 +336,7 @@ optDescr =
|
||||
Option ['f'] ["output-format"] (ReqArg outFmt "FMT")
|
||||
(unlines ["Output format. FMT can be one of:",
|
||||
"Canonical GF grammar: canonical_gf, canonical_json, (and haskell with option --haskell=concrete)",
|
||||
"Multiple concrete: pgf (default), json, js, pgf_pretty, prolog, python, ...", -- gar,
|
||||
"Multiple concrete: pgf (default), lpgf, json, js, pgf_pretty, prolog, python, ...", -- gar,
|
||||
"Single concrete only: bnf, ebnf, fa, gsl, jsgf, regexp, slf, srgs_xml, srgs_abnf, vxml, ....", -- cf, lbnf,
|
||||
"Abstract only: haskell, ..."]), -- prolog_abs,
|
||||
Option [] ["sisr"] (ReqArg sisrFmt "FMT")
|
||||
@@ -477,7 +478,8 @@ outputFormats = map fst outputFormatsExpl
|
||||
|
||||
outputFormatsExpl :: [((String,OutputFormat),String)]
|
||||
outputFormatsExpl =
|
||||
[(("pgf_pretty", FmtPGFPretty),"human-readable pgf"),
|
||||
[(("lpgf", FmtLPGF),"Linearisation-only PGF"),
|
||||
(("pgf_pretty", FmtPGFPretty),"Human-readable PGF"),
|
||||
(("canonical_gf", FmtCanonicalGF),"Canonical GF source files"),
|
||||
(("canonical_json", FmtCanonicalJson),"Canonical JSON source files"),
|
||||
(("js", FmtJavaScript),"JavaScript (whole grammar)"),
|
||||
|
||||
@@ -38,7 +38,6 @@ import GF.Server(server)
|
||||
#endif
|
||||
|
||||
import GF.Command.Messages(welcome)
|
||||
import GF.Infra.UseIO (Output)
|
||||
-- Provides an orphan instance of MonadFail for StateT in ghc versions < 8
|
||||
import Control.Monad.Trans.Instances ()
|
||||
|
||||
@@ -56,6 +55,7 @@ mainGFI opts files = do
|
||||
|
||||
shell opts files = flip evalStateT (emptyGFEnv opts) $
|
||||
do mapStateT runSIO $ importInEnv opts files
|
||||
modify $ \ gfenv0 -> gfenv0 {history = [unwords ("i":files)]}
|
||||
loop
|
||||
|
||||
#ifdef SERVER_MODE
|
||||
|
||||
@@ -58,6 +58,7 @@ mainGFI opts files = do
|
||||
|
||||
shell opts files = flip evalStateT (emptyGFEnv opts) $
|
||||
do mapStateT runSIO $ importInEnv opts files
|
||||
modify $ \ gfenv0 -> gfenv0 {history = [unwords ("i":files)]}
|
||||
loop
|
||||
|
||||
{-
|
||||
|
||||
@@ -16,18 +16,19 @@ import Data.Version
|
||||
import System.Directory
|
||||
import System.Environment (getArgs)
|
||||
import System.Exit
|
||||
import GF.System.Console (setConsoleEncoding)
|
||||
-- import GF.System.Console (setConsoleEncoding)
|
||||
|
||||
-- | Run the GF main program, taking arguments from the command line.
|
||||
-- (It calls 'setConsoleEncoding' and 'getOptions', then 'mainOpts'.)
|
||||
-- Run @gf --help@ for usage info.
|
||||
main :: IO ()
|
||||
main = do
|
||||
--setConsoleEncoding
|
||||
-- setConsoleEncoding
|
||||
uncurry mainOpts =<< getOptions
|
||||
|
||||
-- | Get and parse GF command line arguments. Fix relative paths.
|
||||
-- Calls 'getArgs' and 'parseOptions'.
|
||||
getOptions :: IO (Options, [FilePath])
|
||||
getOptions = do
|
||||
args <- getArgs
|
||||
case parseOptions args of
|
||||
|
||||
@@ -110,4 +110,3 @@ prepunctuate p (x:xs) = x : map (p <>) xs
|
||||
|
||||
($++$) :: Doc -> Doc -> Doc
|
||||
x $++$ y = x $$ emptyLine $$ y
|
||||
|
||||
|
||||
@@ -125,4 +125,3 @@ prepunctuate p (x:xs) = x : map (p <>) xs
|
||||
|
||||
($++$) :: Doc -> Doc -> Doc
|
||||
x $++$ y = x $$ emptyLine $$ y
|
||||
|
||||
|
||||
@@ -300,9 +300,7 @@ transAncientGreek = mkTransliteration "ancient Greek" allTrans allCodes where
|
||||
|
||||
transAmharic :: Transliteration
|
||||
transAmharic = mkTransliteration "Amharic" allTrans allCodes where
|
||||
|
||||
allTrans = words $
|
||||
|
||||
allTrans = words $
|
||||
" h. h- h' h( h) h h? h* l. l- l' l( l) l l? l* "++
|
||||
" H. H- H' H( H) H H? H* m. m- m' m( m) m m? m* "++
|
||||
" s. s- s' s( s) s s? s* r. r- r' r( r) r r? r* "++
|
||||
@@ -325,7 +323,7 @@ allTrans = words $
|
||||
" P. P- P' P( P) P P? P* S. S- S' S( S) S S? S* "++
|
||||
" - - - - - - - - f. f- f' f( f) f f? f*"++
|
||||
" p. p- p' p( p) p p? p*"
|
||||
allCodes = [0x1200..0x1357]
|
||||
allCodes = [0x1200..0x1357]
|
||||
|
||||
-- by Prasad 31/5/2013
|
||||
transSanskrit :: Transliteration
|
||||
|
||||
@@ -14,6 +14,9 @@ For Linux users
|
||||
|
||||
You will need the packages: autoconf, automake, libtool, make
|
||||
|
||||
- On Ubuntu: $ apt-get install autotools-dev
|
||||
- On Fedora: $ dnf install autoconf automake libtool
|
||||
|
||||
The compilation steps are:
|
||||
|
||||
$ autoreconf -i
|
||||
@@ -28,7 +31,7 @@ For Mac OSX users
|
||||
The following is what I did to make it work on MacOSX 10.8:
|
||||
|
||||
- Install XCode and XCode command line tools
|
||||
- Install Homebrew: http://mxcl.github.com/homebrew/
|
||||
- Install Homebrew: https://brew.sh
|
||||
|
||||
$ brew install automake autoconf libtool
|
||||
$ glibtoolize
|
||||
|
||||
3
src/runtime/c/install.sh
Executable file
3
src/runtime/c/install.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
bash setup.sh configure
|
||||
bash setup.sh build
|
||||
bash setup.sh install
|
||||
@@ -140,7 +140,9 @@ unStr (Expr expr touch) =
|
||||
touch
|
||||
return (Just s)
|
||||
|
||||
-- | Constructs an expression from an integer literal
|
||||
-- | Constructs an expression from an integer literal.
|
||||
-- Note that the C runtime does not support long integers, and you may run into overflow issues with large values.
|
||||
-- See [here](https://github.com/GrammaticalFramework/gf-core/issues/109) for more details.
|
||||
mkInt :: Int -> Expr
|
||||
mkInt val =
|
||||
unsafePerformIO $ do
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
name: pgf2
|
||||
version: 1.3.0
|
||||
|
||||
cabal-version: 1.22
|
||||
build-type: Simple
|
||||
license: LGPL-3
|
||||
license-file: LICENSE
|
||||
category: Natural Language Processing
|
||||
synopsis: Bindings to the C version of the PGF runtime
|
||||
description:
|
||||
GF, Grammatical Framework, is a programming language for multilingual grammar applications.
|
||||
GF grammars are compiled into Portable Grammar Format (PGF) which can be used with the PGF runtime, written in C.
|
||||
This package provides Haskell bindings to that runtime.
|
||||
homepage: https://www.grammaticalframework.org
|
||||
license: LGPL-3
|
||||
license-file: LICENSE
|
||||
homepage: https://www.grammaticalframework.org/
|
||||
bug-reports: https://github.com/GrammaticalFramework/gf-core/issues
|
||||
author: Krasimir Angelov
|
||||
category: Natural Language Processing
|
||||
build-type: Simple
|
||||
extra-source-files: CHANGELOG.md, README.md
|
||||
cabal-version: >=1.10
|
||||
tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.10.4
|
||||
|
||||
library
|
||||
exposed-modules:
|
||||
@@ -23,9 +26,9 @@ library
|
||||
PGF2.Expr,
|
||||
PGF2.Type
|
||||
build-depends:
|
||||
base >=4.3 && <5,
|
||||
containers,
|
||||
pretty
|
||||
base >= 4.9.1 && < 4.15,
|
||||
containers >= 0.5.7 && < 0.7,
|
||||
pretty >= 1.1.3 && < 1.2
|
||||
default-language: Haskell2010
|
||||
build-tools: hsc2hs
|
||||
extra-libraries: pgf gu
|
||||
|
||||
3
src/runtime/haskell-bind/stack-ghc7.10.3.yaml
Normal file
3
src/runtime/haskell-bind/stack-ghc7.10.3.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
resolver: lts-6.35 # ghc 7.10.3
|
||||
|
||||
allow-newer: true
|
||||
1
src/runtime/haskell-bind/stack-ghc8.0.2.yaml
Normal file
1
src/runtime/haskell-bind/stack-ghc8.0.2.yaml
Normal file
@@ -0,0 +1 @@
|
||||
resolver: lts-9.21 # ghc 8.0.2
|
||||
1
src/runtime/haskell-bind/stack-ghc8.10.4.yaml
Normal file
1
src/runtime/haskell-bind/stack-ghc8.10.4.yaml
Normal file
@@ -0,0 +1 @@
|
||||
resolver: lts-18.0 # ghc 8.10.4
|
||||
234
src/runtime/haskell/LPGF.hs
Normal file
234
src/runtime/haskell/LPGF.hs
Normal file
@@ -0,0 +1,234 @@
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
|
||||
-- | Linearisation-only portable grammar format.
|
||||
--
|
||||
-- LPGF is an output format from the GF compiler, intended as a smaller and faster alternative to PGF.
|
||||
-- This API allows LPGF files to be used in Haskell programs.
|
||||
--
|
||||
-- The implementation closely follows description in Section 2 of Angelov, Bringert, Ranta (2009):
|
||||
-- "PGF: A Portable Run-Time Format for Type-Theoretical Grammars".
|
||||
-- http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.640.6330&rep=rep1&type=pdf
|
||||
module LPGF (
|
||||
-- * LPGF
|
||||
LPGF,
|
||||
showLPGF,
|
||||
readLPGF,
|
||||
|
||||
-- * Identifiers
|
||||
CId,
|
||||
mkCId,
|
||||
showCId,
|
||||
readCId,
|
||||
|
||||
-- * Abstract syntax
|
||||
Abstract,
|
||||
abstractName,
|
||||
|
||||
-- ** Categories
|
||||
|
||||
-- ** Functions
|
||||
|
||||
-- ** Expressions
|
||||
Expr,
|
||||
PGF.showExpr,
|
||||
PGF.readExpr,
|
||||
|
||||
-- ** Types
|
||||
|
||||
-- ** Type checking
|
||||
|
||||
-- * Concrete syntax
|
||||
Language,
|
||||
PGF.showLanguage,
|
||||
PGF.readLanguage,
|
||||
languages,
|
||||
Concrete,
|
||||
LPGF.concretes,
|
||||
|
||||
-- ** Linearization
|
||||
linearize,
|
||||
linearizeText,
|
||||
linearizeConcrete,
|
||||
linearizeConcreteText
|
||||
) where
|
||||
|
||||
import LPGF.Internal
|
||||
import PGF (Language)
|
||||
import PGF.CId
|
||||
import PGF.Expr (Expr, Literal (..))
|
||||
import PGF.Tree (Tree (..), expr2tree, prTree)
|
||||
import qualified PGF
|
||||
|
||||
import Data.Binary (decodeFile)
|
||||
import Data.Either (isLeft)
|
||||
import qualified Data.IntMap as IntMap
|
||||
import qualified Data.Map.Strict as Map
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text as T
|
||||
import Numeric (showFFloat)
|
||||
import Text.Printf (printf)
|
||||
|
||||
import Prelude hiding ((!!))
|
||||
import qualified Prelude
|
||||
|
||||
-- | The abstract language name is the name of the top-level abstract module.
|
||||
abstractName :: LPGF -> CId
|
||||
abstractName = absname
|
||||
|
||||
-- | List of all languages available in the given grammar.
|
||||
languages :: LPGF -> [Language]
|
||||
languages = Map.keys . LPGF.Internal.concretes
|
||||
|
||||
-- | Map of all languages and their corresponding concrete sytaxes.
|
||||
concretes :: LPGF -> Map.Map Language Concrete
|
||||
concretes = LPGF.Internal.concretes
|
||||
|
||||
-- | Reads file in LPGF and produces 'LPGF' term.
|
||||
-- The file is usually produced with:
|
||||
--
|
||||
-- > $ gf --make --output-format=lpgf <grammar file name>
|
||||
readLPGF :: FilePath -> IO LPGF
|
||||
readLPGF = Data.Binary.decodeFile
|
||||
|
||||
-- | Produce pretty-printed representation of an LPGF.
|
||||
showLPGF :: LPGF -> String
|
||||
showLPGF = render . pp
|
||||
|
||||
-- | Main linearize function, to 'String'
|
||||
linearize :: LPGF -> Language -> Expr -> String
|
||||
linearize lpgf lang expr = T.unpack $ linearizeText lpgf lang expr
|
||||
|
||||
-- | Main linearize function, to 'Data.Text.Text'
|
||||
linearizeText :: LPGF -> Language -> Expr -> Text
|
||||
linearizeText lpgf lang =
|
||||
case Map.lookup lang (LPGF.Internal.concretes lpgf) of
|
||||
Just concr -> linearizeConcreteText concr
|
||||
Nothing -> error $ printf "Unknown language: %s" (showCId lang)
|
||||
|
||||
-- | Language-specific linearize function, to 'String'
|
||||
linearizeConcrete :: Concrete -> Expr -> String
|
||||
linearizeConcrete concr expr = T.unpack $ linearizeConcreteText concr expr
|
||||
|
||||
-- | Language-specific linearize function, to 'Data.Text.Text'
|
||||
linearizeConcreteText :: Concrete -> Expr -> Text
|
||||
linearizeConcreteText concr expr = lin2string $ lin (expr2tree expr)
|
||||
where
|
||||
lin :: Tree -> LinFun
|
||||
lin = \case
|
||||
Fun f as ->
|
||||
case Map.lookup f (lins concr) of
|
||||
Just t -> eval cxt t
|
||||
where cxt = Context { cxToks = toks concr, cxArgs = map lin as }
|
||||
_ -> Missing f
|
||||
Lit l -> Tuple [Token (T.pack s)]
|
||||
where
|
||||
s = case l of
|
||||
LStr s -> s
|
||||
LInt i -> show i
|
||||
LFlt f -> showFFloat (Just 6) f ""
|
||||
x -> error $ printf "Cannot lin: %s" (prTree x)
|
||||
|
||||
-- | Evaluation context
|
||||
data Context = Context {
|
||||
cxArgs :: [LinFun], -- ^ is a sequence of terms
|
||||
cxToks :: IntMap.IntMap Text -- ^ token map
|
||||
}
|
||||
|
||||
-- | Operational semantics
|
||||
eval :: Context -> LinFun -> LinFun
|
||||
eval cxt t = case t of
|
||||
Error err -> error err
|
||||
Pre pts df -> Pre pts' df'
|
||||
where
|
||||
pts' = [(pfxs, eval cxt t) | (pfxs, t) <- pts]
|
||||
df' = eval cxt df
|
||||
|
||||
Concat s t -> Concat v w
|
||||
where
|
||||
v = eval cxt s
|
||||
w = eval cxt t
|
||||
Tuple ts -> Tuple vs
|
||||
where vs = map (eval cxt) ts
|
||||
Projection t u ->
|
||||
case (eval cxt t, eval cxt u) of
|
||||
(Missing f, _) -> Missing f
|
||||
(Tuple vs, Missing _) | not (null vs) -> vs !! 0 -- cannot know how deep to unpack; this gives best results with current testsuite
|
||||
(_, Missing f) -> Missing f
|
||||
(Tuple vs, Ix i) -> vs !! (i-1)
|
||||
(t', tv@(Tuple _)) -> eval cxt $ foldl Projection t' (flattenTuple tv)
|
||||
(t',u') -> error $ printf "Incompatible projection:\n- %s\n⇓ %s\n- %s\n⇓ %s" (show t) (show t') (show u) (show u')
|
||||
Argument i -> cxArgs cxt !! (i-1)
|
||||
|
||||
PreIx pts df -> Pre pts' df'
|
||||
where
|
||||
pts' = [(pfxs, eval cxt t) | (ix, t) <- pts, let pfxs = maybe [] (read . T.unpack) $ IntMap.lookup ix (cxToks cxt)]
|
||||
df' = eval cxt df
|
||||
TokenIx i -> maybe Empty Token $ IntMap.lookup i (cxToks cxt)
|
||||
|
||||
_ -> t
|
||||
|
||||
flattenTuple :: LinFun -> [LinFun]
|
||||
flattenTuple = \case
|
||||
Tuple vs -> concatMap flattenTuple vs
|
||||
lf -> [lf]
|
||||
|
||||
-- | Turn concrete syntax terms into an actual string.
|
||||
-- This is done in two passes, first to flatten concats & evaluate pre's, then to
|
||||
-- apply BIND and other predefs.
|
||||
lin2string :: LinFun -> Text
|
||||
lin2string lf = T.unwords $ join $ flatten [lf]
|
||||
where
|
||||
-- Process bind et al into final token list
|
||||
join :: [Either LinFun Text] -> [Text]
|
||||
join elt = case elt of
|
||||
Right tok:Left Bind:ls ->
|
||||
case join ls of
|
||||
next:ls' -> tok `T.append` next : ls'
|
||||
_ -> []
|
||||
Right tok:ls -> tok : join ls
|
||||
Left Space:ls -> join ls
|
||||
Left Capit:ls ->
|
||||
case join ls of
|
||||
next:ls' -> T.toUpper (T.take 1 next) `T.append` T.drop 1 next : ls'
|
||||
_ -> []
|
||||
Left AllCapit:ls ->
|
||||
case join ls of
|
||||
next:ls' -> T.toUpper next : ls'
|
||||
_ -> []
|
||||
Left (Missing cid):ls -> join (Right (T.pack (printf "[%s]" (show cid))) : ls)
|
||||
[] -> []
|
||||
x -> error $ printf "Unhandled term in lin2string: %s" (show x)
|
||||
|
||||
-- Process concats, tuples, pre into flat list
|
||||
flatten :: [LinFun] -> [Either LinFun Text]
|
||||
flatten [] = []
|
||||
flatten (l:ls) = case l of
|
||||
Empty -> flatten ls
|
||||
Token "" -> flatten ls
|
||||
Token tok -> Right tok : flatten ls
|
||||
Concat l1 l2 -> flatten (l1 : l2 : ls)
|
||||
Tuple [l] -> flatten (l:ls)
|
||||
Tuple (l:_) -> flatten (l:ls) -- unselected table, just choose first option (see e.g. FoodsJpn)
|
||||
Pre pts df ->
|
||||
let
|
||||
f = flatten ls
|
||||
ch = case dropWhile isLeft f of
|
||||
Right next:_ ->
|
||||
let matches = [ l | (pfxs, l) <- pts, any (`T.isPrefixOf` next) pfxs ]
|
||||
in if null matches then df else head matches
|
||||
_ -> df
|
||||
in flatten (ch:ls)
|
||||
x -> Left x : flatten ls
|
||||
|
||||
-- | List indexing with more verbose error messages
|
||||
(!!) :: (Show a) => [a] -> Int -> a
|
||||
(!!) xs i
|
||||
| i < 0 = error $ printf "!!: index %d too small for list: %s" i (show xs)
|
||||
| i > length xs - 1 = error $ printf "!!: index %d too large for list: %s" i (show xs)
|
||||
| otherwise = xs Prelude.!! i
|
||||
|
||||
isIx :: LinFun -> Bool
|
||||
isIx (Ix _) = True
|
||||
isIx _ = False
|
||||
227
src/runtime/haskell/LPGF/Internal.hs
Normal file
227
src/runtime/haskell/LPGF/Internal.hs
Normal file
@@ -0,0 +1,227 @@
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
|
||||
module LPGF.Internal where
|
||||
|
||||
import PGF.CId
|
||||
import PGF ()
|
||||
|
||||
import Control.Monad (liftM, liftM2, forM_)
|
||||
import qualified Control.Monad.Writer as CMW
|
||||
import Data.Binary (Binary, put, get, putWord8, getWord8, encodeFile)
|
||||
import qualified Data.IntMap as IntMap
|
||||
import qualified Data.Map.Strict as Map
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as TE
|
||||
|
||||
-- | Linearisation-only PGF
|
||||
data LPGF = LPGF {
|
||||
absname :: CId,
|
||||
abstract :: Abstract,
|
||||
concretes :: Map.Map CId Concrete
|
||||
} deriving (Show)
|
||||
|
||||
-- | Abstract syntax (currently empty)
|
||||
data Abstract = Abstract {
|
||||
} deriving (Show)
|
||||
|
||||
-- | Concrete syntax
|
||||
data Concrete = Concrete {
|
||||
toks :: IntMap.IntMap Text, -- ^ all strings are stored exactly once here
|
||||
-- lincats :: Map.Map CId LinType, -- ^ a linearization type for each category
|
||||
lins :: Map.Map CId LinFun -- ^ a linearization function for each function
|
||||
} deriving (Show)
|
||||
|
||||
-- | Abstract function type
|
||||
-- data Type = Type [CId] CId
|
||||
-- deriving (Show)
|
||||
|
||||
-- -- | Linearisation type
|
||||
-- data LinType =
|
||||
-- StrType
|
||||
-- | IxType Int
|
||||
-- | ProductType [LinType]
|
||||
-- deriving (Show)
|
||||
|
||||
-- | Linearisation function
|
||||
data LinFun =
|
||||
-- Additions
|
||||
Error String -- ^ a runtime error, should probably not be supported at all
|
||||
| Bind -- ^ join adjacent tokens
|
||||
| Space -- ^ space between adjacent tokens
|
||||
| Capit -- ^ capitalise next character
|
||||
| AllCapit -- ^ capitalise next word
|
||||
| Pre [([Text], LinFun)] LinFun
|
||||
| Missing CId -- ^ missing definition (inserted at runtime)
|
||||
|
||||
-- From original definition in paper
|
||||
| Empty
|
||||
| Token Text
|
||||
| Concat LinFun LinFun
|
||||
| Ix Int
|
||||
| Tuple [LinFun]
|
||||
| Projection LinFun LinFun
|
||||
| Argument Int
|
||||
|
||||
-- For reducing LPGF file when stored
|
||||
| PreIx [(Int, LinFun)] LinFun -- ^ index into `toks` map (must apply read to convert to list)
|
||||
| TokenIx Int -- ^ index into `toks` map
|
||||
|
||||
deriving (Show, Read)
|
||||
|
||||
instance Binary LPGF where
|
||||
put lpgf = do
|
||||
put (absname lpgf)
|
||||
put (abstract lpgf)
|
||||
put (concretes lpgf)
|
||||
get = do
|
||||
an <- get
|
||||
abs <- get
|
||||
concs <- get
|
||||
return $ LPGF {
|
||||
absname = an,
|
||||
abstract = abs,
|
||||
concretes = concs
|
||||
}
|
||||
|
||||
instance Binary Abstract where
|
||||
put abs = return ()
|
||||
get = return $ Abstract {}
|
||||
|
||||
instance Binary Concrete where
|
||||
put concr = do
|
||||
put (toks concr)
|
||||
put (lins concr)
|
||||
get = do
|
||||
ts <- get
|
||||
ls <- get
|
||||
return $ Concrete {
|
||||
toks = ts,
|
||||
lins = ls
|
||||
}
|
||||
|
||||
instance Binary LinFun where
|
||||
put = \case
|
||||
Error e -> putWord8 0 >> put e
|
||||
Bind -> putWord8 1
|
||||
Space -> putWord8 2
|
||||
Capit -> putWord8 3
|
||||
AllCapit -> putWord8 4
|
||||
Pre ps d -> putWord8 5 >> put (ps,d)
|
||||
Missing f -> putWord8 13 >> put f
|
||||
|
||||
Empty -> putWord8 6
|
||||
Token t -> putWord8 7 >> put t
|
||||
Concat l1 l2 -> putWord8 8 >> put (l1,l2)
|
||||
Ix i -> putWord8 9 >> put i
|
||||
Tuple ls -> putWord8 10 >> put ls
|
||||
Projection l1 l2 -> putWord8 11 >> put (l1,l2)
|
||||
Argument i -> putWord8 12 >> put i
|
||||
|
||||
PreIx ps d -> putWord8 15 >> put (ps,d)
|
||||
TokenIx i -> putWord8 14 >> put i
|
||||
|
||||
get = do
|
||||
tag <- getWord8
|
||||
case tag of
|
||||
0 -> liftM Error get
|
||||
1 -> return Bind
|
||||
2 -> return Space
|
||||
3 -> return Capit
|
||||
4 -> return AllCapit
|
||||
5 -> liftM2 Pre get get
|
||||
13 -> liftM Missing get
|
||||
|
||||
6 -> return Empty
|
||||
7 -> liftM Token get
|
||||
8 -> liftM2 Concat get get
|
||||
9 -> liftM Ix get
|
||||
10 -> liftM Tuple get
|
||||
11 -> liftM2 Projection get get
|
||||
12 -> liftM Argument get
|
||||
|
||||
15 -> liftM2 PreIx get get
|
||||
14 -> liftM TokenIx get
|
||||
_ -> fail "Failed to decode LPGF binary format"
|
||||
|
||||
instance Binary Text where
|
||||
put = put . TE.encodeUtf8
|
||||
get = liftM TE.decodeUtf8 get
|
||||
|
||||
encodeFile :: FilePath -> LPGF -> IO ()
|
||||
encodeFile = Data.Binary.encodeFile
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Utilities
|
||||
|
||||
-- | Helper for building concat trees
|
||||
mkConcat :: [LinFun] -> LinFun
|
||||
mkConcat [] = Empty
|
||||
mkConcat [x] = x
|
||||
mkConcat xs = foldl1 Concat xs
|
||||
|
||||
-- | Helper for unfolding concat trees
|
||||
unConcat :: LinFun -> [LinFun]
|
||||
unConcat (Concat l1 l2) = concatMap unConcat [l1, l2]
|
||||
unConcat lf = [lf]
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Pretty-printing
|
||||
|
||||
type Doc = CMW.Writer [String] ()
|
||||
|
||||
render :: Doc -> String
|
||||
render = unlines . CMW.execWriter
|
||||
|
||||
class PP a where
|
||||
pp :: a -> Doc
|
||||
|
||||
instance PP LPGF where
|
||||
pp (LPGF _ _ cncs) = mapM_ pp cncs
|
||||
|
||||
instance PP Concrete where
|
||||
pp (Concrete toks lins) = do
|
||||
forM_ (IntMap.toList toks) $ \(i,tok) ->
|
||||
CMW.tell [show i ++ " " ++ T.unpack tok]
|
||||
CMW.tell [""]
|
||||
forM_ (Map.toList lins) $ \(cid,lin) -> do
|
||||
CMW.tell ["# " ++ showCId cid]
|
||||
pp lin
|
||||
CMW.tell [""]
|
||||
|
||||
instance PP LinFun where
|
||||
pp = pp' 0
|
||||
where
|
||||
pp' n = \case
|
||||
Pre ps d -> do
|
||||
p "Pre"
|
||||
CMW.tell [ replicate (2*(n+1)) ' ' ++ show p | p <- ps ]
|
||||
pp' (n+1) d
|
||||
|
||||
c@(Concat l1 l2) -> do
|
||||
let ts = unConcat c
|
||||
if any isDeep ts
|
||||
then do
|
||||
p "Concat"
|
||||
mapM_ (pp' (n+1)) ts
|
||||
else
|
||||
p $ "Concat " ++ show ts
|
||||
Tuple ls | any isDeep ls -> do
|
||||
p "Tuple"
|
||||
mapM_ (pp' (n+1)) ls
|
||||
Projection l1 l2 | isDeep l1 || isDeep l2 -> do
|
||||
p "Projection"
|
||||
pp' (n+1) l1
|
||||
pp' (n+1) l2
|
||||
t -> p $ show t
|
||||
where
|
||||
p :: String -> Doc
|
||||
p t = CMW.tell [ replicate (2*n) ' ' ++ t ]
|
||||
|
||||
isDeep = not . isTerm
|
||||
isTerm = \case
|
||||
Pre _ _ -> False
|
||||
Concat _ _ -> False
|
||||
Tuple _ -> False
|
||||
Projection _ _ -> False
|
||||
_ -> True
|
||||
@@ -185,6 +185,7 @@ instance Binary Instr where
|
||||
put (PUSH_ACCUM (LFlt d)) = putWord8 78 >> put d
|
||||
put (POP_ACCUM ) = putWord8 80
|
||||
put (ADD ) = putWord8 84
|
||||
get = fail "Missing implementation for ‘get’ in the instance declaration for ‘Binary Instr’"
|
||||
|
||||
instance Binary Type where
|
||||
put (DTyp hypos cat exps) = put (hypos,cat,exps)
|
||||
|
||||
@@ -1,29 +1,32 @@
|
||||
name: pgf
|
||||
version: 3.10.1-git
|
||||
version: 3.11.0-git
|
||||
|
||||
cabal-version: >= 1.20
|
||||
cabal-version: 1.22
|
||||
build-type: Simple
|
||||
license: OtherLicense
|
||||
category: Natural Language Processing
|
||||
synopsis: Grammatical Framework
|
||||
description: A library for interpreting the Portable Grammar Format (PGF)
|
||||
homepage: http://www.grammaticalframework.org/
|
||||
homepage: https://www.grammaticalframework.org/
|
||||
bug-reports: https://github.com/GrammaticalFramework/gf-core/issues
|
||||
tested-with: GHC==7.6.3, GHC==7.8.3, GHC==7.10.3, GHC==8.0.2, GHC==8.4.4
|
||||
tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.10.4
|
||||
|
||||
library
|
||||
default-language: Haskell2010
|
||||
build-depends:
|
||||
array,
|
||||
base >= 4.6 && <5,
|
||||
bytestring,
|
||||
containers,
|
||||
-- exceptions,
|
||||
ghc-prim,
|
||||
mtl,
|
||||
pretty,
|
||||
random,
|
||||
utf8-string
|
||||
array >= 0.5.1 && < 0.6,
|
||||
base >= 4.9.1 && < 4.15,
|
||||
bytestring >= 0.10.8 && < 0.11,
|
||||
containers >= 0.5.7 && < 0.7,
|
||||
ghc-prim >= 0.5.0 && < 0.7,
|
||||
mtl >= 2.2.1 && < 2.3,
|
||||
pretty >= 1.1.3 && < 1.2,
|
||||
random >= 1.1 && < 1.3,
|
||||
utf8-string >= 1.0.1.1 && < 1.1
|
||||
|
||||
if impl(ghc<8.0)
|
||||
build-depends:
|
||||
fail >= 4.9.0 && < 4.10
|
||||
|
||||
other-modules:
|
||||
-- not really part of GF but I have changed the original binary library
|
||||
|
||||
3
src/runtime/haskell/stack-ghc7.10.3.yaml
Normal file
3
src/runtime/haskell/stack-ghc7.10.3.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
resolver: lts-6.35 # ghc 7.10.3
|
||||
|
||||
allow-newer: true
|
||||
1
src/runtime/haskell/stack-ghc8.0.2.yaml
Normal file
1
src/runtime/haskell/stack-ghc8.0.2.yaml
Normal file
@@ -0,0 +1 @@
|
||||
resolver: lts-9.21 # ghc 8.0.2
|
||||
1
src/runtime/haskell/stack-ghc8.10.4.yaml
Normal file
1
src/runtime/haskell/stack-ghc8.10.4.yaml
Normal file
@@ -0,0 +1 @@
|
||||
resolver: lts-18.0 # ghc 8.10.4
|
||||
@@ -7,7 +7,7 @@
|
||||
<link rel="alternate stylesheet" type="text/css" href="molto.css" title="MOLTO">
|
||||
<link rel="stylesheet" type="text/css" href="../minibar/minibar.css">
|
||||
<link rel="stylesheet" type="text/css" href="../syntax-editor/editor.css">
|
||||
<link rel="stylesheet" type="text/css" href="https://www.grammaticalframework.org/wordnet/gf-wordnet.css">
|
||||
<link rel="stylesheet" type="text/css" href="../wordnet/gf-wordnet.css">
|
||||
|
||||
|
||||
<link rel=author href="http://www.cse.chalmers.se/~hallgren/" title="Thomas Hallgren">
|
||||
@@ -62,9 +62,9 @@ HTML
|
||||
<script type="text/javascript" src="../syntax-editor/ast.js"></script>
|
||||
<script type="text/javascript" src="../syntax-editor/editor_menu.js"></script>
|
||||
<script type="text/javascript" src="../syntax-editor/editor.js"></script>
|
||||
<script type="text/javascript" src="https://www.grammaticalframework.org/wordnet/js/gf-wordnet.js"></script>
|
||||
<script type="text/javascript" src="https://www.grammaticalframework.org/wordnet/js/tsnejs.js"></script>
|
||||
<script type="text/javascript" src="https://www.grammaticalframework.org/wordnet/js/wordcloud2.js"></script>
|
||||
<script type="text/javascript" src="../wordnet/js/gf-wordnet.js"></script>
|
||||
<script src="https://unpkg.com/vis-network@9.0.4/standalone/umd/vis-network.min.js"></script>
|
||||
<script type="text/javascript" src="../wordnet/js/wordcloud2.js"></script>
|
||||
|
||||
<div id="search_popup" class="search_popup">
|
||||
<table id="domains" class="selector">
|
||||
|
||||
14
stack-ghc8.10.4.yaml
Normal file
14
stack-ghc8.10.4.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
resolver: lts-18.0 # ghc 8.10.4
|
||||
|
||||
extra-deps:
|
||||
- network-2.6.3.6
|
||||
- httpd-shed-0.4.0.3
|
||||
- cgi-3001.5.0.0@sha256:3d1193a328d5f627a021a0ef3927c1ae41dd341e32dba612fed52d0e3a6df056,2990
|
||||
- json-0.10@sha256:d9fc6b07ce92b8894825a17d2cf14799856767eb30c8bf55962baa579207d799,3210
|
||||
- multipart-0.2.0@sha256:b8770e3ff6089be4dd089a8250894b31287cca671f3d258190a505f9351fa8a9,1084
|
||||
|
||||
# flags:
|
||||
# gf:
|
||||
# c-runtime: true
|
||||
# extra-lib-dirs:
|
||||
# - /usr/local/lib
|
||||
@@ -1,13 +1,15 @@
|
||||
# This default stack file is a copy of stack-ghc8.6.5.yaml
|
||||
# This default stack file is a copy of stack-ghc8.10.4.yaml
|
||||
# But committing a symlink can be problematic on Windows, so it's a real copy.
|
||||
# See: https://github.com/GrammaticalFramework/gf-core/pull/106
|
||||
|
||||
resolver: lts-14.27 # ghc 8.6.5
|
||||
resolver: lts-18.0 # ghc 8.10.4
|
||||
|
||||
extra-deps:
|
||||
- network-2.6.3.6
|
||||
- httpd-shed-0.4.0.3
|
||||
- cgi-3001.5.0.0
|
||||
- cgi-3001.5.0.0@sha256:3d1193a328d5f627a021a0ef3927c1ae41dd341e32dba612fed52d0e3a6df056,2990
|
||||
- json-0.10@sha256:d9fc6b07ce92b8894825a17d2cf14799856767eb30c8bf55962baa579207d799,3210
|
||||
- multipart-0.2.0@sha256:b8770e3ff6089be4dd089a8250894b31287cca671f3d258190a505f9351fa8a9,1084
|
||||
|
||||
# flags:
|
||||
# gf:
|
||||
|
||||
392
testsuite/lpgf/README.md
Normal file
392
testsuite/lpgf/README.md
Normal file
@@ -0,0 +1,392 @@
|
||||
# LPGF testsuite & benchmark
|
||||
|
||||
## Testsuite
|
||||
|
||||
LPGF must be equivalent to PGF in terms of linearisation output.
|
||||
|
||||
Possible exceptions:
|
||||
- No handling of variants (design choice)
|
||||
- Rendering of missing functions
|
||||
|
||||
**N.B.**
|
||||
Phrasebook doesn't compile with RGL after 1131058b68c204a8d1312d2e2a610748eb8032cb
|
||||
|
||||
### Running
|
||||
|
||||
Because Stack insists on rebuilding things all the time, I use separate `.stack-work` folders for testing and benchmarking.
|
||||
|
||||
Assumes treebank in same folder with same abstract name as grammar, e.g. `unittests/Params.treebank`
|
||||
|
||||
```
|
||||
stack build --work-dir .stack-work-test --test --no-run-tests
|
||||
stack test --work-dir .stack-work-test gf:test:lpgf # all LPGF tests
|
||||
stack test --work-dir .stack-work-test gf:test:lpgf --test-arguments="unittests/Params" # specific grammar
|
||||
stack test --work-dir .stack-work-test gf:test:lpgf --test-arguments="foods/Foods Fre Ger" # specific grammar and languages
|
||||
stack test --work-dir .stack-work-test gf:test:lpgf --test-arguments="phrasebook/Phrasebook"
|
||||
```
|
||||
|
||||
Set environment variable `DEBUG=1` to enable dumping of intermediate formats into `DEBUG/` folder.
|
||||
|
||||
---
|
||||
|
||||
## Benchmark
|
||||
|
||||
Compare performance metrics between LPGF and PGF[2]. Note: correctness is not checked here.
|
||||
|
||||
### Compilation
|
||||
|
||||
Comparing PGF, LPGF along following criteria:
|
||||
|
||||
- Time
|
||||
- Memory
|
||||
- Binary file size
|
||||
|
||||
### Runtime (linearisation)
|
||||
|
||||
Comparing PGF, PGF2, LPGF along following criteria:
|
||||
|
||||
- Time
|
||||
- Memory
|
||||
|
||||
### Running
|
||||
|
||||
Run each command separately so that memory measurements are isolated.
|
||||
The `+RTS -T -RTS` is so that GHC can report its own memory usage.
|
||||
|
||||
```
|
||||
stack build --work-dir .stack-work-bench --bench --no-run-benchmarks &&
|
||||
stack bench --work-dir .stack-work-bench --benchmark-arguments "compile pgf testsuite/lpgf/foods/Foods*.gf +RTS -T -RTS" &&
|
||||
stack bench --work-dir .stack-work-bench --benchmark-arguments "compile lpgf testsuite/lpgf/foods/Foods*.gf +RTS -T -RTS" &&
|
||||
stack bench --work-dir .stack-work-bench --benchmark-arguments "run pgf Foods.pgf testsuite/lpgf/foods/Foods-all.trees +RTS -T -RTS" &&
|
||||
stack bench --work-dir .stack-work-bench --benchmark-arguments "run pgf2 Foods.pgf testsuite/lpgf/foods/Foods-all.trees +RTS -T -RTS" &&
|
||||
stack bench --work-dir .stack-work-bench --benchmark-arguments "run lpgf Foods.lpgf testsuite/lpgf/foods/Foods-all.trees +RTS -T -RTS"
|
||||
```
|
||||
|
||||
```
|
||||
stack build --work-dir .stack-work-bench --bench --no-run-benchmarks &&
|
||||
stack bench --work-dir .stack-work-bench --benchmark-arguments "compile pgf testsuite/lpgf/phrasebook/Phrasebook*.gf +RTS -T -RTS" &&
|
||||
stack bench --work-dir .stack-work-bench --benchmark-arguments "compile lpgf testsuite/lpgf/phrasebook/Phrasebook*.gf +RTS -T -RTS" &&
|
||||
stack bench --work-dir .stack-work-bench --benchmark-arguments "run pgf Phrasebook.pgf testsuite/lpgf/phrasebook/Phrasebook-10000.trees +RTS -T -RTS" &&
|
||||
stack bench --work-dir .stack-work-bench --benchmark-arguments "run pgf2 Phrasebook.pgf testsuite/lpgf/phrasebook/Phrasebook-10000.trees +RTS -T -RTS" &&
|
||||
stack bench --work-dir .stack-work-bench --benchmark-arguments "run lpgf Phrasebook.lpgf testsuite/lpgf/phrasebook/Phrasebook-10000.trees +RTS -T -RTS"
|
||||
```
|
||||
|
||||
## Profiling
|
||||
|
||||
```
|
||||
stack build --work-dir .stack-work-profile --profile --bench --no-run-benchmarks &&
|
||||
stack bench --work-dir .stack-work-profile --profile --benchmark-arguments "compile lpgf testsuite/lpgf/phrasebook/PhrasebookFre.gf +RTS -T -p -h -RTS"
|
||||
```
|
||||
|
||||
Produced files:
|
||||
- `lpgf-bench.prof` - total time and memory allocation (`-p`)
|
||||
- `lpgf-bench.hp` - heap profile (`-h`)
|
||||
|
||||
Open heap profile graph on-the-fly:
|
||||
```
|
||||
stack exec -- hp2ps -c lpgf-bench.hp && open lpgf-bench.ps
|
||||
```
|
||||
|
||||
Convert and copy timestamped files into `PROF/`:
|
||||
```
|
||||
TS="$(date +%Y-%m-%d_%H%M)" &&
|
||||
stack exec -- hp2ps -c lpgf-bench.hp &&
|
||||
mv lpgf-bench.prof PROF/$TS.prof &&
|
||||
mv lpgf-bench.ps PROF/$TS.ps &&
|
||||
mv lpgf-bench.hs PROF/$TS.hp
|
||||
```
|
||||
|
||||
**Resources**
|
||||
|
||||
- https://downloads.haskell.org/ghc/8.6.5/docs/html/users_guide/profiling.html
|
||||
- http://book.realworldhaskell.org/read/profiling-and-optimization.html
|
||||
- https://wiki.haskell.org/Performance
|
||||
|
||||
|
||||
### Honing in
|
||||
|
||||
```
|
||||
stack build --test --bench --no-run-tests --no-run-benchmarks &&
|
||||
stack bench --benchmark-arguments "compile lpgf testsuite/lpgf/phrasebook/PhrasebookFre.gf +RTS -T -RTS"
|
||||
```
|
||||
|
||||
**Baseline PGF**
|
||||
- compile: 1.600776s
|
||||
- size: 2.88 MB Phrasebook.pgf
|
||||
Max memory: 328.20 MB
|
||||
|
||||
**Baseline LPGF = B**
|
||||
- compile: 12.401099s
|
||||
- size: 3.01 MB Phrasebook.lpgf
|
||||
Max memory: 1.33 GB
|
||||
|
||||
**Baseline LPGF String instead of Text**
|
||||
- compile: 12.124689s
|
||||
- size: 3.01 MB Phrasebook.lpgf
|
||||
Max memory: 1.34 GB
|
||||
|
||||
**Baseline LPGF with impossible pruning**
|
||||
- compile: 7.406503s
|
||||
- size: 3.01 MB Phrasebook.lpgf
|
||||
Max memory: 1.13 GB
|
||||
|
||||
|
||||
**B -extractStrings**
|
||||
- compile: 13.822735s
|
||||
- size: 5.78 MB Phrasebook.lpgf
|
||||
Max memory: 1.39 GB
|
||||
|
||||
**B -cleanupRecordFields**
|
||||
- compile: 13.670776s
|
||||
- size: 3.01 MB Phrasebook.lpgf
|
||||
Max memory: 1.48 GB
|
||||
|
||||
**No generation at all = E**
|
||||
- compile: 0.521001s
|
||||
- size: 3.27 KB Phrasebook.lpgf
|
||||
Max memory: 230.69 MB
|
||||
|
||||
**+ Concat, Literal, Error, Predef, Tuple, Variant, Commented**
|
||||
- compile: 1.503594s
|
||||
- size: 3.27 KB Phrasebook.lpgf
|
||||
Max memory: 395.31 MB
|
||||
|
||||
**+ Var, Pre, Selection**
|
||||
- compile: 1.260184s
|
||||
- size: 3.28 KB Phrasebook.lpgf
|
||||
Max memory: 392.17 MB
|
||||
|
||||
**+ Record**
|
||||
- compile: 1.659233s
|
||||
- size: 7.07 KB Phrasebook.lpgf
|
||||
Max memory: 397.41 MB
|
||||
|
||||
**+ Projection = X**
|
||||
- compile: 1.446217s
|
||||
- size: 7.94 KB Phrasebook.lpgf
|
||||
Max memory: 423.62 MB
|
||||
|
||||
**X + Param**
|
||||
- compile: 2.073838s
|
||||
- size: 10.82 KB Phrasebook.lpgf
|
||||
Max memory: 619.71 MB
|
||||
|
||||
**X + Table**
|
||||
- compile: 11.26558s
|
||||
- size: 2.48 MB Phrasebook.lpgf
|
||||
Max memory: 1.15 GB
|
||||
|
||||
**RawIdents**
|
||||
- compile: 5.393466s
|
||||
- size: 3.01 MB Phrasebook.lpgf
|
||||
Max memory: 1.12 GB
|
||||
|
||||
### Repeated terms in compilation
|
||||
|
||||
**Param and Table**
|
||||
|
||||
| Concr | Total | Unique | Perc |
|
||||
|:--------------|-------:|-------:|-----:|
|
||||
| PhrasebookEng | 8673 | 1724 | 20% |
|
||||
| PhrasebookSwe | 14802 | 2257 | 15% |
|
||||
| PhrasebookFin | 526225 | 4866 | 1% |
|
||||
|
||||
**Param**
|
||||
|
||||
| Concr | Total | Unique | Perc |
|
||||
|:--------------|-------:|-------:|-----:|
|
||||
| PhrasebookEng | 3211 | 78 | 2% |
|
||||
| PhrasebookSwe | 7567 | 69 | 1% |
|
||||
| PhrasebookFin | 316355 | 310 | 0.1% |
|
||||
|
||||
**Table**
|
||||
|
||||
| Concr | Total | Unique | Perc |
|
||||
|:--------------|-------:|-------:|-----:|
|
||||
| PhrasebookEng | 5470 | 1654 | 30% |
|
||||
| PhrasebookSwe | 7243 | 2196 | 30% |
|
||||
| PhrasebookFin | 209878 | 4564 | 2% |
|
||||
|
||||
### After impelementing state monad for table memoisation
|
||||
|
||||
**worse!**
|
||||
- compile: 12.55848s
|
||||
- size: 3.01 MB Phrasebook.lpgf
|
||||
Max memory: 2.25 GB
|
||||
|
||||
**Params**
|
||||
|
||||
| Concr | Total | Misses | Perc |
|
||||
|:--------------|-------:|-------:|------:|
|
||||
| PhrasebookEng | 3211 | 72 | 2% |
|
||||
| PhrasebookSwe | 7526 | 61 | 1% |
|
||||
| PhrasebookFin | 135268 | 333 | 0.2% |
|
||||
| PhrasebookFre | 337102 | 76 | 0.02% |
|
||||
|
||||
**Tables**
|
||||
|
||||
| Concr | Total | Misses | Perc |
|
||||
|:--------------|------:|-------:|-----:|
|
||||
| PhrasebookEng | 3719 | 3170 | 85% |
|
||||
| PhrasebookSwe | 4031 | 3019 | 75% |
|
||||
| PhrasebookFin | 36875 | 21730 | 59% |
|
||||
| PhrasebookFre | 41397 | 32967 | 80% |
|
||||
|
||||
Conclusions:
|
||||
- map itself requires more memory than actual compilation
|
||||
- lookup/insert is also as bad as actual compilation
|
||||
|
||||
Tried HashMap (deriving Hashable for LinValue), no inprovement.
|
||||
Using show on LinValue for keys is incredibly slow.
|
||||
|
||||
# Notes on compilation
|
||||
|
||||
## 1 (see unittests/Params4)
|
||||
|
||||
**param defns**
|
||||
P = P1 | P2
|
||||
Q = Q1 | Q2
|
||||
R = RP P | RPQ P Q | R0
|
||||
X = XPQ P Q
|
||||
|
||||
**translation**
|
||||
NB: tuples may be nested, but will be concatted at runtime
|
||||
|
||||
P1 = <1>
|
||||
P2 = <2>
|
||||
|
||||
Q1 = <1>
|
||||
Q2 = <2>
|
||||
|
||||
R P1 = <1,1>
|
||||
R P2 = <1,2>
|
||||
RPQ P1 Q1 = <2,1,1>
|
||||
RPQ P1 Q2 = <2,1,2>
|
||||
RPQ P2 Q1 = <2,2,1>
|
||||
RPQ P2 Q2 = <2,2,2>
|
||||
R0 = <3>
|
||||
|
||||
XPQ P1 Q1 = <1,1,1>
|
||||
XPQ P1 Q2 = <1,1,2>
|
||||
XPQ P2 Q1 = <1,2,1>
|
||||
XPQ P2 Q2 = <1,2,2>
|
||||
|
||||
P => Str
|
||||
<"P1","P2">
|
||||
|
||||
{p:P ; q:Q} => Str
|
||||
<<"P1;Q1","P1;Q2">,<"P2;Q1","P2;Q2">>
|
||||
|
||||
{p=P2; q=Q1}
|
||||
<<2>,<1>>
|
||||
|
||||
R => Str
|
||||
< <"RP P1","RP P2">,
|
||||
< <"RPQ P1 Q1","RPQ P1 Q2">,
|
||||
<"RPQ P2 Q1","RPQ P2 Q2"> >,
|
||||
"R0"
|
||||
>
|
||||
|
||||
X => Str
|
||||
<<<"XPQ P1 Q1","XPQ P1 Q2">,
|
||||
<"XPQ P2 Q1","XPQ P2 Q2">>>
|
||||
|
||||
{p=P2 ; r=R0}
|
||||
<<2>,<3>>
|
||||
|
||||
{p=P2 ; r1=RP P1 ; r2=RPQ P1 Q2 ; r3=R0 }
|
||||
< <2> , <1, 1> , <2, 1, 2> , <3>>
|
||||
|
||||
## 2 (see unittests/Params5)
|
||||
|
||||
**param defns**
|
||||
|
||||
P = P1 | PQ Q
|
||||
Q = Q1 | QR R
|
||||
R = R1 | R2
|
||||
|
||||
**translation**
|
||||
|
||||
P1 = <1>
|
||||
PQ Q1 = <2,1>
|
||||
PQ QR R1 = <2,2,1>
|
||||
PQ QR R2 = <2,2,2>
|
||||
|
||||
Q1 = <1>
|
||||
QR R1 = <2,1>
|
||||
QR R2 = <2,2>
|
||||
|
||||
R1 = <1>
|
||||
R2 = <2>
|
||||
|
||||
P => Str
|
||||
<"P1",<"PQ Q1",<"PQ (QR R1)","PQ (QR R2)">>>
|
||||
|
||||
{q:Q ; p:P} => Str
|
||||
< <"Q1;P1",<"Q1;PQ Q1",<"Q1;PQ (QR R1)","Q1;PQ (QR R2)">>>,
|
||||
<
|
||||
<"QR R1;P1",<"QR R1;PQ Q1",<"QR R1;PQ (QR R1)","QR R1;PQ (QR R2)">>>,
|
||||
<"QR R2;P1",<"QR R2;PQ Q1",<"QR R2;PQ (QR R1)","QR R2;PQ (QR R2)">>>
|
||||
>
|
||||
>
|
||||
|
||||
{q=Q1 ; p=P1} = <<1>,<1>>
|
||||
{q=Q1 ; p=PQ Q1} = <<1>,<2,1>>
|
||||
{q=Q1 ; p=PQ (QR R1)} = <<1>,<2,2,1>>
|
||||
{q=Q1 ; p=PQ (QR R2)} = <<1>,<2,2,2>>
|
||||
|
||||
{q=QR R1 ; p=P1} = <<2,1>,<1>>
|
||||
{q=QR R1 ; p=PQ Q1} = <<2,1>,<2,1>>
|
||||
{q=QR R1 ; p=PQ (QR R1)} = <<2,1>,<2,2,1>>
|
||||
{q=QR R1 ; p=PQ (QR R2)} = <<2,1>,<2,2,2>>
|
||||
|
||||
{q=QR R2 ; p=P1} = <<2,2>,<1>>
|
||||
{q=QR R2 ; p=PQ Q1} = <<2,2>,<2,1>>
|
||||
{q=QR R2 ; p=PQ (QR R1)} = <<2,2>,<2,2,1>>
|
||||
{q=QR R2 ; p=PQ (QR R2)} = <<2,2>,<2,2,2>>
|
||||
|
||||
**NOTE**: GF will swap q and p in record, as part of record field sorting, resulting in the following:
|
||||
|
||||
{p:P ; q:Q} => Str
|
||||
< <"P1;Q1", <"P1;QR R1","P1;QR R2">>,
|
||||
< <"PQ Q1;Q1", <"PQ Q1;QR R1","PQ Q1;QR R2">>,
|
||||
< <"PQ (QR R1);Q1", <"PQ (QR R1);QR R1","PQ (QR R1);QR R2">>,
|
||||
<"PQ (QR R2);Q1", <"PQ (QR R2);QR R1","PQ (QR R2);QR R2">>
|
||||
>
|
||||
>
|
||||
>
|
||||
|
||||
{p=P1 ; q=Q1} = <<1>,<1>>
|
||||
{p=P1 ; q=QR R1} = <<1>,<2,1>>
|
||||
{p=P1 ; q=QR R2} = <<1>,<2,2>>
|
||||
|
||||
{p=PQ Q1 ; q=Q1} = <<2,1>,<1>>
|
||||
{p=PQ Q1 ; q=QR R1} = <<2,1>,<2,1>>
|
||||
{p=PQ Q1 ; q=QR R2} = <<2,1>,<2,2>>
|
||||
|
||||
{p=PQ (QR R1) ; q=Q1} = <<2,2,1>,<1>>
|
||||
{p=PQ (QR R1) ; q=QR R1} = <<2,2,1>,<2,1>>
|
||||
{p=PQ (QR R1) ; q=QR R2} = <<2,2,1>,<2,2>>
|
||||
|
||||
{p=PQ (QR R2) ; q=Q1} = <<2,2,2>,<1>>
|
||||
{p=PQ (QR R2) ; q=QR R1} = <<2,2,2>,<2,1>>
|
||||
{p=PQ (QR R2) ; q=QR R2} = <<2,2,2>,<2,2>>
|
||||
|
||||
|
||||
{pp: {p:P} ; q:Q} => Str
|
||||
|
||||
{pp={p=P1} ; q=Q1} = <<<1>>,<1>>
|
||||
{pp={p=P1} ; q=QR R1} = <<<1>>,<2,1>>
|
||||
{pp={p=P1} ; q=QR R2} = <<<1>>,<2,2>>
|
||||
|
||||
{pp={p=PQ Q1} ; q=Q1} = <<<2,1>>, <1>>
|
||||
{pp={p=PQ Q1} ; q=QR R1} = <<<2,1>>, <2,1>>
|
||||
{pp={p=PQ Q1} ; q=QR R2} = <<<2,1>>, <2,2>>
|
||||
|
||||
{pp={p=PQ (QR R1)} ; q=Q1} = <<<2,2,1>>,<1>>
|
||||
{pp={p=PQ (QR R1)} ; q=QR R1} = <<<2,2,1>>,<2,1>>
|
||||
{pp={p=PQ (QR R1)} ; q=QR R2} = <<<2,2,1>>,<2,2>>
|
||||
|
||||
{pp={p=PQ (QR R2)} ; q=Q1} = <<<2,2,2>>,<1>>
|
||||
{pp={p=PQ (QR R2)} ; q=QR R1} = <<<2,2,2>>,<2,1>>
|
||||
{pp={p=PQ (QR R2)} ; q=QR R2} = <<<2,2,2>>,<2,2>>
|
||||
193
testsuite/lpgf/bench.hs
Normal file
193
testsuite/lpgf/bench.hs
Normal file
@@ -0,0 +1,193 @@
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
|
||||
module Main where
|
||||
|
||||
import qualified LPGF
|
||||
import qualified PGF
|
||||
import qualified PGF2
|
||||
|
||||
import GF (compileToPGF, compileToLPGF, writePGF, writeLPGF)
|
||||
import GF.Support (Options, Flags (..), Verbosity (..), noOptions, addOptions, modifyFlags)
|
||||
|
||||
import Control.DeepSeq (NFData, force)
|
||||
import qualified Control.Exception as EX
|
||||
import Control.Monad (when, forM)
|
||||
import Data.Either (isLeft)
|
||||
import qualified Data.List as L
|
||||
import Data.Maybe (fromJust, isJust, isNothing)
|
||||
import qualified Data.Map as Map
|
||||
import Data.Text (Text)
|
||||
import Data.Time.Clock (getCurrentTime, diffUTCTime)
|
||||
import System.Console.ANSI
|
||||
import System.Directory (listDirectory, getFileSize)
|
||||
import System.Environment (getArgs)
|
||||
import System.Exit (die)
|
||||
import System.FilePath ((</>), (<.>), takeFileName, takeDirectory, dropExtension)
|
||||
import Text.Printf (printf)
|
||||
|
||||
import GHC.Stats
|
||||
|
||||
options :: Options
|
||||
options = addOptions (modifyFlags (\f -> f{optVerbosity=Quiet})) noOptions
|
||||
|
||||
usage :: String
|
||||
usage = "Arguments:\n\
|
||||
\ compile [pgf|lpgf] FoodsEng.gf FoodsGer.gf ...\n\
|
||||
\ run [pgf|pgf2|lpgf] Foods.pgf test.trees\
|
||||
\"
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
-- Parse command line arguments
|
||||
args <- getArgs
|
||||
let argc = length args
|
||||
when (argc < 1) (die usage)
|
||||
let (mode:_) = args
|
||||
when (mode `L.notElem` ["compile","run"]) (die usage)
|
||||
when (mode == "compile" && argc < 2) (die usage)
|
||||
when (mode == "run" && argc < 3) (die usage)
|
||||
let target = let a1 = args !! 1 in if a1 `elem` ["pgf", "pgf2", "lpgf"] then Just a1 else Nothing
|
||||
let mods' = if mode == "compile" then drop (if isJust target then 2 else 1) args else []
|
||||
|
||||
mods <- concat <$> forM mods' (\mod ->
|
||||
-- If * is supplied in module name, collect modules ourselves
|
||||
if '*' `elem` mod
|
||||
then do
|
||||
let
|
||||
dir = takeDirectory mod
|
||||
pre = takeWhile (/='*') (takeFileName mod)
|
||||
post = drop 1 $ dropWhile (/='*') (takeFileName mod)
|
||||
map (dir </>)
|
||||
. filter (\p -> let fn = takeFileName p in pre `L.isPrefixOf` fn && post `L.isSuffixOf` fn)
|
||||
<$> listDirectory dir
|
||||
else
|
||||
return [mod]
|
||||
)
|
||||
|
||||
let binaryFile = if mode == "run" then Just $ args !! (if isJust target then 2 else 1) else Nothing
|
||||
let treesFile = if mode == "run" then Just $ args !! (if isJust target then 3 else 2) else Nothing
|
||||
|
||||
let doPGF = isNothing target || target == Just "pgf"
|
||||
let doPGF2 = isNothing target || target == Just "pgf2"
|
||||
let doLPGF = isNothing target || target == Just "lpgf"
|
||||
|
||||
-- Compilation
|
||||
when (mode == "compile") $ do
|
||||
when doPGF $ do
|
||||
heading "PGF"
|
||||
(path, pgf) <- time "- compile: " (compilePGF mods)
|
||||
size <- getFileSize path
|
||||
printf "- size: %s %s\n" (convertSize size) path
|
||||
|
||||
when doLPGF $ do
|
||||
heading "LPGF"
|
||||
(path, lpgf) <- time "- compile: " (compileLPGF mods)
|
||||
size <- getFileSize path
|
||||
printf "- size: %s %s\n" (convertSize size) path
|
||||
|
||||
-- Linearisation
|
||||
when (mode == "run") $ do
|
||||
-- Read trees
|
||||
lns <- lines <$> readFile (fromJust treesFile)
|
||||
let trees = map (fromJust . PGF.readExpr) lns
|
||||
let trees2 = map (fromJust . PGF2.readExpr) lns
|
||||
printf "Read %d trees\n" (length trees)
|
||||
|
||||
when doPGF $ do
|
||||
heading "PGF"
|
||||
pgf <- PGF.readPGF (dropExtension (fromJust binaryFile) <.> "pgf")
|
||||
timePure "- linearise: " (linPGF pgf trees)
|
||||
return ()
|
||||
|
||||
when doPGF2 $ do
|
||||
heading "PGF2"
|
||||
pgf <- PGF2.readPGF (dropExtension (fromJust binaryFile) <.> "pgf")
|
||||
timePure "- linearise: " (linPGF2 pgf trees2)
|
||||
return ()
|
||||
|
||||
when doLPGF $ do
|
||||
heading "LPGF"
|
||||
lpgf <- LPGF.readLPGF (dropExtension (fromJust binaryFile) <.> "lpgf")
|
||||
-- timePure "- linearise: " (linLPGF lpgf trees)
|
||||
ress <- time "- linearise: " (linLPGF' lpgf trees)
|
||||
when (any (any isLeft) ress) $ do
|
||||
setSGR [SetColor Foreground Dull Red]
|
||||
putStrLn "Teminated with errors"
|
||||
setSGR [Reset]
|
||||
|
||||
stats <- getRTSStats
|
||||
printf "Max memory: %s\n" (convertSize (fromIntegral (max_mem_in_use_bytes stats)))
|
||||
|
||||
heading :: String -> IO ()
|
||||
heading s = do
|
||||
setSGR [SetColor Foreground Vivid Yellow, SetConsoleIntensity BoldIntensity]
|
||||
putStrLn s
|
||||
setSGR [Reset]
|
||||
|
||||
-- For accurate timing, IO action must for evaluation itself (e.g., write to file)
|
||||
time :: String -> IO a -> IO a
|
||||
time desc io = do
|
||||
start <- getCurrentTime
|
||||
r <- io >>= EX.evaluate -- only WHNF
|
||||
end <- getCurrentTime
|
||||
putStrLn $ desc ++ show (diffUTCTime end start)
|
||||
return r
|
||||
|
||||
-- Performs deep evaluation
|
||||
timePure :: (NFData a) => String -> a -> IO a
|
||||
timePure desc val = time desc (return $ force val)
|
||||
|
||||
compilePGF :: [FilePath] -> IO (FilePath, PGF.PGF)
|
||||
compilePGF mods = do
|
||||
pgf <- compileToPGF options mods
|
||||
files <- writePGF options pgf
|
||||
return (head files, pgf)
|
||||
|
||||
compileLPGF :: [FilePath] -> IO (FilePath, LPGF.LPGF)
|
||||
compileLPGF mods = do
|
||||
lpgf <- compileToLPGF options mods
|
||||
file <- writeLPGF options lpgf
|
||||
return (file, lpgf)
|
||||
|
||||
linPGF :: PGF.PGF -> [PGF.Expr] -> [[String]]
|
||||
linPGF pgf trees =
|
||||
[ map (PGF.linearize pgf lang) trees | lang <- PGF.languages pgf ]
|
||||
|
||||
linPGF2 :: PGF2.PGF -> [PGF2.Expr] -> [[String]]
|
||||
linPGF2 pgf trees =
|
||||
[ map (PGF2.linearize concr) trees | (_, concr) <- Map.toList (PGF2.languages pgf) ]
|
||||
|
||||
linLPGF :: LPGF.LPGF -> [PGF.Expr] -> [[Text]]
|
||||
linLPGF lpgf trees =
|
||||
[ map (LPGF.linearizeConcreteText concr) trees | (_,concr) <- Map.toList (LPGF.concretes lpgf) ]
|
||||
|
||||
linLPGF' :: LPGF.LPGF -> [PGF.Expr] -> IO [[Either String Text]]
|
||||
linLPGF' lpgf trees =
|
||||
forM (Map.toList (LPGF.concretes lpgf)) $ \(_,concr) -> mapM (try . LPGF.linearizeConcreteText concr) trees
|
||||
|
||||
-- | Produce human readable file size
|
||||
-- Adapted from https://hackage.haskell.org/package/hrfsize
|
||||
convertSize :: Integer -> String
|
||||
convertSize = convertSize'' . fromInteger
|
||||
|
||||
convertSize' :: Double -> String
|
||||
convertSize' size
|
||||
| size < 1024.0 = printf "%.0v bytes" size
|
||||
| size < 1024.0 ^ (2 :: Int) = printf "%.2v KiB" $ size / 1024.0
|
||||
| size < 1024.0 ^ (3 :: Int) = printf "%.2v MiB" $ size / 1024.0 ^ (2 :: Int)
|
||||
| size < 1024.0 ^ (4 :: Int) = printf "%.2v GiB" $ size / 1024.0 ^ (3 :: Int)
|
||||
| otherwise = printf "%.2v TiB" $ size / 1024.0 ^ (4 :: Int)
|
||||
|
||||
convertSize'' :: Double -> String
|
||||
convertSize'' size
|
||||
| size < 1000 = printf "%.0v bytes" size
|
||||
| size < 1000 ^ (2 :: Int) = printf "%.2v KB" $ size / 1000
|
||||
| size < 1000 ^ (3 :: Int) = printf "%.2v MB" $ size / 1000 ^ (2 :: Int)
|
||||
| size < 1000 ^ (4 :: Int) = printf "%.2v GB" $ size / 1000 ^ (3 :: Int)
|
||||
| otherwise = printf "%.2v TB" $ size / 1000 ^ (4 :: Int)
|
||||
|
||||
-- | Run a computation and catch any exception/errors.
|
||||
try :: a -> IO (Either String a)
|
||||
try comp = do
|
||||
let f = Right <$> EX.evaluate comp
|
||||
EX.catch f (\(e :: EX.SomeException) -> return $ Left (show e))
|
||||
13
testsuite/lpgf/foods/CharactersGla.gf
Normal file
13
testsuite/lpgf/foods/CharactersGla.gf
Normal file
@@ -0,0 +1,13 @@
|
||||
--# -coding=latin1
|
||||
resource CharactersGla = {
|
||||
|
||||
--Character classes
|
||||
oper
|
||||
vowel : pattern Str = #("a"|"e"|"i"|"o"|"u"|"à"|"è"|"ì"|"ò"|"ù") ;
|
||||
vowelCap : pattern Str = #("A"|"E"|"I"|"O"|"U"|"À"|"É"|"Ì"|"Ò"|"Ù") ;
|
||||
consonant : pattern Str = #("b"|"c"|"d"|"f"|"g"|"h"|"j"|"k"|"l"|"m"|"n"|"p"|"q"|"r"|"s"|"t"|"v"|"w"|"x"|"z") ;
|
||||
consonantCap : pattern Str = #("B"|"C"|"D"|"F"|"G"|"H"|"J"|"K"|"L"|"M"|"N"|"P"|"Q"|"R"|"S"|"T"|"V"|"W"|"X"|"Z") ;
|
||||
broadVowel : pattern Str = #("a"|"o"|"u"|"à"|"ò"|"ù") ;
|
||||
slenderVowel : pattern Str = #("e"|"i"|"è"|"ì") ;
|
||||
|
||||
}
|
||||
13
testsuite/lpgf/foods/CharactersGle.gf
Normal file
13
testsuite/lpgf/foods/CharactersGle.gf
Normal file
@@ -0,0 +1,13 @@
|
||||
--# -coding=latin1
|
||||
resource CharactersGle = {
|
||||
|
||||
--Character classes
|
||||
oper
|
||||
vowel : pattern Str = #("a"|"e"|"i"|"o"|"u"|"á"|"é"|"í"|"ó"|"ú") ;
|
||||
vowelCap : pattern Str = #("A"|"E"|"I"|"O"|"U"|"Á"|"É"|"Í"|"Ó"|"Ú") ;
|
||||
consonant : pattern Str = #("b"|"c"|"d"|"f"|"g"|"h"|"j"|"k"|"l"|"m"|"n"|"p"|"q"|"r"|"s"|"t"|"v"|"w"|"x"|"z") ;
|
||||
consonantCap : pattern Str = #("B"|"C"|"D"|"F"|"G"|"H"|"J"|"K"|"L"|"M"|"N"|"P"|"Q"|"R"|"S"|"T"|"V"|"W"|"X"|"Z") ;
|
||||
broadVowel : pattern Str = #("a"|"o"|"u"|"á"|"ó"|"ú") ;
|
||||
slenderVowel : pattern Str = #("e"|"i"|"é"|"í") ;
|
||||
|
||||
}
|
||||
32640
testsuite/lpgf/foods/Foods-all.trees
Normal file
32640
testsuite/lpgf/foods/Foods-all.trees
Normal file
File diff suppressed because it is too large
Load Diff
15
testsuite/lpgf/foods/Foods.gf
Normal file
15
testsuite/lpgf/foods/Foods.gf
Normal file
@@ -0,0 +1,15 @@
|
||||
-- (c) 2009 Aarne Ranta under LGPL
|
||||
|
||||
abstract Foods = {
|
||||
flags startcat = Comment ;
|
||||
cat
|
||||
Comment ; Item ; Kind ; Quality ;
|
||||
fun
|
||||
Pred : Item -> Quality -> Comment ;
|
||||
This, That, These, Those : Kind -> Item ;
|
||||
Mod : Quality -> Kind -> Kind ;
|
||||
Wine, Cheese, Fish, Pizza : Kind ;
|
||||
Very : Quality -> Quality ;
|
||||
Fresh, Warm, Italian,
|
||||
Expensive, Delicious, Boring : Quality ;
|
||||
}
|
||||
185
testsuite/lpgf/foods/Foods.treebank
Normal file
185
testsuite/lpgf/foods/Foods.treebank
Normal file
@@ -0,0 +1,185 @@
|
||||
Foods: Pred (That Wine) Delicious
|
||||
FoodsAfr: daardie wyn is heerlik
|
||||
FoodsAmh: ያ ወይን ጣፋጭ ነው::
|
||||
FoodsBul: онова вино е превъзходно
|
||||
FoodsCat: aquell vi és deliciós
|
||||
FoodsChi: 那 瓶 酒 是 美 味 的
|
||||
FoodsCze: tamto víno je vynikající
|
||||
FoodsDut: die wijn is lekker
|
||||
FoodsEng: that wine is delicious
|
||||
FoodsEpo: tiu vino estas bongusta
|
||||
FoodsFin: tuo viini on herkullinen
|
||||
FoodsFre: ce vin est délicieux
|
||||
FoodsGer: jener Wein ist köstlich
|
||||
FoodsGla: tha an fìon sin blasta
|
||||
FoodsGle: tá an fíon sin blasta
|
||||
FoodsHeb: היין ההוא טעים
|
||||
FoodsHin: वह मदिरा स्वादिष्ट है
|
||||
FoodsIce: þetta vín er ljúffengt
|
||||
FoodsIta: quel vino è delizioso
|
||||
FoodsJpn: その ワインは おいしい
|
||||
FoodsLat: id vinum est iucundum
|
||||
FoodsLav: tas vīns ir garšīgs
|
||||
FoodsMkd: она вино е вкусно
|
||||
FoodsMlt: dak l- inbid tajjeb
|
||||
FoodsMon: тэр дарс бол амттай
|
||||
FoodsNep: त्यो रक्सी स्वादिष्ट छ
|
||||
FoodsOri: ସେଇ ମଦ ସ୍ଵାଦିସ୍ଟ ଅଟେ
|
||||
FoodsPes: آن شراب لذىذ است
|
||||
FoodsPor: esse vinho é delicioso
|
||||
FoodsRon: acel vin este delicios
|
||||
FoodsSpa: ese vino es delicioso
|
||||
FoodsSwe: det där vinet är läckert
|
||||
FoodsTha: เหล้าองุ่น ขวด นั้น อร่อย
|
||||
FoodsTsn: bojalwa boo bo monate
|
||||
FoodsTur: şu şarap lezzetlidir
|
||||
FoodsUrd: وہ شراب مزیدار ہے
|
||||
|
||||
Foods: Pred (This Pizza) (Very Boring)
|
||||
FoodsAfr: hierdie pizza is baie vervelig
|
||||
FoodsAmh: ይህ [Pizza] በጣም አስቀያሚ ነው::
|
||||
FoodsBul: тази пица е много еднообразна
|
||||
FoodsCat: aquesta pizza és molt aburrida
|
||||
FoodsChi: 这 张 比 萨 饼 是 非 常 难 吃 的
|
||||
FoodsCze: tato pizza je velmi nudná
|
||||
FoodsDut: deze pizza is erg saai
|
||||
FoodsEng: this pizza is very boring
|
||||
FoodsEpo: ĉi tiu pico estas tre enuiga
|
||||
FoodsFin: tämä pizza on erittäin tylsä
|
||||
FoodsFre: cette pizza est très ennuyeuse
|
||||
FoodsGer: diese Pizza ist sehr langweilig
|
||||
FoodsGla: tha an pizza seo glè leamh
|
||||
FoodsGle: tá an píotsa seo an-leamh
|
||||
FoodsHeb: הפיצה הזאת מאוד משעממת
|
||||
FoodsHin: यह पिज़्ज़ा अति अरुचिकर है
|
||||
FoodsIce: þessi flatbaka er mjög leiðinleg
|
||||
FoodsIta: questa pizza è molto noiosa
|
||||
FoodsJpn: この ピザは とても つまらない
|
||||
FoodsLat: haec placenta neapolitana est valde fluens
|
||||
FoodsLav: šī pica ir ļoti garlaicīga
|
||||
FoodsMkd: оваа пица е многу досадна
|
||||
FoodsMlt: din il- pizza tad-dwejjaq ħafna
|
||||
FoodsMon: энэ пицца бол маш амтгүй
|
||||
FoodsNep: यो पिज्जा धेरै नमिठा छ
|
||||
FoodsOri: ଏଇ ପିଜଜ଼ା ଅତି ଅରୁଚିକର ଅଟେ
|
||||
FoodsPes: این پیتزا خیلی ملال آور است
|
||||
FoodsPor: esta pizza é muito chata
|
||||
FoodsRon: această pizza este foarte plictisitoare
|
||||
FoodsSpa: esta pizza es muy aburrida
|
||||
FoodsSwe: den här pizzan är mycket tråkig
|
||||
FoodsTha: พิซซา ถาด นี้ น่าเบิ่อ มาก
|
||||
FoodsTsn: pizza e e bosula thata
|
||||
FoodsTur: bu pizza çok sıkıcıdır
|
||||
FoodsUrd: یھ پیزہ بہت فضول ہے
|
||||
|
||||
Foods: Pred (This Cheese) Fresh
|
||||
FoodsAfr: hierdie kaas is vars
|
||||
FoodsAmh: ይህ አይብ አዲስ ነው::
|
||||
FoodsBul: това сирене е свежо
|
||||
FoodsCat: aquest formatge és fresc
|
||||
FoodsChi: 这 块 奶 酪 是 新 鲜 的
|
||||
FoodsCze: tento sýr je čerstvý
|
||||
FoodsDut: deze kaas is vers
|
||||
FoodsEng: this cheese is fresh
|
||||
FoodsEpo: ĉi tiu fromaĝo estas freŝa
|
||||
FoodsFin: tämä juusto on tuore
|
||||
FoodsFre: ce fromage est frais
|
||||
FoodsGer: dieser Käse ist frisch
|
||||
FoodsGla: tha an càise seo úr
|
||||
FoodsGle: tá an cháis seo úr
|
||||
FoodsHeb: הגבינה הזאת טריה
|
||||
FoodsHin: यह पनीर ताज़ा है
|
||||
FoodsIce: þessi ostur er ferskur
|
||||
FoodsIta: questo formaggio è fresco
|
||||
FoodsJpn: この チーズは 新鮮 だ
|
||||
FoodsLat: hoc formaticum est recens
|
||||
FoodsLav: šis siers ir svaigs
|
||||
FoodsMkd: ова сирење е свежо
|
||||
FoodsMlt: dan il- ġobon frisk
|
||||
FoodsMon: энэ бяслаг бол шинэ
|
||||
FoodsNep: यो चिज ताजा छ
|
||||
FoodsOri: ଏଇ ଛେନା ତାଜା ଅଟେ
|
||||
FoodsPes: این پنیر تازه است
|
||||
FoodsPor: este queijo é fresco
|
||||
FoodsRon: această brânză este proaspătă
|
||||
FoodsSpa: este queso es fresco
|
||||
FoodsSwe: den här osten är färsk
|
||||
FoodsTha: เนยแข็ง ก้อน นี้ สด
|
||||
FoodsTsn: kase e e ntsha
|
||||
FoodsTur: bu peynir tazedir
|
||||
FoodsUrd: یھ پنیر تازہ ہے
|
||||
|
||||
Foods: Pred (Those Fish) Warm
|
||||
FoodsAfr: daardie visse is warm
|
||||
FoodsAmh: [Those] ትኩስ ነው::
|
||||
FoodsBul: онези риби са горещи
|
||||
FoodsCat: aquells peixos són calents
|
||||
FoodsChi: 那 几 条 鱼 是 温 热 的
|
||||
FoodsCze: tamty ryby jsou teplé
|
||||
FoodsDut: die vissen zijn warm
|
||||
FoodsEng: those fish are warm
|
||||
FoodsEpo: tiuj fiŝoj estas varmaj
|
||||
FoodsFin: nuo kalat ovat lämpimiä
|
||||
FoodsFre: ces poissons sont chauds
|
||||
FoodsGer: jene Fische sind warm
|
||||
FoodsGla: tha na h-èisg sin blàth
|
||||
FoodsGle: tá na héisc sin te
|
||||
FoodsHeb: הדגים ההם חמים
|
||||
FoodsHin: वे मछलीयँा गरम हैं
|
||||
FoodsIce: þessir fiskar eru heitir
|
||||
FoodsIta: quei pesci sono caldi
|
||||
FoodsJpn: その 魚は あたたかい
|
||||
FoodsLat: ei pisces sunt calidi
|
||||
FoodsLav: tās zivis ir siltas
|
||||
FoodsMkd: оние риби се топли
|
||||
FoodsMlt: dawk il- ħut sħan
|
||||
FoodsMon: тэдгээр загаснууд бол халуун
|
||||
FoodsNep: ती माछाहरु तातो छन्
|
||||
FoodsOri: ସେଇ ମାଛ ଗୁଡିକ ଗରମ ଅଟେ
|
||||
FoodsPes: آن ماهىها گرم هستند
|
||||
FoodsPor: esses peixes são quentes
|
||||
FoodsRon: acei peşti sunt calzi
|
||||
FoodsSpa: esos pescados son calientes
|
||||
FoodsSwe: de där fiskarna är varma
|
||||
FoodsTha: ปลา ตัว นั้น อุ่น
|
||||
FoodsTsn: dithlapi tseo di bothitho
|
||||
FoodsTur: şu balıklar ılıktır
|
||||
FoodsUrd: وہ مچھلیاں گرم ہیں
|
||||
|
||||
Foods: Pred (That (Mod Boring (Mod Italian Pizza))) Expensive
|
||||
FoodsAfr: daardie vervelige Italiaanse pizza is duur
|
||||
FoodsAmh: ያ አስቀያሚ የጥልያን [Pizza] ውድ ነው::
|
||||
FoodsBul: онази еднообразна италианска пица е скъпа
|
||||
FoodsCat: aquella pizza italiana aburrida és cara
|
||||
FoodsChi: 那 张 又 难 吃 又 意 大 利 式 的 比 萨 饼 是 昂 贵 的
|
||||
FoodsCze: tamta nudná italská pizza je drahá
|
||||
FoodsDut: die saaie Italiaanse pizza is duur
|
||||
FoodsEng: that boring Italian pizza is expensive
|
||||
FoodsEpo: tiu enuiga itala pico estas altekosta
|
||||
FoodsFin: tuo tylsä italialainen pizza on kallis
|
||||
FoodsFre: cette pizza italienne ennuyeuse est chère
|
||||
FoodsGer: jene langweilige italienische Pizza ist teuer
|
||||
FoodsGla: tha an pizza Eadailteach leamh sin daor
|
||||
FoodsGle: tá an píotsa Iodálach leamh sin daor
|
||||
FoodsHeb: הפיצה האיטלקית המשעממת ההיא יקרה
|
||||
FoodsHin: वह अरुचिकर इटली पिज़्ज़ा बहुमूल्य है
|
||||
FoodsIce: þessi leiðinlega ítalska flatbaka er dýr
|
||||
FoodsIta: quella pizza italiana noiosa è cara
|
||||
FoodsJpn: その つまらない イタリアの ピザは たかい
|
||||
FoodsLat: ea placenta itala fluens neapolitana est pretiosa
|
||||
FoodsLav: tā garlaicīgā itāļu pica ir dārga
|
||||
FoodsMkd: онаа досадна италијанска пица е скапа
|
||||
FoodsMlt: dik il- pizza Taljana tad-dwejjaq għalja
|
||||
FoodsMon: тэр амтгүй итали пицца бол үнэтэй
|
||||
FoodsNep: त्यो नमिठा इटालियन पिज्जा महँगो छ
|
||||
FoodsOri: ସେଇ ଅରୁଚିକର ଇଟାଲି ପିଜଜ଼ା ମୁଲ୍ୟବାନ୍ ଅଟେ
|
||||
FoodsPes: آن پیتزا ایتالیایی ى ملال آور گران است
|
||||
FoodsPor: essa pizza Italiana chata é cara
|
||||
FoodsRon: acea pizza italiană plictisitoare este scumpă
|
||||
FoodsSpa: esa pizza italiana aburrida es cara
|
||||
FoodsSwe: den där tråkiga italienska pizzan är dyr
|
||||
FoodsTha: พิซซา อิตาลี น่าเบิ่อ ถาด นั้น แพง
|
||||
FoodsTsn: pizza eo ya ga Itali le e e bosula e a tura
|
||||
FoodsTur: şu sıkıcı İtalyan pizzası pahalıdır
|
||||
FoodsUrd: وہ فضول اٹا لوی پیزہ مہنگا ہے
|
||||
|
||||
5
testsuite/lpgf/foods/Foods.trees
Normal file
5
testsuite/lpgf/foods/Foods.trees
Normal file
@@ -0,0 +1,5 @@
|
||||
Pred (That Wine) Delicious
|
||||
Pred (This Pizza) (Very Boring)
|
||||
Pred (This Cheese) Fresh
|
||||
Pred (Those Fish) Warm
|
||||
Pred (That (Mod Boring (Mod Italian Pizza))) Expensive
|
||||
77
testsuite/lpgf/foods/FoodsAfr.gf
Normal file
77
testsuite/lpgf/foods/FoodsAfr.gf
Normal file
@@ -0,0 +1,77 @@
|
||||
-- (c) 2009 Laurette Pretorius Sr & Jr and Ansu Berg under LGPL
|
||||
--# -coding=latin1
|
||||
|
||||
concrete FoodsAfr of Foods = open Prelude, Predef in{
|
||||
lincat
|
||||
Comment = {s: Str} ;
|
||||
Kind = {s: Number => Str} ;
|
||||
Item = {s: Str ; n: Number} ;
|
||||
Quality = {s: AdjAP => Str} ;
|
||||
|
||||
lin
|
||||
Pred item quality = {s = item.s ++ "is" ++ (quality.s ! Predic)};
|
||||
This kind = {s = "hierdie" ++ (kind.s ! Sg); n = Sg};
|
||||
That kind = {s = "daardie" ++ (kind.s ! Sg); n = Sg};
|
||||
These kind = {s = "hierdie" ++ (kind.s ! Pl); n = Pl};
|
||||
Those kind = {s = "daardie" ++ (kind.s ! Pl); n = Pl};
|
||||
Mod quality kind = {s = table{n => (quality.s ! Attr) ++ (kind.s!n)}};
|
||||
|
||||
Wine = declNoun_e "wyn";
|
||||
Cheese = declNoun_aa "kaas";
|
||||
Fish = declNoun_ss "vis";
|
||||
Pizza = declNoun_s "pizza";
|
||||
|
||||
Very quality = veryAdj quality;
|
||||
|
||||
Fresh = regAdj "vars";
|
||||
Warm = regAdj "warm";
|
||||
Italian = smartAdj_e "Italiaans";
|
||||
Expensive = regAdj "duur";
|
||||
Delicious = smartAdj_e "heerlik";
|
||||
Boring = smartAdj_e "vervelig";
|
||||
|
||||
param
|
||||
AdjAP = Attr | Predic ;
|
||||
Number = Sg | Pl ;
|
||||
|
||||
oper
|
||||
--Noun operations (wyn, kaas, vis, pizza)
|
||||
|
||||
declNoun_aa: Str -> {s: Number => Str} = \x ->
|
||||
let v = tk 2 x
|
||||
in
|
||||
{s = table{Sg => x ; Pl => v + (last x) +"e"}};
|
||||
|
||||
declNoun_e: Str -> {s: Number => Str} = \x -> {s = table{Sg => x ; Pl => x + "e"}} ;
|
||||
declNoun_s: Str -> {s: Number => Str} = \x -> {s = table{Sg => x ; Pl => x + "s"}} ;
|
||||
|
||||
declNoun_ss: Str -> {s: Number => Str} = \x -> {s = table{Sg => x ; Pl => x + (last x) + "e"}} ;
|
||||
|
||||
|
||||
--Adjective operations
|
||||
|
||||
mkAdj : Str -> Str -> {s: AdjAP => Str} = \x,y -> {s = table{Attr => x; Predic => y}};
|
||||
|
||||
declAdj_e : Str -> {s : AdjAP=> Str} = \x -> mkAdj (x + "e") x;
|
||||
declAdj_g : Str -> {s : AdjAP=> Str} = \w ->
|
||||
let v = init w
|
||||
in mkAdj (v + "ë") w ;
|
||||
|
||||
declAdj_oog : Str -> {s : AdjAP=> Str} = \w ->
|
||||
let v = init w
|
||||
in
|
||||
let i = init v
|
||||
in mkAdj (i + "ë") w ;
|
||||
|
||||
regAdj : Str -> {s : AdjAP=> Str} = \x -> mkAdj x x;
|
||||
|
||||
veryAdj : {s: AdjAP => Str} -> {s : AdjAP=> Str} = \x -> {s = table{a => "baie" ++ (x.s!a)}};
|
||||
|
||||
|
||||
smartAdj_e : Str -> {s : AdjAP=> Str} = \a -> case a of
|
||||
{
|
||||
_ + "oog" => declAdj_oog a ;
|
||||
_ + ("e" | "ie" | "o" | "oe") + "g" => declAdj_g a ;
|
||||
_ => declAdj_e a
|
||||
};
|
||||
}
|
||||
21
testsuite/lpgf/foods/FoodsAmh.gf
Normal file
21
testsuite/lpgf/foods/FoodsAmh.gf
Normal file
@@ -0,0 +1,21 @@
|
||||
concrete FoodsAmh of Foods ={
|
||||
flags coding = utf8;
|
||||
lincat
|
||||
Comment,Item,Kind,Quality = Str;
|
||||
lin
|
||||
Pred item quality = item ++ quality++ "ነው::" ;
|
||||
This kind = "ይህ" ++ kind;
|
||||
That kind = "ያ" ++ kind;
|
||||
Mod quality kind = quality ++ kind;
|
||||
Wine = "ወይን";
|
||||
Cheese = "አይብ";
|
||||
Fish = "ዓሳ";
|
||||
Very quality = "በጣም" ++ quality;
|
||||
Fresh = "አዲስ";
|
||||
Warm = "ትኩስ";
|
||||
Italian = "የጥልያን";
|
||||
Expensive = "ውድ";
|
||||
Delicious = "ጣፋጭ";
|
||||
Boring = "አስቀያሚ";
|
||||
|
||||
}
|
||||
43
testsuite/lpgf/foods/FoodsBul.gf
Normal file
43
testsuite/lpgf/foods/FoodsBul.gf
Normal file
@@ -0,0 +1,43 @@
|
||||
-- (c) 2009 Krasimir Angelov under LGPL
|
||||
|
||||
concrete FoodsBul of Foods = {
|
||||
|
||||
flags
|
||||
coding = utf8;
|
||||
|
||||
param
|
||||
Gender = Masc | Fem | Neutr;
|
||||
Number = Sg | Pl;
|
||||
Agr = ASg Gender | APl ;
|
||||
|
||||
lincat
|
||||
Comment = Str ;
|
||||
Quality = {s : Agr => Str} ;
|
||||
Item = {s : Str; a : Agr} ;
|
||||
Kind = {s : Number => Str; g : Gender} ;
|
||||
|
||||
lin
|
||||
Pred item qual = item.s ++ case item.a of {ASg _ => "е"; APl => "са"} ++ qual.s ! item.a ;
|
||||
|
||||
This kind = {s=case kind.g of {Masc=>"този"; Fem=>"тази"; Neutr=>"това" } ++ kind.s ! Sg; a=ASg kind.g} ;
|
||||
That kind = {s=case kind.g of {Masc=>"онзи"; Fem=>"онази"; Neutr=>"онова"} ++ kind.s ! Sg; a=ASg kind.g} ;
|
||||
These kind = {s="тези" ++ kind.s ! Pl; a=APl} ;
|
||||
Those kind = {s="онези" ++ kind.s ! Pl; a=APl} ;
|
||||
|
||||
Mod qual kind = {s=\\n => qual.s ! (case n of {Sg => ASg kind.g; Pl => APl}) ++ kind.s ! n; g=kind.g} ;
|
||||
|
||||
Wine = {s = table {Sg => "вино"; Pl => "вина"}; g = Neutr};
|
||||
Cheese = {s = table {Sg => "сирене"; Pl => "сирена"}; g = Neutr};
|
||||
Fish = {s = table {Sg => "риба"; Pl => "риби"}; g = Fem};
|
||||
Pizza = {s = table {Sg => "пица"; Pl => "пици"}; g = Fem};
|
||||
|
||||
Very qual = {s = \\g => "много" ++ qual.s ! g};
|
||||
|
||||
Fresh = {s = table {ASg Masc => "свеж"; ASg Fem => "свежа"; ASg Neutr => "свежо"; APl => "свежи"}};
|
||||
Warm = {s = table {ASg Masc => "горещ"; ASg Fem => "гореща"; ASg Neutr => "горещо"; APl => "горещи"}};
|
||||
Italian = {s = table {ASg Masc => "италиански"; ASg Fem => "италианска"; ASg Neutr => "италианско"; APl => "италиански"}};
|
||||
Expensive = {s = table {ASg Masc => "скъп"; ASg Fem => "скъпа"; ASg Neutr => "скъпо"; APl => "скъпи"}};
|
||||
Delicious = {s = table {ASg Masc => "превъзходен"; ASg Fem => "превъзходна"; ASg Neutr => "превъзходно"; APl => "превъзходни"}};
|
||||
Boring = {s = table {ASg Masc => "еднообразен"; ASg Fem => "еднообразна"; ASg Neutr => "еднообразно"; APl => "еднообразни"}};
|
||||
|
||||
}
|
||||
6
testsuite/lpgf/foods/FoodsCat.gf
Normal file
6
testsuite/lpgf/foods/FoodsCat.gf
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
-- (c) 2009 Jordi Saludes under LGPL
|
||||
|
||||
concrete FoodsCat of Foods = FoodsI with
|
||||
(Syntax = SyntaxCat),
|
||||
(LexFoods = LexFoodsCat) ;
|
||||
56
testsuite/lpgf/foods/FoodsChi.gf
Normal file
56
testsuite/lpgf/foods/FoodsChi.gf
Normal file
@@ -0,0 +1,56 @@
|
||||
concrete FoodsChi of Foods = open Prelude in {
|
||||
flags coding = utf8 ;
|
||||
lincat
|
||||
Comment, Item = Str;
|
||||
Kind = knd ;
|
||||
Quality = qual ;
|
||||
lin
|
||||
Pred = (\itm, ql ->
|
||||
case ql.hasVery of {
|
||||
True => itm ++ "是 非 常" ++ ql.s ++ ql.p ;
|
||||
False => itm ++ "是" ++ ql.s ++ ql.p } ) ;
|
||||
This kind = "这" ++ kind.c ++ kind.m ++ kind.s ;
|
||||
That kind = "那" ++ kind.c ++ kind.m ++ kind.s ;
|
||||
These kind = "这" ++ "几" ++ kind.c ++ kind.m ++ kind.s ;
|
||||
Those kind = "那" ++ "几" ++ kind.c ++ kind.m ++ kind.s ;
|
||||
Mod = modifier ;
|
||||
|
||||
Wine = geKind "酒" "瓶" ;
|
||||
Pizza = geKind "比 萨 饼" "张" ;
|
||||
Cheese = geKind "奶 酪" "块";
|
||||
Fish = geKind "鱼" "条";
|
||||
|
||||
Very = (\q -> {s = q.s ; p = q.p ; hasVery = True}) ;
|
||||
Fresh = longQuality "新 鲜" ;
|
||||
Warm = longQuality "温 热" ;
|
||||
Italian = longQuality "意 大 利 式" ;
|
||||
Expensive = longQuality "昂 贵" ;
|
||||
Delicious = longQuality "美 味" ;
|
||||
-- this technically translates to "unpalatable" instead of boring
|
||||
Boring = longQuality "难 吃" ;
|
||||
|
||||
oper
|
||||
-- lincat aliases
|
||||
qual : Type = {s,p : Str ; hasVery : Bool} ;
|
||||
knd : Type = {s,c,m : Str; hasMod : Bool} ;
|
||||
|
||||
-- Constructor functions
|
||||
mkKind : Str -> Str -> knd = \s,c ->
|
||||
{s = s ; c = c; m = ""; hasMod = False} ;
|
||||
geKind : Str -> Str -> knd = \s,cl ->
|
||||
mkKind s (classifier cl) ;
|
||||
longQuality : Str -> qual = \s ->
|
||||
{s = s ; p = "的" ; hasVery = False} ;
|
||||
modifier : qual -> knd -> knd = \q,k ->
|
||||
{ s = k.s ; c = k.c ; m = modJoin k.hasMod q k.m ;
|
||||
hasMod = True } ;
|
||||
|
||||
-- Helper functions
|
||||
classifier : Str -> Str = \s ->
|
||||
case s of {"" => "个" ; _ => s };
|
||||
modJoin : Bool -> qual -> Str -> Str = \bool, q,m ->
|
||||
case bool of {
|
||||
True => "又" ++ q.s ++ "又" ++ m ;
|
||||
False => q.s ++ q.p } ;
|
||||
|
||||
}
|
||||
35
testsuite/lpgf/foods/FoodsCze.gf
Normal file
35
testsuite/lpgf/foods/FoodsCze.gf
Normal file
@@ -0,0 +1,35 @@
|
||||
-- (c) 2011 Katerina Bohmova under LGPL
|
||||
|
||||
concrete FoodsCze of Foods = open ResCze in {
|
||||
flags
|
||||
coding = utf8 ;
|
||||
lincat
|
||||
Comment = {s : Str} ;
|
||||
Quality = Adjective ;
|
||||
Kind = Noun ;
|
||||
Item = NounPhrase ;
|
||||
lin
|
||||
Pred item quality =
|
||||
{s = item.s ++ copula ! item.n ++
|
||||
quality.s ! item.g ! item.n} ;
|
||||
This = det Sg "tento" "tato" "toto" ;
|
||||
That = det Sg "tamten" "tamta" "tamto" ;
|
||||
These = det Pl "tyto" "tyto" "tato" ;
|
||||
Those = det Pl "tamty" "tamty" "tamta" ;
|
||||
Mod quality kind = {
|
||||
s = \\n => quality.s ! kind.g ! n ++ kind.s ! n ;
|
||||
g = kind.g
|
||||
} ;
|
||||
Wine = noun "víno" "vína" Neutr ;
|
||||
Cheese = noun "sýr" "sýry" Masc ;
|
||||
Fish = noun "ryba" "ryby" Fem ;
|
||||
Pizza = noun "pizza" "pizzy" Fem ;
|
||||
Very qual = {s = \\g,n => "velmi" ++ qual.s ! g ! n} ;
|
||||
Fresh = regAdj "čerstv" ;
|
||||
Warm = regAdj "tepl" ;
|
||||
Italian = regAdj "italsk" ;
|
||||
Expensive = regAdj "drah" ;
|
||||
Delicious = regnfAdj "vynikající" ;
|
||||
Boring = regAdj "nudn" ;
|
||||
}
|
||||
|
||||
58
testsuite/lpgf/foods/FoodsDut.gf
Normal file
58
testsuite/lpgf/foods/FoodsDut.gf
Normal file
@@ -0,0 +1,58 @@
|
||||
-- (c) 2009 Femke Johansson under LGPL
|
||||
|
||||
concrete FoodsDut of Foods = {
|
||||
|
||||
lincat
|
||||
Comment = {s : Str};
|
||||
Quality = {s : AForm => Str};
|
||||
Kind = { s : Number => Str};
|
||||
Item = {s : Str ; n : Number};
|
||||
|
||||
lin
|
||||
Pred item quality =
|
||||
{s = item.s ++ copula ! item.n ++ quality.s ! APred};
|
||||
This = det Sg "deze";
|
||||
These = det Pl "deze";
|
||||
That = det Sg "die";
|
||||
Those = det Pl "die";
|
||||
|
||||
Mod quality kind =
|
||||
{s = \\n => quality.s ! AAttr ++ kind.s ! n};
|
||||
Wine = regNoun "wijn";
|
||||
Cheese = noun "kaas" "kazen";
|
||||
Fish = noun "vis" "vissen";
|
||||
Pizza = noun "pizza" "pizza's";
|
||||
|
||||
Very a = {s = \\f => "erg" ++ a.s ! f};
|
||||
|
||||
Fresh = regadj "vers";
|
||||
Warm = regadj "warm";
|
||||
Italian = regadj "Italiaans";
|
||||
Expensive = adj "duur" "dure";
|
||||
Delicious = regadj "lekker";
|
||||
Boring = regadj "saai";
|
||||
|
||||
param
|
||||
Number = Sg | Pl;
|
||||
AForm = APred | AAttr;
|
||||
|
||||
oper
|
||||
det : Number -> Str ->
|
||||
{s : Number => Str} -> {s : Str ; n: Number} =
|
||||
\n,det,noun -> {s = det ++ noun.s ! n ; n=n};
|
||||
|
||||
noun : Str -> Str -> {s : Number => Str} =
|
||||
\man,men -> {s = table {Sg => man; Pl => men}};
|
||||
|
||||
regNoun : Str -> {s : Number => Str} =
|
||||
\wijn -> noun wijn (wijn + "en");
|
||||
|
||||
regadj : Str -> {s : AForm => Str} =
|
||||
\koud -> adj koud (koud+"e");
|
||||
|
||||
adj : Str -> Str -> {s : AForm => Str} =
|
||||
\duur, dure -> {s = table {APred => duur; AAttr => dure}};
|
||||
|
||||
copula : Number => Str =
|
||||
table {Sg => "is" ; Pl => "zijn"};
|
||||
}
|
||||
43
testsuite/lpgf/foods/FoodsEng.gf
Normal file
43
testsuite/lpgf/foods/FoodsEng.gf
Normal file
@@ -0,0 +1,43 @@
|
||||
-- (c) 2009 Aarne Ranta under LGPL
|
||||
|
||||
concrete FoodsEng of Foods = {
|
||||
flags language = en_US;
|
||||
lincat
|
||||
Comment, Quality = {s : Str} ;
|
||||
Kind = {s : Number => Str} ;
|
||||
Item = {s : Str ; n : Number} ;
|
||||
lin
|
||||
Pred item quality =
|
||||
{s = item.s ++ copula ! item.n ++ quality.s} ;
|
||||
This = det Sg "this" ;
|
||||
That = det Sg "that" ;
|
||||
These = det Pl "these" ;
|
||||
Those = det Pl "those" ;
|
||||
Mod quality kind =
|
||||
{s = \\n => quality.s ++ kind.s ! n} ;
|
||||
Wine = regNoun "wine" ;
|
||||
Cheese = regNoun "cheese" ;
|
||||
Fish = noun "fish" "fish" ;
|
||||
Pizza = regNoun "pizza" ;
|
||||
Very a = {s = "very" ++ a.s} ;
|
||||
Fresh = adj "fresh" ;
|
||||
Warm = adj "warm" ;
|
||||
Italian = adj "Italian" ;
|
||||
Expensive = adj "expensive" ;
|
||||
Delicious = adj "delicious" ;
|
||||
Boring = adj "boring" ;
|
||||
param
|
||||
Number = Sg | Pl ;
|
||||
oper
|
||||
det : Number -> Str ->
|
||||
{s : Number => Str} -> {s : Str ; n : Number} =
|
||||
\n,det,noun -> {s = det ++ noun.s ! n ; n = n} ;
|
||||
noun : Str -> Str -> {s : Number => Str} =
|
||||
\man,men -> {s = table {Sg => man ; Pl => men}} ;
|
||||
regNoun : Str -> {s : Number => Str} =
|
||||
\car -> noun car (car + "s") ;
|
||||
adj : Str -> {s : Str} =
|
||||
\cold -> {s = cold} ;
|
||||
copula : Number => Str =
|
||||
table {Sg => "is" ; Pl => "are"} ;
|
||||
}
|
||||
48
testsuite/lpgf/foods/FoodsEpo.gf
Normal file
48
testsuite/lpgf/foods/FoodsEpo.gf
Normal file
@@ -0,0 +1,48 @@
|
||||
-- (c) 2009 Julia Hammar under LGPL
|
||||
|
||||
concrete FoodsEpo of Foods = open Prelude in {
|
||||
|
||||
flags coding =utf8 ;
|
||||
|
||||
lincat
|
||||
Comment = SS ;
|
||||
Kind, Quality = {s : Number => Str} ;
|
||||
Item = {s : Str ; n : Number} ;
|
||||
|
||||
lin
|
||||
Pred item quality = ss (item.s ++ copula ! item.n ++ quality.s ! item.n) ;
|
||||
This = det Sg "ĉi tiu" ;
|
||||
That = det Sg "tiu" ;
|
||||
These = det Pl "ĉi tiuj" ;
|
||||
Those = det Pl "tiuj" ;
|
||||
Mod quality kind = {s = \\n => quality.s ! n ++ kind.s ! n} ;
|
||||
Wine = regNoun "vino" ;
|
||||
Cheese = regNoun "fromaĝo" ;
|
||||
Fish = regNoun "fiŝo" ;
|
||||
Pizza = regNoun "pico" ;
|
||||
Very quality = {s = \\n => "tre" ++ quality.s ! n} ;
|
||||
Fresh = regAdj "freŝa" ;
|
||||
Warm = regAdj "varma" ;
|
||||
Italian = regAdj "itala" ;
|
||||
Expensive = regAdj "altekosta" ;
|
||||
Delicious = regAdj "bongusta" ;
|
||||
Boring = regAdj "enuiga" ;
|
||||
|
||||
param
|
||||
Number = Sg | Pl ;
|
||||
|
||||
oper
|
||||
det : Number -> Str -> {s : Number => Str} -> {s : Str ; n : Number} =
|
||||
\n,d,cn -> {
|
||||
s = d ++ cn.s ! n ;
|
||||
n = n
|
||||
} ;
|
||||
regNoun : Str -> {s : Number => Str} =
|
||||
\vino -> {s = table {Sg => vino ; Pl => vino + "j"}
|
||||
} ;
|
||||
regAdj : Str -> {s : Number => Str} =
|
||||
\nova -> {s = table {Sg => nova ; Pl => nova + "j"}
|
||||
} ;
|
||||
copula : Number => Str = \\_ => "estas" ;
|
||||
}
|
||||
|
||||
6
testsuite/lpgf/foods/FoodsFin.gf
Normal file
6
testsuite/lpgf/foods/FoodsFin.gf
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
-- (c) 2009 Aarne Ranta under LGPL
|
||||
|
||||
concrete FoodsFin of Foods = FoodsI with
|
||||
(Syntax = SyntaxFin),
|
||||
(LexFoods = LexFoodsFin) ;
|
||||
31
testsuite/lpgf/foods/FoodsFre.gf
Normal file
31
testsuite/lpgf/foods/FoodsFre.gf
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
concrete FoodsFre of Foods = open SyntaxFre, ParadigmsFre in {
|
||||
|
||||
flags coding = utf8 ;
|
||||
|
||||
lincat
|
||||
Comment = Utt ;
|
||||
Item = NP ;
|
||||
Kind = CN ;
|
||||
Quality = AP ;
|
||||
|
||||
lin
|
||||
Pred item quality = mkUtt (mkCl item quality) ;
|
||||
This kind = mkNP this_QuantSg kind ;
|
||||
That kind = mkNP that_QuantSg kind ;
|
||||
These kind = mkNP these_QuantPl kind ;
|
||||
Those kind = mkNP those_QuantPl kind ;
|
||||
Mod quality kind = mkCN quality kind ;
|
||||
Very quality = mkAP very_AdA quality ;
|
||||
|
||||
Wine = mkCN (mkN "vin" masculine) ;
|
||||
Pizza = mkCN (mkN "pizza" feminine) ;
|
||||
Cheese = mkCN (mkN "fromage" masculine) ;
|
||||
Fish = mkCN (mkN "poisson" masculine) ;
|
||||
Fresh = mkAP (mkA "frais" "fraîche" "frais" "fraîchement") ;
|
||||
Warm = mkAP (mkA "chaud") ;
|
||||
Italian = mkAP (mkA "italien") ;
|
||||
Expensive = mkAP (mkA "cher") ;
|
||||
Delicious = mkAP (mkA "délicieux") ;
|
||||
Boring = mkAP (mkA "ennuyeux") ;
|
||||
}
|
||||
6
testsuite/lpgf/foods/FoodsGer.gf
Normal file
6
testsuite/lpgf/foods/FoodsGer.gf
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
-- (c) 2009 Aarne Ranta under LGPL
|
||||
|
||||
concrete FoodsGer of Foods = FoodsI with
|
||||
(Syntax = SyntaxGer),
|
||||
(LexFoods = LexFoodsGer) ;
|
||||
67
testsuite/lpgf/foods/FoodsGla.gf
Normal file
67
testsuite/lpgf/foods/FoodsGla.gf
Normal file
@@ -0,0 +1,67 @@
|
||||
--# -coding=latin1
|
||||
concrete FoodsGla of Foods = open MutationsGla, CharactersGla, Prelude in {
|
||||
param Gender = Masc|Fem ;
|
||||
param Number = Sg|Pl ;
|
||||
param Breadth = Broad|Slender|NoBreadth ;
|
||||
param Beginning = Bcgmp|Other ;
|
||||
|
||||
lincat Comment = Str;
|
||||
lin Pred item quality = "tha" ++ item ++ quality.s!Sg!Unmutated ;
|
||||
|
||||
lincat Item = Str;
|
||||
lin
|
||||
This kind = (addArticleSg kind) ++ "seo" ;
|
||||
That kind = (addArticleSg kind) ++ "sin";
|
||||
These kind = (addArticlePl kind) ++ "seo" ;
|
||||
Those kind = (addArticlePl kind) ++ "sin" ;
|
||||
oper addArticleSg : {s : Number => Mutation => Str; g : Gender} -> Str =
|
||||
\kind -> case kind.g of { Masc => "an" ++ kind.s!Sg!PrefixT; Fem => "a'" ++ kind.s!Sg!Lenition1DNTLS } ;
|
||||
oper addArticlePl : {s : Number => Mutation => Str; g : Gender} -> Str =
|
||||
\kind -> "na" ++ kind.s!Pl!PrefixH ;
|
||||
|
||||
oper Noun : Type = {s : Number => Mutation => Str; g : Gender; pe : Breadth; beginning: Beginning; };
|
||||
lincat Kind = Noun;
|
||||
lin
|
||||
Mod quality kind = {
|
||||
s = table{
|
||||
Sg => table{mutation => kind.s!Sg!mutation ++ case kind.g of {Masc => quality.s!Sg!Unmutated; Fem => quality.s!Sg!Lenition1} };
|
||||
Pl => table{mutation => kind.s!Pl!mutation ++ case kind.pe of {Slender => quality.s!Pl!Lenition1; _ => quality.s!Pl!Unmutated} }
|
||||
};
|
||||
g = kind.g;
|
||||
pe = kind.pe;
|
||||
beginning = kind.beginning
|
||||
} ;
|
||||
Wine = makeNoun "fìon" "fìontan" Masc ;
|
||||
Cheese = makeNoun "càise" "càisean" Masc ;
|
||||
Fish = makeNoun "iasg" "èisg" Masc ;
|
||||
Pizza = makeNoun "pizza" "pizzathan" Masc ;
|
||||
oper makeNoun : Str -> Str -> Gender -> Noun = \sg,pl,g -> {
|
||||
s = table{Sg => (mutate sg); Pl => (mutate pl)};
|
||||
g = g;
|
||||
pe = pe;
|
||||
beginning = Bcgmp
|
||||
}
|
||||
where {
|
||||
pe : Breadth = case pl of {
|
||||
_ + v@(#broadVowel) + c@(#consonant*) + #consonant => Broad;
|
||||
_ + v@(#slenderVowel) + c@(#consonant*) + #consonant => Slender;
|
||||
_ => NoBreadth
|
||||
}
|
||||
};
|
||||
|
||||
oper Adjective : Type = {s : Number => Mutation => Str; sVery : Number => Str};
|
||||
lincat Quality = Adjective;
|
||||
lin
|
||||
Very quality = {s=table{number => table{_ => quality.sVery!number}}; sVery=quality.sVery } ;
|
||||
Fresh = makeAdjective "úr" "ùra" ;
|
||||
Warm = makeAdjective "blàth" "blàtha" ;
|
||||
Italian = makeAdjective "Eadailteach" "Eadailteach" ;
|
||||
Expensive = makeAdjective "daor" "daora" ;
|
||||
Delicious = makeAdjective "blasta" "blasta" ;
|
||||
Boring = makeAdjective "leamh" "leamha" ;
|
||||
oper makeAdjective : Str -> Str -> Adjective =
|
||||
\sg,pl -> {
|
||||
s=table{Sg => (mutate sg); Pl => (mutate pl)};
|
||||
sVery=table{Sg => "glè"++(lenition1dntls sg); Pl => "glè"++(lenition1dntls pl)}
|
||||
} ;
|
||||
}
|
||||
60
testsuite/lpgf/foods/FoodsGle.gf
Normal file
60
testsuite/lpgf/foods/FoodsGle.gf
Normal file
@@ -0,0 +1,60 @@
|
||||
--# -coding=latin1
|
||||
concrete FoodsGle of Foods = open MutationsGle, CharactersGle in {
|
||||
param Gender = Masc|Fem ;
|
||||
param Number = Sg|Pl ;
|
||||
param Breadth = Broad|Slender|NoBreadth ;
|
||||
|
||||
lincat Comment = Str;
|
||||
lin Pred item quality = "tá" ++ item ++ quality.s!Sg!Unmutated ;
|
||||
|
||||
lincat Item = Str;
|
||||
lin
|
||||
This kind = (addArticleSg kind) ++ "seo" ;
|
||||
That kind = (addArticleSg kind) ++ "sin";
|
||||
These kind = (addArticlePl kind) ++ "seo" ;
|
||||
Those kind = (addArticlePl kind) ++ "sin" ;
|
||||
oper addArticleSg : {s : Number => Mutation => Str; g : Gender} -> Str =
|
||||
\kind -> "an" ++ case kind.g of { Masc => kind.s!Sg!PrefixT; Fem => kind.s!Sg!Lenition1DNTLS } ;
|
||||
oper addArticlePl : {s : Number => Mutation => Str; g : Gender} -> Str =
|
||||
\kind -> "na" ++ kind.s!Pl!PrefixH ;
|
||||
|
||||
lincat Kind = {s : Number => Mutation => Str; g : Gender; pe : Breadth} ;
|
||||
lin
|
||||
Mod quality kind = {
|
||||
s = table{
|
||||
Sg => table{mutation => kind.s!Sg!mutation ++ case kind.g of {Masc => quality.s!Sg!Unmutated; Fem => quality.s!Sg!Lenition1} };
|
||||
Pl => table{mutation => kind.s!Pl!mutation ++ case kind.pe of {Slender => quality.s!Pl!Lenition1; _ => quality.s!Pl!Unmutated} }
|
||||
};
|
||||
g = kind.g;
|
||||
pe = kind.pe
|
||||
} ;
|
||||
Wine = makeNoun "fíon" "fíonta" Masc ;
|
||||
Cheese = makeNoun "cáis" "cáiseanna" Fem ;
|
||||
Fish = makeNoun "iasc" "éisc" Masc ;
|
||||
Pizza = makeNoun "píotsa" "píotsaí" Masc ;
|
||||
oper makeNoun : Str -> Str -> Gender -> {s : Number => Mutation => Str; g : Gender; pe : Breadth} =
|
||||
\sg,pl,g -> {
|
||||
s = table{Sg => (mutate sg); Pl => (mutate pl)};
|
||||
g = g;
|
||||
pe = case pl of {
|
||||
_ + v@(#broadVowel) + c@(#consonant*) + #consonant => Broad;
|
||||
_ + v@(#slenderVowel) + c@(#consonant*) + #consonant => Slender;
|
||||
_ => NoBreadth
|
||||
}
|
||||
} ;
|
||||
|
||||
lincat Quality = {s : Number => Mutation => Str; sVery : Number => Str} ;
|
||||
lin
|
||||
Very quality = {s=table{number => table{_ => quality.sVery!number}}; sVery=quality.sVery } ;
|
||||
Fresh = makeAdjective "úr" "úra" ;
|
||||
Warm = makeAdjective "te" "te" ;
|
||||
Italian = makeAdjective "Iodálach" "Iodálacha" ;
|
||||
Expensive = makeAdjective "daor" "daora" ;
|
||||
Delicious = makeAdjective "blasta" "blasta" ;
|
||||
Boring = makeAdjective "leamh" "leamha" ;
|
||||
oper makeAdjective : Str -> Str -> {s : Number => Mutation => Str; sVery : Number => Str} =
|
||||
\sg,pl -> {
|
||||
s=table{Sg => (mutate sg); Pl => (mutate pl)};
|
||||
sVery=table{Sg => "an-"+(lenition1dntls sg); Pl => "an-"+(lenition1dntls pl)}
|
||||
} ;
|
||||
}
|
||||
107
testsuite/lpgf/foods/FoodsHeb.gf
Normal file
107
testsuite/lpgf/foods/FoodsHeb.gf
Normal file
@@ -0,0 +1,107 @@
|
||||
|
||||
--(c) 2009 Dana Dannells
|
||||
-- Licensed under LGPL
|
||||
|
||||
concrete FoodsHeb of Foods = open Prelude in {
|
||||
|
||||
flags coding=utf8 ;
|
||||
|
||||
lincat
|
||||
Comment = SS ;
|
||||
Quality = {s: Number => Species => Gender => Str} ;
|
||||
Kind = {s : Number => Species => Str ; g : Gender ; mod : Modified} ;
|
||||
Item = {s : Str ; g : Gender ; n : Number ; sp : Species ; mod : Modified} ;
|
||||
|
||||
|
||||
lin
|
||||
Pred item quality = ss (item.s ++ quality.s ! item.n ! Indef ! item.g ) ;
|
||||
This = det Sg Def "הזה" "הזאת";
|
||||
That = det Sg Def "ההוא" "ההיא" ;
|
||||
These = det Pl Def "האלה" "האלה" ;
|
||||
Those = det Pl Def "ההם" "ההן" ;
|
||||
Mod quality kind = {
|
||||
s = \\n,sp => kind.s ! n ! sp ++ quality.s ! n ! sp ! kind.g;
|
||||
g = kind.g ;
|
||||
mod = T
|
||||
} ;
|
||||
Wine = regNoun "יין" "יינות" Masc ;
|
||||
Cheese = regNoun "גבינה" "גבינות" Fem ;
|
||||
Fish = regNoun "דג" "דגים" Masc ;
|
||||
Pizza = regNoun "פיצה" "פיצות" Fem ;
|
||||
Very qual = {s = \\g,n,sp => "מאוד" ++ qual.s ! g ! n ! sp} ;
|
||||
Fresh = regAdj "טרי" ;
|
||||
Warm = regAdj "חם" ;
|
||||
Italian = regAdj2 "איטלקי" ;
|
||||
Expensive = regAdj "יקר" ;
|
||||
Delicious = regAdj "טעים" ;
|
||||
Boring = regAdj2 "משעמם";
|
||||
|
||||
param
|
||||
Number = Sg | Pl ;
|
||||
Gender = Masc | Fem ;
|
||||
Species = Def | Indef ;
|
||||
Modified = T | F ;
|
||||
|
||||
oper
|
||||
Noun : Type = {s : Number => Species => Str ; g : Gender ; mod : Modified } ;
|
||||
Adj : Type = {s : Number => Species => Gender => Str} ;
|
||||
|
||||
det : Number -> Species -> Str -> Str -> Noun ->
|
||||
{s : Str ; g :Gender ; n : Number ; sp : Species ; mod : Modified} =
|
||||
\n,sp,m,f,cn -> {
|
||||
s = case cn.mod of { _ => cn.s ! n ! sp ++ case cn.g of {Masc => m ; Fem => f} };
|
||||
g = cn.g ;
|
||||
n = n ;
|
||||
sp = sp ;
|
||||
mod = cn.mod
|
||||
} ;
|
||||
|
||||
noun : (gvina,hagvina,gvinot,hagvinot : Str) -> Gender -> Noun =
|
||||
\gvina,hagvina,gvinot,hagvinot,g -> {
|
||||
s = table {
|
||||
Sg => table {
|
||||
Indef => gvina ;
|
||||
Def => hagvina
|
||||
} ;
|
||||
Pl => table {
|
||||
Indef => gvinot ;
|
||||
Def => hagvinot
|
||||
}
|
||||
} ;
|
||||
g = g ;
|
||||
mod = F
|
||||
} ;
|
||||
|
||||
regNoun : Str -> Str -> Gender -> Noun =
|
||||
\gvina,gvinot, g ->
|
||||
noun gvina (defH gvina) gvinot (defH gvinot) g ;
|
||||
|
||||
defH : Str -> Str = \cn ->
|
||||
case cn of {_ => "ה" + cn};
|
||||
|
||||
replaceLastLetter : Str -> Str = \c ->
|
||||
case c of {"ף" => "פ" ; "ם" => "מ" ; "ן" => "נ" ; "ץ" => "צ" ; "ך" => "כ"; _ => c} ;
|
||||
|
||||
adjective : (_,_,_,_ : Str) -> Adj =
|
||||
\tov,tova,tovim,tovot -> {
|
||||
s = table {
|
||||
Sg => table {
|
||||
Indef => table { Masc => tov ; Fem => tova } ;
|
||||
Def => table { Masc => defH tov ; Fem => defH tova }
|
||||
} ;
|
||||
Pl => table {
|
||||
Indef => table {Masc => tovim ; Fem => tovot } ;
|
||||
Def => table { Masc => defH tovim ; Fem => defH tovot }
|
||||
}
|
||||
}
|
||||
} ;
|
||||
|
||||
regAdj : Str -> Adj = \tov ->
|
||||
case tov of { to + c@? =>
|
||||
adjective tov (to + replaceLastLetter (c) + "ה" ) (to + replaceLastLetter (c) +"ים" ) (to + replaceLastLetter (c) + "ות" )};
|
||||
|
||||
regAdj2 : Str -> Adj = \italki ->
|
||||
case italki of { italk+ c@? =>
|
||||
adjective italki (italk + replaceLastLetter (c) +"ת" ) (italk + replaceLastLetter (c)+ "ים" ) (italk + replaceLastLetter (c) + "ות" )};
|
||||
|
||||
} -- FoodsHeb
|
||||
75
testsuite/lpgf/foods/FoodsHin.gf
Normal file
75
testsuite/lpgf/foods/FoodsHin.gf
Normal file
@@ -0,0 +1,75 @@
|
||||
-- (c) 2010 Vikash Rauniyar under LGPL
|
||||
|
||||
concrete FoodsHin of Foods = {
|
||||
|
||||
flags coding=utf8 ;
|
||||
|
||||
param
|
||||
Gender = Masc | Fem ;
|
||||
Number = Sg | Pl ;
|
||||
lincat
|
||||
Comment = {s : Str} ;
|
||||
Item = {s : Str ; g : Gender ; n : Number} ;
|
||||
Kind = {s : Number => Str ; g : Gender} ;
|
||||
Quality = {s : Gender => Number => Str} ;
|
||||
lin
|
||||
Pred item quality = {
|
||||
s = item.s ++ quality.s ! item.g ! item.n ++ copula item.n
|
||||
} ;
|
||||
This kind = {s = "यह" ++ kind.s ! Sg ; g = kind.g ; n = Sg} ;
|
||||
That kind = {s = "वह" ++ kind.s ! Sg ; g = kind.g ; n = Sg} ;
|
||||
These kind = {s = "ये" ++ kind.s ! Pl ; g = kind.g ; n = Pl} ;
|
||||
Those kind = {s = "वे" ++ kind.s ! Pl ; g = kind.g ; n = Pl} ;
|
||||
Mod quality kind = {
|
||||
s = \\n => quality.s ! kind.g ! n ++ kind.s ! n ;
|
||||
g = kind.g
|
||||
} ;
|
||||
Wine = regN "मदिरा" ;
|
||||
Cheese = regN "पनीर" ;
|
||||
Fish = regN "मछली" ;
|
||||
Pizza = regN "पिज़्ज़ा" ;
|
||||
Very quality = {s = \\g,n => "अति" ++ quality.s ! g ! n} ;
|
||||
Fresh = regAdj "ताज़ा" ;
|
||||
Warm = regAdj "गरम" ;
|
||||
Italian = regAdj "इटली" ;
|
||||
Expensive = regAdj "बहुमूल्य" ;
|
||||
Delicious = regAdj "स्वादिष्ट" ;
|
||||
Boring = regAdj "अरुचिकर" ;
|
||||
|
||||
oper
|
||||
mkN : Str -> Str -> Gender -> {s : Number => Str ; g : Gender} =
|
||||
\s,p,g -> {
|
||||
s = table {
|
||||
Sg => s ;
|
||||
Pl => p
|
||||
} ;
|
||||
g = g
|
||||
} ;
|
||||
|
||||
regN : Str -> {s : Number => Str ; g : Gender} = \s -> case s of {
|
||||
lark + "ा" => mkN s (lark + "े") Masc ;
|
||||
lark + "ी" => mkN s (lark + "ीयँा") Fem ;
|
||||
_ => mkN s s Masc
|
||||
} ;
|
||||
|
||||
mkAdj : Str -> Str -> Str -> {s : Gender => Number => Str} = \ms,mp,f -> {
|
||||
s = table {
|
||||
Masc => table {
|
||||
Sg => ms ;
|
||||
Pl => mp
|
||||
} ;
|
||||
Fem => \\_ => f
|
||||
}
|
||||
} ;
|
||||
|
||||
regAdj : Str -> {s : Gender => Number => Str} = \a -> case a of {
|
||||
acch + "ा" => mkAdj a (acch + "े") (acch + "ी") ;
|
||||
_ => mkAdj a a a
|
||||
} ;
|
||||
|
||||
copula : Number -> Str = \n -> case n of {
|
||||
Sg => "है" ;
|
||||
Pl => "हैं"
|
||||
} ;
|
||||
|
||||
}
|
||||
29
testsuite/lpgf/foods/FoodsI.gf
Normal file
29
testsuite/lpgf/foods/FoodsI.gf
Normal file
@@ -0,0 +1,29 @@
|
||||
-- (c) 2009 Aarne Ranta under LGPL
|
||||
|
||||
incomplete concrete FoodsI of Foods =
|
||||
open Syntax, LexFoods in {
|
||||
lincat
|
||||
Comment = Utt ;
|
||||
Item = NP ;
|
||||
Kind = CN ;
|
||||
Quality = AP ;
|
||||
lin
|
||||
Pred item quality = mkUtt (mkCl item quality) ;
|
||||
This kind = mkNP this_Det kind ;
|
||||
That kind = mkNP that_Det kind ;
|
||||
These kind = mkNP these_Det kind ;
|
||||
Those kind = mkNP those_Det kind ;
|
||||
Mod quality kind = mkCN quality kind ;
|
||||
Very quality = mkAP very_AdA quality ;
|
||||
|
||||
Wine = mkCN wine_N ;
|
||||
Pizza = mkCN pizza_N ;
|
||||
Cheese = mkCN cheese_N ;
|
||||
Fish = mkCN fish_N ;
|
||||
Fresh = mkAP fresh_A ;
|
||||
Warm = mkAP warm_A ;
|
||||
Italian = mkAP italian_A ;
|
||||
Expensive = mkAP expensive_A ;
|
||||
Delicious = mkAP delicious_A ;
|
||||
Boring = mkAP boring_A ;
|
||||
}
|
||||
83
testsuite/lpgf/foods/FoodsIce.gf
Normal file
83
testsuite/lpgf/foods/FoodsIce.gf
Normal file
@@ -0,0 +1,83 @@
|
||||
|
||||
-- (c) 2009 Martha Dis Brandt under LGPL
|
||||
|
||||
concrete FoodsIce of Foods = open Prelude in {
|
||||
|
||||
flags coding=utf8;
|
||||
|
||||
lincat
|
||||
Comment = SS ;
|
||||
Quality = {s : Gender => Number => Defin => Str} ;
|
||||
Kind = {s : Number => Str ; g : Gender} ;
|
||||
Item = {s : Str ; g : Gender ; n : Number} ;
|
||||
|
||||
lin
|
||||
Pred item quality = ss (item.s ++ copula item.n ++ quality.s ! item.g ! item.n ! Ind) ;
|
||||
This, That = det Sg "þessi" "þessi" "þetta" ;
|
||||
These, Those = det Pl "þessir" "þessar" "þessi" ;
|
||||
Mod quality kind = { s = \\n => quality.s ! kind.g ! n ! Def ++ kind.s ! n ; g = kind.g } ;
|
||||
Wine = noun "vín" "vín" Neutr ;
|
||||
Cheese = noun "ostur" "ostar" Masc ;
|
||||
Fish = noun "fiskur" "fiskar" Masc ;
|
||||
-- the word "pizza" is more commonly used in Iceland, but "flatbaka" is the Icelandic word for it
|
||||
Pizza = noun "flatbaka" "flatbökur" Fem ;
|
||||
Very qual = {s = \\g,n,defOrInd => "mjög" ++ qual.s ! g ! n ! defOrInd } ;
|
||||
Fresh = regAdj "ferskur" ;
|
||||
Warm = regAdj "heitur" ;
|
||||
Boring = regAdj "leiðinlegur" ;
|
||||
-- the order of the given adj forms is: mSg fSg nSg mPl fPl nPl mSgDef f/nSgDef _PlDef
|
||||
Italian = adjective "ítalskur" "ítölsk" "ítalskt" "ítalskir" "ítalskar" "ítölsk" "ítalski" "ítalska" "ítalsku" ;
|
||||
Expensive = adjective "dýr" "dýr" "dýrt" "dýrir" "dýrar" "dýr" "dýri" "dýra" "dýru" ;
|
||||
Delicious = adjective "ljúffengur" "ljúffeng" "ljúffengt" "ljúffengir" "ljúffengar" "ljúffeng" "ljúffengi" "ljúffenga" "ljúffengu" ;
|
||||
|
||||
param
|
||||
Number = Sg | Pl ;
|
||||
Gender = Masc | Fem | Neutr ;
|
||||
Defin = Ind | Def ;
|
||||
|
||||
oper
|
||||
det : Number -> Str -> Str -> Str -> {s : Number => Str ; g : Gender} ->
|
||||
{s : Str ; g : Gender ; n : Number} =
|
||||
\n,masc,fem,neutr,cn -> {
|
||||
s = case cn.g of {Masc => masc ; Fem => fem; Neutr => neutr } ++ cn.s ! n ;
|
||||
g = cn.g ;
|
||||
n = n
|
||||
} ;
|
||||
|
||||
noun : Str -> Str -> Gender -> {s : Number => Str ; g : Gender} =
|
||||
\man,men,g -> {
|
||||
s = table {
|
||||
Sg => man ;
|
||||
Pl => men
|
||||
} ;
|
||||
g = g
|
||||
} ;
|
||||
|
||||
adjective : (x1,_,_,_,_,_,_,_,x9 : Str) -> {s : Gender => Number => Defin => Str} =
|
||||
\ferskur,fersk,ferskt,ferskir,ferskar,fersk_pl,ferski,ferska,fersku -> {
|
||||
s = \\g,n,t => case <g,n,t> of {
|
||||
< Masc, Sg, Ind > => ferskur ;
|
||||
< Masc, Pl, Ind > => ferskir ;
|
||||
< Fem, Sg, Ind > => fersk ;
|
||||
< Fem, Pl, Ind > => ferskar ;
|
||||
< Neutr, Sg, Ind > => ferskt ;
|
||||
< Neutr, Pl, Ind > => fersk_pl;
|
||||
< Masc, Sg, Def > => ferski ;
|
||||
< Fem, Sg, Def > | < Neutr, Sg, Def > => ferska ;
|
||||
< _ , Pl, Def > => fersku
|
||||
}
|
||||
} ;
|
||||
|
||||
regAdj : Str -> {s : Gender => Number => Defin => Str} = \ferskur ->
|
||||
let fersk = Predef.tk 2 ferskur
|
||||
in adjective
|
||||
ferskur fersk (fersk + "t")
|
||||
(fersk + "ir") (fersk + "ar") fersk
|
||||
(fersk + "i") (fersk + "a") (fersk + "u") ;
|
||||
|
||||
copula : Number -> Str =
|
||||
\n -> case n of {
|
||||
Sg => "er" ;
|
||||
Pl => "eru"
|
||||
} ;
|
||||
}
|
||||
7
testsuite/lpgf/foods/FoodsIta.gf
Normal file
7
testsuite/lpgf/foods/FoodsIta.gf
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
-- (c) 2009 Aarne Ranta under LGPL
|
||||
|
||||
concrete FoodsIta of Foods = FoodsI with
|
||||
(Syntax = SyntaxIta),
|
||||
(LexFoods = LexFoodsIta) ;
|
||||
|
||||
71
testsuite/lpgf/foods/FoodsJpn.gf
Normal file
71
testsuite/lpgf/foods/FoodsJpn.gf
Normal file
@@ -0,0 +1,71 @@
|
||||
|
||||
-- (c) 2009 Zofia Stankiewicz under LGPL
|
||||
|
||||
concrete FoodsJpn of Foods = open Prelude in {
|
||||
|
||||
flags coding=utf8 ;
|
||||
|
||||
lincat
|
||||
Comment = {s: Style => Str};
|
||||
Quality = {s: AdjUse => Str ; t: AdjType} ;
|
||||
Kind = {s : Number => Str} ;
|
||||
Item = {s : Str ; n : Number} ;
|
||||
|
||||
lin
|
||||
Pred item quality = {s = case quality.t of {
|
||||
IAdj => table {Plain => item.s ++ quality.s ! APred ; Polite => item.s ++ quality.s ! APred ++ copula ! Polite ! item.n } ;
|
||||
NaAdj => \\p => item.s ++ quality.s ! APred ++ copula ! p ! item.n }
|
||||
} ;
|
||||
This = det Sg "この" ;
|
||||
That = det Sg "その" ;
|
||||
These = det Pl "この" ;
|
||||
Those = det Pl "その" ;
|
||||
Mod quality kind = {s = \\n => quality.s ! Attr ++ kind.s ! n} ;
|
||||
Wine = regNoun "ワインは" ;
|
||||
Cheese = regNoun "チーズは" ;
|
||||
Fish = regNoun "魚は" ;
|
||||
Pizza = regNoun "ピザは" ;
|
||||
Very quality = {s = \\a => "とても" ++ quality.s ! a ; t = quality.t } ;
|
||||
Fresh = adj "新鮮な" "新鮮";
|
||||
Warm = regAdj "あたたかい" ;
|
||||
Italian = adj "イタリアの" "イタリアのもの";
|
||||
Expensive = regAdj "たかい" ;
|
||||
Delicious = regAdj "おいしい" ;
|
||||
Boring = regAdj "つまらない" ;
|
||||
|
||||
param
|
||||
Number = Sg | Pl ;
|
||||
AdjUse = Attr | APred ; -- na-adjectives have different forms as noun attributes and predicates
|
||||
Style = Plain | Polite ; -- for phrase types
|
||||
AdjType = IAdj | NaAdj ; -- IAdj can form predicates without the copula, NaAdj cannot
|
||||
|
||||
oper
|
||||
det : Number -> Str -> {s : Number => Str} -> {s : Str ; n : Number} =
|
||||
\n,d,cn -> {
|
||||
s = d ++ cn.s ! n ;
|
||||
n = n
|
||||
} ;
|
||||
noun : Str -> Str -> {s : Number => Str} =
|
||||
\sakana,sakana -> {s = \\_ => sakana } ;
|
||||
|
||||
regNoun : Str -> {s : Number => Str} =
|
||||
\sakana -> noun sakana sakana ;
|
||||
|
||||
adj : Str -> Str -> {s : AdjUse => Str ; t : AdjType} =
|
||||
\chosenna, chosen -> {
|
||||
s = table {
|
||||
Attr => chosenna ;
|
||||
APred => chosen
|
||||
} ;
|
||||
t = NaAdj
|
||||
} ;
|
||||
|
||||
regAdj : Str -> {s: AdjUse => Str ; t : AdjType} =\akai -> {
|
||||
s = \\_ => akai ; t = IAdj} ;
|
||||
|
||||
copula : Style => Number => Str =
|
||||
table {
|
||||
Plain => \\_ => "だ" ;
|
||||
Polite => \\_ => "です" } ;
|
||||
|
||||
}
|
||||
76
testsuite/lpgf/foods/FoodsLat.gf
Normal file
76
testsuite/lpgf/foods/FoodsLat.gf
Normal file
@@ -0,0 +1,76 @@
|
||||
--# -path=.:present
|
||||
|
||||
-- (c) 2009 Aarne Ranta under LGPL
|
||||
|
||||
concrete FoodsLat of Foods = LexFoodsLat **
|
||||
{
|
||||
lincat
|
||||
Comment = { s : Str } ;
|
||||
Item = { number : Number ; gender : Gender; noun : Str; adj : Str; det : Str };
|
||||
lin
|
||||
Mod quality kind =
|
||||
variants {
|
||||
{
|
||||
gender = kind.gender ;
|
||||
noun = table { number => kind.noun ! number ++ quality.s ! number ! kind.gender } ;
|
||||
adj = kind.adj
|
||||
} ;
|
||||
{
|
||||
gender = kind.gender ;
|
||||
noun = kind.noun ;
|
||||
adj = table { number => kind.adj ! number ++ quality.s ! number ! kind.gender }
|
||||
} ;
|
||||
{
|
||||
gender = kind.gender ;
|
||||
noun = table { number => quality.s ! number ! kind.gender ++ kind.noun ! number } ;
|
||||
adj = kind.adj
|
||||
} ;
|
||||
{
|
||||
gender = kind.gender ;
|
||||
noun = kind.noun ;
|
||||
adj = table { number => quality.s ! number ! kind.gender ++ kind.adj ! number }
|
||||
}
|
||||
};
|
||||
Pred item quality =
|
||||
let aux : Number => Str =
|
||||
table { Sg => "est" ; Pl => "sunt" } ;
|
||||
in
|
||||
{
|
||||
s = variants {
|
||||
item.det ++ item.noun ++ item.adj ++ aux ! item.number ++ quality.s ! item.number ! item.gender ;
|
||||
item.det ++ item.adj ++ item.noun ++ aux ! item.number ++ quality.s ! item.number ! item.gender ;
|
||||
item.det ++ item.noun ++ item.adj ++ quality.s ! item.number ! item.gender ++ aux ! item.number ;
|
||||
item.det ++ item.adj ++ item.noun ++ quality.s ! item.number ! item.gender ++ aux ! item.number
|
||||
};
|
||||
};
|
||||
This kind = {
|
||||
number = Sg ;
|
||||
gender = kind.gender ;
|
||||
noun = kind.noun ! Sg ;
|
||||
adj = kind.adj ! Sg ;
|
||||
det = table { Male => "hic" ; Female => "haec" ; Neuter => "hoc" } ! kind.gender
|
||||
} ;
|
||||
These kind = {
|
||||
number = Pl ;
|
||||
gender = kind.gender ;
|
||||
noun = kind.noun ! Pl ;
|
||||
adj = kind.adj ! Pl ;
|
||||
det = table { Male => "hi" ; Female => "hae" ; Neuter => "haec" } ! kind.gender
|
||||
} ;
|
||||
That kind = {
|
||||
number = Sg ;
|
||||
gender = kind.gender ;
|
||||
noun = kind.noun ! Sg ;
|
||||
adj = kind.adj ! Sg ;
|
||||
det = table { Male => "is" ; Female => "ea" ; Neuter => "id" } ! kind.gender
|
||||
} ;
|
||||
Those kind = {
|
||||
number = Pl ;
|
||||
gender = kind.gender ;
|
||||
noun = kind.noun ! Pl ;
|
||||
adj = kind.adj ! Pl ;
|
||||
det = table { Male => variants { "ei "; "ii" } ; Female => "eae" ; Neuter => "ea" } ! kind.gender
|
||||
} ;
|
||||
Very quality = { s = \\n,g => "valde" ++ quality.s ! n ! g };
|
||||
}
|
||||
|
||||
90
testsuite/lpgf/foods/FoodsLav.gf
Normal file
90
testsuite/lpgf/foods/FoodsLav.gf
Normal file
@@ -0,0 +1,90 @@
|
||||
|
||||
-- (c) 2009 Inese Bernsone under LGPL
|
||||
|
||||
concrete FoodsLav of Foods = open Prelude in {
|
||||
|
||||
flags
|
||||
coding=utf8 ;
|
||||
|
||||
lincat
|
||||
Comment = SS ;
|
||||
Quality = {s : Q => Gender => Number => Defin => Str } ;
|
||||
Kind = {s : Number => Str ; g : Gender} ;
|
||||
Item = {s : Str ; g : Gender ; n : Number } ;
|
||||
|
||||
lin
|
||||
Pred item quality = ss (item.s ++ {- copula item.n -} "ir" ++ quality.s ! Q1 ! item.g ! item.n ! Ind ) ;
|
||||
This = det Sg "šis" "šī" ;
|
||||
That = det Sg "tas" "tā" ;
|
||||
These = det Pl "šie" "šīs" ;
|
||||
Those = det Pl "tie" "tās" ;
|
||||
Mod quality kind = {s = \\n => quality.s ! Q1 ! kind.g ! n ! Def ++ kind.s ! n ; g = kind.g } ;
|
||||
Wine = noun "vīns" "vīni" Masc ;
|
||||
Cheese = noun "siers" "sieri" Masc ;
|
||||
Fish = noun "zivs" "zivis" Fem ;
|
||||
Pizza = noun "pica" "picas" Fem ;
|
||||
Very qual = {s = \\q,g,n,spec => "ļoti" ++ qual.s ! Q2 ! g ! n ! spec };
|
||||
|
||||
Fresh = adjective "svaigs" "svaiga" "svaigi" "svaigas" "svaigais" "svaigā" "svaigie" "svaigās" ;
|
||||
Warm = regAdj "silts" ;
|
||||
Italian = specAdj "itāļu" (regAdj "itālisks") ;
|
||||
Expensive = regAdj "dārgs" ;
|
||||
Delicious = regAdj "garšīgs" ;
|
||||
Boring = regAdj "garlaicīgs" ;
|
||||
|
||||
param
|
||||
Number = Sg | Pl ;
|
||||
Gender = Masc | Fem ;
|
||||
Defin = Ind | Def ;
|
||||
Q = Q1 | Q2 ;
|
||||
|
||||
oper
|
||||
det : Number -> Str -> Str -> {s : Number => Str ; g : Gender} ->
|
||||
{s : Str ; g : Gender ; n : Number} =
|
||||
\n,m,f,cn -> {
|
||||
s = case cn.g of {Masc => m ; Fem => f} ++ cn.s ! n ;
|
||||
g = cn.g ;
|
||||
n = n
|
||||
} ;
|
||||
noun : Str -> Str -> Gender -> {s : Number => Str ; g : Gender} =
|
||||
\man,men,g -> {
|
||||
s = table {
|
||||
Sg => man ;
|
||||
Pl => men
|
||||
} ;
|
||||
g = g
|
||||
} ;
|
||||
adjective : (_,_,_,_,_,_,_,_ : Str) -> {s : Q => Gender => Number => Defin => Str} =
|
||||
\skaists,skaista,skaisti,skaistas,skaistais,skaistaa,skaistie,skaistaas -> {
|
||||
s = table {
|
||||
_ => table {
|
||||
Masc => table {
|
||||
Sg => table {Ind => skaists ; Def => skaistais} ;
|
||||
Pl => table {Ind => skaisti ; Def => skaistie}
|
||||
} ;
|
||||
Fem => table {
|
||||
Sg => table {Ind => skaista ; Def => skaistaa} ;
|
||||
Pl => table {Ind => skaistas ; Def => skaistaas}
|
||||
}
|
||||
}
|
||||
}
|
||||
} ;
|
||||
|
||||
{- irregAdj : Str -> {s : Gender => Number => Defin => Str} = \itaalju ->
|
||||
let itaalju = itaalju
|
||||
in adjective itaalju (itaalju) (itaalju) (itaalju) (itaalju) (itaalju) (itaalju) (itaalju) ; -}
|
||||
|
||||
regAdj : Str -> {s : Q => Gender => Number => Defin => Str} = \skaists ->
|
||||
let skaist = init skaists
|
||||
in adjective skaists (skaist + "a") (skaist + "i") (skaist + "as") (skaist + "ais") (skaist + "ā") (skaist + "ie") (skaist + "ās");
|
||||
|
||||
Adjective : Type = {s : Q => Gender => Number => Defin => Str} ;
|
||||
|
||||
specAdj : Str -> Adjective -> Adjective = \s,a -> {
|
||||
s = table {
|
||||
Q2 => a.s ! Q1 ;
|
||||
Q1 => \\_,_,_ => s
|
||||
}
|
||||
} ;
|
||||
|
||||
}
|
||||
120
testsuite/lpgf/foods/FoodsMkd.gf
Normal file
120
testsuite/lpgf/foods/FoodsMkd.gf
Normal file
@@ -0,0 +1,120 @@
|
||||
-- (c) 2009 Krasimir Angelov under LGPL
|
||||
|
||||
concrete FoodsMkd of Foods = {
|
||||
|
||||
flags coding = utf8 ;
|
||||
|
||||
lincat
|
||||
Comment = Str;
|
||||
Quality = {s : Agr => Str};
|
||||
Item = {s : Str; a : Agr};
|
||||
Kind = {s : Number => Str; g : Gender};
|
||||
|
||||
lin
|
||||
Pred item qual =
|
||||
item.s ++
|
||||
case item.a of {
|
||||
ASg _ => "е";
|
||||
APl => "се"
|
||||
} ++
|
||||
qual.s ! item.a;
|
||||
This kind = {
|
||||
s = case kind.g of {
|
||||
Masc => "овоj";
|
||||
Fem => "оваа";
|
||||
Neutr => "ова"
|
||||
} ++
|
||||
kind.s ! Sg;
|
||||
a = ASg kind.g};
|
||||
That kind = {
|
||||
s = case kind.g of {
|
||||
Masc => "оноj";
|
||||
Fem => "онаа";
|
||||
Neutr => "она"
|
||||
} ++
|
||||
kind.s ! Sg;
|
||||
a = ASg kind.g};
|
||||
These kind = {s = "овие" ++ kind.s ! Pl; a = APl};
|
||||
Those kind = {s = "оние" ++ kind.s ! Pl; a = APl};
|
||||
Mod qual kind = {
|
||||
s = \\n => qual.s ! case n of {
|
||||
Sg => ASg kind.g;
|
||||
Pl => APl
|
||||
} ++
|
||||
kind.s ! n;
|
||||
g = kind.g};
|
||||
Wine = {
|
||||
s = table {
|
||||
Sg => "вино";
|
||||
Pl => "вина"
|
||||
};
|
||||
g = Neutr};
|
||||
Cheese = {
|
||||
s = table {
|
||||
Sg => "сирење";
|
||||
Pl => "сирењa"
|
||||
};
|
||||
g = Neutr};
|
||||
Fish = {
|
||||
s = table {
|
||||
Sg => "риба";
|
||||
Pl => "риби"
|
||||
};
|
||||
g = Fem};
|
||||
Pizza = {
|
||||
s = table {
|
||||
Sg => "пица";
|
||||
Pl => "пици"
|
||||
};
|
||||
g = Fem
|
||||
};
|
||||
Very qual = {s = \\g => "многу" ++ qual.s ! g};
|
||||
Fresh = {
|
||||
s = table {
|
||||
ASg Masc => "свеж";
|
||||
ASg Fem => "свежа";
|
||||
ASg Neutr => "свежо";
|
||||
APl => "свежи"}
|
||||
};
|
||||
Warm = {
|
||||
s = table {
|
||||
ASg Masc => "топол";
|
||||
ASg Fem => "топла";
|
||||
ASg Neutr => "топло";
|
||||
APl => "топли"}
|
||||
};
|
||||
Italian = {
|
||||
s = table {
|
||||
ASg Masc => "италијански";
|
||||
ASg Fem => "италијанска";
|
||||
ASg Neutr => "италијанско";
|
||||
APl => "италијански"}
|
||||
};
|
||||
Expensive = {
|
||||
s = table {
|
||||
ASg Masc => "скап";
|
||||
ASg Fem => "скапа";
|
||||
ASg Neutr => "скапо";
|
||||
APl => "скапи"}
|
||||
};
|
||||
Delicious = {
|
||||
s = table {
|
||||
ASg Masc => "вкусен";
|
||||
ASg Fem => "вкусна";
|
||||
ASg Neutr => "вкусно";
|
||||
APl => "вкусни"}
|
||||
};
|
||||
Boring = {
|
||||
s = table {
|
||||
ASg Masc => "досаден";
|
||||
ASg Fem => "досадна";
|
||||
ASg Neutr => "досадно";
|
||||
APl => "досадни"}
|
||||
};
|
||||
|
||||
param
|
||||
Gender = Masc | Fem | Neutr;
|
||||
Number = Sg | Pl;
|
||||
Agr = ASg Gender | APl;
|
||||
|
||||
}
|
||||
105
testsuite/lpgf/foods/FoodsMlt.gf
Normal file
105
testsuite/lpgf/foods/FoodsMlt.gf
Normal file
@@ -0,0 +1,105 @@
|
||||
-- (c) 2013 John J. Camilleri under LGPL
|
||||
|
||||
concrete FoodsMlt of Foods = open Prelude in {
|
||||
flags coding=utf8 ;
|
||||
|
||||
lincat
|
||||
Comment = SS ;
|
||||
Quality = {s : Gender => Number => Str} ;
|
||||
Kind = {s : Number => Str ; g : Gender} ;
|
||||
Item = {s : Str ; g : Gender ; n : Number} ;
|
||||
|
||||
lin
|
||||
-- Pred item quality = ss (item.s ++ copula item.n item.g ++ quality.s ! item.g ! item.n) ;
|
||||
Pred item quality = ss (item.s ++ quality.s ! item.g ! item.n) ;
|
||||
|
||||
This kind = det Sg "dan" "din" kind ;
|
||||
That kind = det Sg "dak" "dik" kind ;
|
||||
These kind = det Pl "dawn" "" kind ;
|
||||
Those kind = det Pl "dawk" "" kind ;
|
||||
|
||||
Mod quality kind = {
|
||||
s = \\n => kind.s ! n ++ quality.s ! kind.g ! n ;
|
||||
g = kind.g
|
||||
} ;
|
||||
|
||||
Wine = noun "inbid" "inbejjed" Masc ;
|
||||
Cheese = noun "ġobon" "ġobniet" Masc ;
|
||||
Fish = noun "ħuta" "ħut" Fem ;
|
||||
Pizza = noun "pizza" "pizzez" Fem ;
|
||||
|
||||
Very qual = {s = \\g,n => qual.s ! g ! n ++ "ħafna"} ;
|
||||
|
||||
Warm = adjective "sħun" "sħuna" "sħan" ;
|
||||
Expensive = adjective "għali" "għalja" "għaljin" ;
|
||||
Delicious = adjective "tajjeb" "tajba" "tajbin" ;
|
||||
Boring = uniAdj "tad-dwejjaq" ;
|
||||
Fresh = regAdj "frisk" ;
|
||||
Italian = regAdj "Taljan" ;
|
||||
|
||||
param
|
||||
Number = Sg | Pl ;
|
||||
Gender = Masc | Fem ;
|
||||
|
||||
oper
|
||||
--Create an adjective (full function)
|
||||
--Params: Sing Masc, Sing Fem, Plural
|
||||
adjective : (_,_,_ : Str) -> {s : Gender => Number => Str} = \iswed,sewda,suwed -> {
|
||||
s = table {
|
||||
Masc => table {
|
||||
Sg => iswed ;
|
||||
Pl => suwed
|
||||
} ;
|
||||
Fem => table {
|
||||
Sg => sewda ;
|
||||
Pl => suwed
|
||||
}
|
||||
}
|
||||
} ;
|
||||
|
||||
--Create a regular adjective
|
||||
--Param: Sing Masc
|
||||
regAdj : Str -> {s : Gender => Number => Str} = \frisk ->
|
||||
adjective frisk (frisk + "a") (frisk + "i") ;
|
||||
|
||||
--Create a "uni-adjective" eg tal-buzz
|
||||
--Param: Sing Masc
|
||||
uniAdj : Str -> {s : Gender => Number => Str} = \uni ->
|
||||
adjective uni uni uni ;
|
||||
|
||||
--Create a noun
|
||||
--Params: Singular, Plural, Gender (inherent)
|
||||
noun : Str -> Str -> Gender -> {s : Number => Str ; g : Gender} = \ktieb,kotba,g -> {
|
||||
s = table {
|
||||
Sg => ktieb ;
|
||||
Pl => kotba
|
||||
} ;
|
||||
g = g
|
||||
} ;
|
||||
|
||||
--Copula is a linking verb
|
||||
--Params: Number, Gender
|
||||
-- copula : Number -> Gender -> Str = \n,g -> case n of {
|
||||
-- Sg => case g of { Masc => "huwa" ; Fem => "hija" } ;
|
||||
-- Pl => "huma"
|
||||
-- } ;
|
||||
|
||||
--Create an article, taking into account first letter of next word
|
||||
article = pre {
|
||||
"a"|"e"|"i"|"o"|"u" => "l-" ;
|
||||
--cons@("ċ"|"d"|"n"|"r"|"s"|"t"|"x"|"ż") => "i" + cons + "-" ;
|
||||
_ => "il-"
|
||||
} ;
|
||||
|
||||
--Create a determinant
|
||||
--Params: Sg/Pl, Masc, Fem
|
||||
det : Number -> Str -> Str -> {s : Number => Str ; g : Gender} -> {s : Str ; g : Gender ; n : Number} = \n,m,f,cn -> {
|
||||
s = case n of {
|
||||
Sg => case cn.g of {Masc => m ; Fem => f}; --string
|
||||
Pl => m --default to masc
|
||||
} ++ article ++ cn.s ! n ;
|
||||
g = cn.g ; --gender
|
||||
n = n --number
|
||||
} ;
|
||||
|
||||
}
|
||||
48
testsuite/lpgf/foods/FoodsMon.gf
Normal file
48
testsuite/lpgf/foods/FoodsMon.gf
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
-- (c) 2009 Nyamsuren Erdenebadrakh under LGPL
|
||||
|
||||
concrete FoodsMon of Foods = open Prelude in {
|
||||
flags coding=utf8;
|
||||
|
||||
lincat
|
||||
Comment, Quality = SS ;
|
||||
Kind = {s : Number => Str} ;
|
||||
Item = {s : Str ; n : Number} ;
|
||||
|
||||
lin
|
||||
Pred item quality = ss (item.s ++ "бол" ++ quality.s) ;
|
||||
This = det Sg "энэ" ;
|
||||
That = det Sg "тэр" ;
|
||||
These = det Pl "эдгээр" ;
|
||||
Those = det Pl "тэдгээр" ;
|
||||
Mod quality kind = {s = \\n => quality.s ++ kind.s ! n} ;
|
||||
Wine = regNoun "дарс" ;
|
||||
Cheese = regNoun "бяслаг" ;
|
||||
Fish = regNoun "загас" ;
|
||||
Pizza = regNoun "пицца" ;
|
||||
Very = prefixSS "маш" ;
|
||||
Fresh = ss "шинэ" ;
|
||||
Warm = ss "халуун" ;
|
||||
Italian = ss "итали" ;
|
||||
Expensive = ss "үнэтэй" ;
|
||||
Delicious = ss "амттай" ;
|
||||
Boring = ss "амтгүй" ;
|
||||
|
||||
param
|
||||
Number = Sg | Pl ;
|
||||
|
||||
oper
|
||||
det : Number -> Str -> {s : Number => Str} -> {s : Str ; n : Number} =
|
||||
\n,d,cn -> {
|
||||
s = d ++ cn.s ! n ;
|
||||
n = n
|
||||
} ;
|
||||
|
||||
regNoun : Str -> {s : Number => Str} =
|
||||
\x -> {s = table {
|
||||
Sg => x ;
|
||||
Pl => x + "нууд"}
|
||||
} ;
|
||||
}
|
||||
|
||||
|
||||
60
testsuite/lpgf/foods/FoodsNep.gf
Normal file
60
testsuite/lpgf/foods/FoodsNep.gf
Normal file
@@ -0,0 +1,60 @@
|
||||
-- (c) 2011 Dinesh Simkhada under LGPL
|
||||
|
||||
concrete FoodsNep of Foods = {
|
||||
|
||||
flags coding = utf8 ;
|
||||
|
||||
lincat
|
||||
Comment, Quality = {s : Str} ;
|
||||
Kind = {s : Number => Str} ;
|
||||
Item = {s : Str ; n : Number} ;
|
||||
|
||||
lin
|
||||
Pred item quality =
|
||||
{s = item.s ++ quality.s ++ copula ! item.n} ;
|
||||
|
||||
This = det Sg "यो" ;
|
||||
That = det Sg "त्यो" ;
|
||||
These = det Pl "यी" ;
|
||||
Those = det Pl "ती" ;
|
||||
Mod quality kind =
|
||||
{s = \\n => quality.s ++ kind.s ! n} ;
|
||||
|
||||
Wine = regNoun "रक्सी" ;
|
||||
Cheese = regNoun "चिज" ;
|
||||
Fish = regNoun "माछा" ;
|
||||
Pizza = regNoun "पिज्जा" ;
|
||||
Very a = {s = "धेरै" ++ a.s} ;
|
||||
Fresh = adj "ताजा" ;
|
||||
Warm = adj "तातो" ;
|
||||
Italian = adj "इटालियन" ;
|
||||
Expensive = adj "महँगो" | adj "बहुमूल्य" ;
|
||||
Delicious = adj "स्वादिष्ट" | adj "मीठो" ;
|
||||
Boring = adjPl "नमिठो" ;
|
||||
|
||||
param
|
||||
Number = Sg | Pl ;
|
||||
|
||||
oper
|
||||
det : Number -> Str ->
|
||||
{s : Number => Str} -> {s : Str ; n : Number} =
|
||||
\n,det,noun -> {s = det ++ noun.s ! n ; n = n} ;
|
||||
|
||||
noun : Str -> Str -> {s : Number => Str} =
|
||||
\man,men -> {s = table {Sg => man ; Pl => men}} ;
|
||||
|
||||
regNoun : Str -> {s : Number => Str} =
|
||||
\car -> noun car (car + "हरु") ;
|
||||
|
||||
adjPl : Str -> {s : Str} = \a -> case a of {
|
||||
bor + "ठो" => adj (bor + "ठा") ;
|
||||
_ => adj a
|
||||
} ;
|
||||
|
||||
adj : Str -> {s : Str} =
|
||||
\cold -> {s = cold} ;
|
||||
|
||||
copula : Number => Str =
|
||||
table {Sg => "छ" ; Pl => "छन्"} ;
|
||||
}
|
||||
|
||||
30
testsuite/lpgf/foods/FoodsOri.gf
Normal file
30
testsuite/lpgf/foods/FoodsOri.gf
Normal file
@@ -0,0 +1,30 @@
|
||||
concrete FoodsOri of Foods = {
|
||||
|
||||
flags coding = utf8 ;
|
||||
|
||||
lincat
|
||||
Comment = Str;
|
||||
Item = Str;
|
||||
Kind = Str;
|
||||
Quality = Str;
|
||||
|
||||
lin
|
||||
Pred item quality = item ++ quality ++ "ଅଟେ";
|
||||
This kind = "ଏଇ" ++ kind;
|
||||
That kind = "ସେଇ" ++ kind;
|
||||
These kind = "ଏଇ" ++ kind ++ "ଗୁଡିକ" ;
|
||||
Those kind = "ସେଇ" ++ kind ++ "ଗୁଡିକ" ;
|
||||
Mod quality kind = quality ++ kind;
|
||||
Wine = "ମଦ";
|
||||
Cheese = "ଛେନା";
|
||||
Fish = "ମାଛ";
|
||||
Pizza = "ପିଜଜ଼ା" ;
|
||||
Very quality = "ଅତି" ++ quality;
|
||||
Fresh = "ତାଜା";
|
||||
Warm = "ଗରମ";
|
||||
Italian = "ଇଟାଲି";
|
||||
Expensive = "ମୁଲ୍ୟବାନ୍";
|
||||
Delicious = "ସ୍ଵାଦିସ୍ଟ ";
|
||||
Boring = "ଅରୁଚିକର";
|
||||
|
||||
}
|
||||
65
testsuite/lpgf/foods/FoodsPes.gf
Normal file
65
testsuite/lpgf/foods/FoodsPes.gf
Normal file
@@ -0,0 +1,65 @@
|
||||
concrete FoodsPes of Foods = {
|
||||
|
||||
flags optimize=noexpand ; coding=utf8 ;
|
||||
|
||||
lincat
|
||||
Comment = {s : Str} ;
|
||||
Quality = {s : Add => Str; prep : Str} ;
|
||||
Kind = {s : Add => Number => Str ; prep : Str};
|
||||
Item = {s : Str ; n : Number};
|
||||
lin
|
||||
Pred item quality = {s = item.s ++ quality.s ! Indep ++ copula ! item.n} ;
|
||||
This = det Sg "این" ;
|
||||
That = det Sg "آن" ;
|
||||
These = det Pl "این" ;
|
||||
Those = det Pl "آن" ;
|
||||
|
||||
Mod quality kind = {s = \\a,n => kind.s ! Attr ! n ++ kind.prep ++ quality.s ! a ;
|
||||
prep = quality.prep
|
||||
};
|
||||
Wine = regN "شراب" ;
|
||||
Cheese = regN "پنیر" ;
|
||||
Fish = regN "ماهى" ;
|
||||
Pizza = regN "پیتزا" ;
|
||||
Very a = {s = \\at => "خیلی" ++ a.s ! at ; prep = a.prep} ;
|
||||
Fresh = adj "تازه" ;
|
||||
Warm = adj "گرم" ;
|
||||
Italian = adj "ایتالیایی" ;
|
||||
Expensive = adj "گران" ;
|
||||
Delicious = adj "لذىذ" ;
|
||||
Boring = adj "ملال آور" ; -- it must be written as ملال آور.
|
||||
|
||||
param
|
||||
Number = Sg | Pl ;
|
||||
Add = Indep | Attr ;
|
||||
oper
|
||||
det : Number -> Str -> {s: Add => Number => Str ; prep : Str} -> {s : Str ; n: Number} =
|
||||
\n,det,noun -> {s = det ++ noun.s ! Indep ! n ; n = n };
|
||||
|
||||
noun : (x1,_,_,x4 : Str) -> {s : Add => Number => Str ; prep : Str} = \pytzA, pytzAy, pytzAhA,pr ->
|
||||
{s = \\a,n => case <a,n> of
|
||||
{<Indep,Sg> => pytzA ; <Indep,Pl> => pytzAhA ;
|
||||
<Attr,Sg> =>pytzA ; <Attr,Pl> => pytzAhA + "ى" };
|
||||
prep = pr
|
||||
};
|
||||
|
||||
regN : Str -> {s: Add => Number => Str ; prep : Str} = \mrd ->
|
||||
case mrd of
|
||||
{ _ + ("ا"|"ه"|"ى"|"و"|"") => noun mrd (mrd+"ى") (mrd + "ها") "";
|
||||
_ => noun mrd mrd (mrd + "ها") "e"
|
||||
};
|
||||
|
||||
adj : Str -> {s : Add => Str; prep : Str} = \tAzh ->
|
||||
case tAzh of
|
||||
{ _ + ("ا"|"ه"|"ى"|"و"|"") => mkAdj tAzh (tAzh ++ "ى") "" ;
|
||||
_ => mkAdj tAzh tAzh "ه"
|
||||
};
|
||||
|
||||
mkAdj : Str -> Str -> Str -> {s : Add => Str; prep : Str} = \tAzh, tAzhy, pr ->
|
||||
{s = table {Indep => tAzh;
|
||||
Attr => tAzhy};
|
||||
prep = pr
|
||||
};
|
||||
copula : Number => Str = table {Sg => "است"; Pl => "هستند"};
|
||||
|
||||
}
|
||||
78
testsuite/lpgf/foods/FoodsPor.gf
Normal file
78
testsuite/lpgf/foods/FoodsPor.gf
Normal file
@@ -0,0 +1,78 @@
|
||||
-- (c) 2009 Rami Shashati under LGPL
|
||||
--# -coding=latin1
|
||||
|
||||
concrete FoodsPor of Foods = open Prelude in {
|
||||
lincat
|
||||
Comment = {s : Str} ;
|
||||
Quality = {s : Gender => Number => Str} ;
|
||||
Kind = {s : Number => Str ; g : Gender} ;
|
||||
Item = {s : Str ; n : Number ; g : Gender } ;
|
||||
|
||||
lin
|
||||
Pred item quality =
|
||||
{s = item.s ++ copula ! item.n ++ quality.s ! item.g ! item.n } ;
|
||||
This = det Sg (table {Masc => "este" ; Fem => "esta"}) ;
|
||||
That = det Sg (table {Masc => "esse" ; Fem => "essa"}) ;
|
||||
These = det Pl (table {Masc => "estes" ; Fem => "estas"}) ;
|
||||
Those = det Pl (table {Masc => "esses" ; Fem => "essas"}) ;
|
||||
|
||||
Mod quality kind = { s = \\n => kind.s ! n ++ quality.s ! kind.g ! n ; g = kind.g } ;
|
||||
|
||||
Wine = regNoun "vinho" Masc ;
|
||||
Cheese = regNoun "queijo" Masc ;
|
||||
Fish = regNoun "peixe" Masc ;
|
||||
Pizza = regNoun "pizza" Fem ;
|
||||
|
||||
Very a = { s = \\g,n => "muito" ++ a.s ! g ! n } ;
|
||||
|
||||
Fresh = mkAdjReg "fresco" ;
|
||||
Warm = mkAdjReg "quente" ;
|
||||
Italian = mkAdjReg "Italiano" ;
|
||||
Expensive = mkAdjReg "caro" ;
|
||||
Delicious = mkAdjReg "delicioso" ;
|
||||
Boring = mkAdjReg "chato" ;
|
||||
|
||||
param
|
||||
Number = Sg | Pl ;
|
||||
Gender = Masc | Fem ;
|
||||
|
||||
oper
|
||||
QualityT : Type = {s : Gender => Number => Str} ;
|
||||
|
||||
mkAdj : (_,_,_,_ : Str) -> QualityT = \bonito,bonita,bonitos,bonitas -> {
|
||||
s = table {
|
||||
Masc => table { Sg => bonito ; Pl => bonitos } ;
|
||||
Fem => table { Sg => bonita ; Pl => bonitas }
|
||||
} ;
|
||||
} ;
|
||||
|
||||
-- regular pattern
|
||||
adjSozinho : Str -> QualityT = \sozinho ->
|
||||
let sozinh = Predef.tk 1 sozinho
|
||||
in mkAdj sozinho (sozinh + "a") (sozinh + "os") (sozinh + "as") ;
|
||||
|
||||
-- for gender-independent adjectives
|
||||
adjUtil : Str -> Str -> QualityT = \util,uteis ->
|
||||
mkAdj util util uteis uteis ;
|
||||
|
||||
-- smart paradigm for adjcetives
|
||||
mkAdjReg : Str -> QualityT = \a -> case last a of {
|
||||
"o" => adjSozinho a ;
|
||||
"e" => adjUtil a (a + "s")
|
||||
} ;
|
||||
|
||||
ItemT : Type = {s : Str ; n : Number ; g : Gender } ;
|
||||
|
||||
det : Number -> (Gender => Str) -> KindT -> ItemT =
|
||||
\num,det,noun -> {s = det ! noun.g ++ noun.s ! num ; n = num ; g = noun.g } ;
|
||||
|
||||
KindT : Type = {s : Number => Str ; g : Gender} ;
|
||||
|
||||
noun : Str -> Str -> Gender -> KindT =
|
||||
\animal,animais,gen -> {s = table {Sg => animal ; Pl => animais} ; g = gen } ;
|
||||
|
||||
regNoun : Str -> Gender -> KindT =
|
||||
\carro,gen -> noun carro (carro + "s") gen ;
|
||||
|
||||
copula : Number => Str = table {Sg => "é" ; Pl => "são"} ;
|
||||
}
|
||||
72
testsuite/lpgf/foods/FoodsRon.gf
Normal file
72
testsuite/lpgf/foods/FoodsRon.gf
Normal file
@@ -0,0 +1,72 @@
|
||||
-- (c) 2009 Ramona Enache under LGPL
|
||||
|
||||
concrete FoodsRon of Foods =
|
||||
{
|
||||
flags coding=utf8 ;
|
||||
|
||||
param Number = Sg | Pl ;
|
||||
Gender = Masc | Fem ;
|
||||
NGender = NMasc | NFem | NNeut ;
|
||||
lincat
|
||||
Comment = {s : Str};
|
||||
Quality = {s : Number => Gender => Str};
|
||||
Kind = {s : Number => Str; g : NGender};
|
||||
Item = {s : Str ; n : Number; g : Gender};
|
||||
|
||||
lin
|
||||
|
||||
This = det Sg (mkTab "acest" "această");
|
||||
That = det Sg (mkTab "acel" "acea");
|
||||
These = det Pl (mkTab "acești" "aceste");
|
||||
Those = det Pl (mkTab "acei" "acele");
|
||||
|
||||
Wine = mkNoun "vin" "vinuri" NNeut ;
|
||||
Cheese = mkNoun "brânză" "brânzeturi" NFem ;
|
||||
Fish = mkNoun "peşte" "peşti" NMasc ;
|
||||
Pizza = mkNoun "pizza" "pizze" NFem;
|
||||
|
||||
Very a = {s = \\n,g => "foarte" ++ a.s ! n ! g};
|
||||
|
||||
Fresh = mkAdj "proaspăt" "proaspătă" "proaspeţi" "proaspete" ;
|
||||
Warm = mkAdj "cald" "caldă" "calzi" "calde" ;
|
||||
Italian = mkAdj "italian" "italiană" "italieni" "italiene" ;
|
||||
Expensive = mkAdj "scump" "scumpă" "scumpi" "scumpe" ;
|
||||
Delicious = mkAdj "delicios" "delcioasă" "delicioşi" "delicioase" ;
|
||||
Boring = mkAdj "plictisitor" "plictisitoare" "plictisitori" "plictisitoare" ;
|
||||
|
||||
Pred item quality = {s = item.s ++ copula ! item.n ++ quality.s ! item.n ! item.g} ;
|
||||
|
||||
Mod quality kind = {s = \\n => kind.s ! n ++ quality.s ! n ! (getAgrGender kind.g n) ; g = kind.g};
|
||||
|
||||
oper
|
||||
|
||||
mkTab : Str -> Str -> {s : Gender => Str} = \acesta, aceasta ->
|
||||
{s = table{Masc => acesta;
|
||||
Fem => aceasta}};
|
||||
|
||||
det : Number -> {s : Gender => Str} -> {s : Number => Str ; g : NGender} -> {s : Str; n : Number; g : Gender} =
|
||||
\n,det,noun -> let gg = getAgrGender noun.g n
|
||||
in
|
||||
{s = det.s ! gg ++ noun.s ! n ; n = n ; g = gg};
|
||||
|
||||
mkNoun : Str -> Str -> NGender -> {s : Number => Str; g : NGender} = \peste, pesti,g ->
|
||||
{s = table {Sg => peste;
|
||||
Pl => pesti};
|
||||
g = g
|
||||
};
|
||||
|
||||
oper mkAdj : (x1,_,_,x4 : Str) -> {s : Number => Gender => Str} = \scump, scumpa, scumpi, scumpe ->
|
||||
{s = \\n,g => case <n,g> of
|
||||
{<Sg,Masc> => scump ; <Sg,Fem> => scumpa;
|
||||
<Pl,Masc> => scumpi ; <Pl,Fem> => scumpe
|
||||
}};
|
||||
|
||||
copula : Number => Str = table {Sg => "este" ; Pl => "sunt"};
|
||||
|
||||
getAgrGender : NGender -> Number -> Gender = \ng,n ->
|
||||
case <ng,n> of
|
||||
{<NMasc,_> => Masc ; <NFem,_> => Fem;
|
||||
<NNeut,Sg> => Masc ; <NNeut,Pl> => Fem
|
||||
};
|
||||
|
||||
}
|
||||
30
testsuite/lpgf/foods/FoodsSpa.gf
Normal file
30
testsuite/lpgf/foods/FoodsSpa.gf
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
concrete FoodsSpa of Foods = open SyntaxSpa, StructuralSpa, ParadigmsSpa in {
|
||||
|
||||
lincat
|
||||
Comment = Utt ;
|
||||
Item = NP ;
|
||||
Kind = CN ;
|
||||
Quality = AP ;
|
||||
|
||||
lin
|
||||
Pred item quality = mkUtt (mkCl item quality) ;
|
||||
This kind = mkNP this_QuantSg kind ;
|
||||
That kind = mkNP that_QuantSg kind ;
|
||||
These kind = mkNP these_QuantPl kind ;
|
||||
Those kind = mkNP those_QuantPl kind ;
|
||||
Mod quality kind = mkCN quality kind ;
|
||||
Very quality = mkAP very_AdA quality ;
|
||||
Wine = mkCN (mkN "vino") ;
|
||||
Pizza = mkCN (mkN "pizza") ;
|
||||
Cheese = mkCN (mkN "queso") ;
|
||||
Fish = mkCN (mkN "pescado") ;
|
||||
Fresh = mkAP (mkA "fresco") ;
|
||||
Warm = mkAP (mkA "caliente") ;
|
||||
Italian = mkAP (mkA "italiano") ;
|
||||
Expensive = mkAP (mkA "caro") ;
|
||||
Delicious = mkAP (mkA "delicioso") ;
|
||||
Boring = mkAP (mkA "aburrido") ;
|
||||
|
||||
}
|
||||
|
||||
6
testsuite/lpgf/foods/FoodsSwe.gf
Normal file
6
testsuite/lpgf/foods/FoodsSwe.gf
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
-- (c) 2009 Aarne Ranta under LGPL
|
||||
|
||||
concrete FoodsSwe of Foods = FoodsI with
|
||||
(Syntax = SyntaxSwe),
|
||||
(LexFoods = LexFoodsSwe) ** {flags language = sv_SE;} ;
|
||||
32
testsuite/lpgf/foods/FoodsTha.gf
Normal file
32
testsuite/lpgf/foods/FoodsTha.gf
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
concrete FoodsTha of Foods = open SyntaxTha, LexiconTha,
|
||||
ParadigmsTha, (R=ResTha) in {
|
||||
|
||||
flags coding = utf8 ;
|
||||
|
||||
lincat
|
||||
Comment = Utt ;
|
||||
Item = NP ;
|
||||
Kind = CN ;
|
||||
Quality = AP ;
|
||||
|
||||
lin
|
||||
Pred item quality = mkUtt (mkCl item quality) ;
|
||||
This kind = mkNP this_Det kind ;
|
||||
That kind = mkNP that_Det kind ;
|
||||
These kind = mkNP these_Det kind ;
|
||||
Those kind = mkNP those_Det kind ;
|
||||
Mod quality kind = mkCN quality kind ;
|
||||
Very quality = mkAP very_AdA quality ;
|
||||
Wine = mkCN (mkN (R.thword "เหล้าอ" "งุ่น") "ขวด") ;
|
||||
Pizza = mkCN (mkN (R.thword "พิซ" "ซา") "ถาด") ;
|
||||
Cheese = mkCN (mkN (R.thword "เนย" "แข็ง") "ก้อน") ;
|
||||
Fish = mkCN fish_N ;
|
||||
Fresh = mkAP (mkA "สด") ;
|
||||
Warm = mkAP warm_A ;
|
||||
Italian = mkAP (mkA " อิตาลี") ;
|
||||
Expensive = mkAP (mkA "แพง") ;
|
||||
Delicious = mkAP (mkA "อร่อย") ;
|
||||
Boring = mkAP (mkA (R.thword "น่า" "เบิ่อ")) ;
|
||||
|
||||
}
|
||||
177
testsuite/lpgf/foods/FoodsTsn.gf
Normal file
177
testsuite/lpgf/foods/FoodsTsn.gf
Normal file
@@ -0,0 +1,177 @@
|
||||
|
||||
-- (c) 2009 Laurette Pretorius Sr & Jr and Ansu Berg under LGPL
|
||||
|
||||
concrete FoodsTsn of Foods = open Prelude, Predef in {
|
||||
flags coding = utf8;
|
||||
lincat
|
||||
Comment = {s:Str};
|
||||
Item = {s:Str; c:NounClass; n:Number};
|
||||
Kind = {w: Number => Str; r: Str; c: NounClass; q: Number => Str; b: Bool};
|
||||
Quality = {s: NounClass => Number => Str; p_form: Str; t: TType};
|
||||
lin
|
||||
Pred item quality = {s = item.s ++ ((mkPredDescrCop quality.t) ! item.c ! item.n) ++ quality.p_form};
|
||||
|
||||
This kind = {s = (kind.w ! Sg) ++ (mkDemPron1 ! kind.c ! Sg) ++ (kind.q ! Sg); c = kind.c; n = Sg};
|
||||
That kind = {s = (kind.w ! Sg) ++ (mkDemPron2 ! kind.c ! Sg) ++ (kind.q ! Sg); c = kind.c; n = Sg};
|
||||
These kind = {s = (kind.w ! Pl) ++ (mkDemPron1 ! kind.c ! Pl) ++ (kind.q ! Pl); c = kind.c; n = Pl};
|
||||
Those kind = {s = (kind.w ! Pl) ++ (mkDemPron2 ! kind.c ! Pl) ++ (kind.q ! Pl); c = kind.c; n = Pl};
|
||||
|
||||
Mod quality kind = mkMod quality kind;
|
||||
|
||||
-- Lexicon
|
||||
Wine = mkNounNC14_6 "jalwa";
|
||||
Cheese = mkNounNC9_10 "kase";
|
||||
Fish = mkNounNC9_10 "thlapi";
|
||||
Pizza = mkNounNC9_10 "pizza";
|
||||
Very quality = smartVery quality;
|
||||
Fresh = mkVarAdj "ntsha";
|
||||
Warm = mkOrdAdj "bothitho";
|
||||
Italian = mkPerAdj "Itali";
|
||||
Expensive = mkVerbRel "tura";
|
||||
Delicious = mkOrdAdj "monate";
|
||||
Boring = mkOrdAdj "bosula";
|
||||
|
||||
param
|
||||
NounClass = NC9_10 | NC14_6;
|
||||
Number = Sg | Pl;
|
||||
TType = P | V | ModV | R ;
|
||||
oper
|
||||
mkMod : {s: NounClass => Number => Str; p_form: Str; t: TType} -> {w: Number => Str; r: Str; c: NounClass; q: Number => Str; b: Bool} -> {w: Number => Str; r: Str; c: NounClass; q: Number => Str;
|
||||
b: Bool} = \x,y -> case y.b of
|
||||
{
|
||||
True => {w = y.w; r = y.r; c = y.c;
|
||||
q = table {
|
||||
Sg => ((y.q ! Sg) ++ "le" ++ ((smartQualRelPart (x.t)) ! y.c ! Sg) ++ ((smartDescrCop (x.t)) ! y.c ! Sg) ++ (x.s ! y.c ! Sg));
|
||||
Pl => ((y.q ! Pl) ++ "le" ++ ((smartQualRelPart (x.t))! y.c ! Pl) ++ ((smartDescrCop (x.t)) ! y.c ! Pl) ++(x.s ! y.c ! Pl))
|
||||
}; b = True
|
||||
};
|
||||
False => {w = y.w; r = y.r; c = y.c;
|
||||
q = table {
|
||||
Sg => ((y.q ! Sg) ++ ((smartQualRelPart (x.t)) ! y.c ! Sg) ++ ((smartDescrCop (x.t)) ! y.c ! Sg) ++ (x.s ! y.c ! Sg));
|
||||
Pl => ((y.q ! Pl) ++ ((smartQualRelPart (x.t)) ! y.c ! Pl) ++ ((smartDescrCop (x.t)) ! y.c ! Pl) ++(x.s ! y.c ! Pl))
|
||||
}; b = True
|
||||
}
|
||||
};
|
||||
|
||||
mkNounNC14_6 : Str -> {w: Number => Str; r: Str; c: NounClass; q: Number => Str; b: Bool} = \x -> {w = table {Sg => "bo" + x; Pl => "ma" + x}; r = x; c = NC14_6;
|
||||
q = table {Sg => ""; Pl => ""}; b = False};
|
||||
|
||||
mkNounNC9_10 : Str -> {w: Number => Str; r: Str; c: NounClass; q: Number => Str; b: Bool} = \x -> {w = table {Sg => "" + x; Pl => "di" + x}; r = x; c = NC9_10;
|
||||
q = table {Sg => ""; Pl => ""}; b = False};
|
||||
|
||||
mkVarAdj : Str -> {s: NounClass => Number => Str; p_form: Str; t: TType} = \x ->
|
||||
{
|
||||
s = table {
|
||||
NC9_10 => table {Sg => "" + x; Pl => "di" + x};
|
||||
NC14_6 => table {Sg => "bo" + x; Pl => "ma" + x}
|
||||
};
|
||||
p_form = x;
|
||||
t = R;
|
||||
};
|
||||
|
||||
mkOrdAdj : Str -> {s: NounClass => Number => Str; p_form: Str; t: TType} = \x ->
|
||||
{
|
||||
s = table {
|
||||
NC9_10 => table {Sg => "" + x; Pl => "" + x};
|
||||
NC14_6 => table {Sg => "" + x; Pl => "" + x}
|
||||
};
|
||||
p_form = x;
|
||||
t = R;
|
||||
};
|
||||
|
||||
mkVerbRel : Str -> {s: NounClass => Number => Str; p_form: Str; t: TType} = \x ->
|
||||
{
|
||||
s = table {
|
||||
NC9_10 => table {Sg => x + "ng"; Pl => x + "ng"};
|
||||
NC14_6 => table {Sg => x + "ng"; Pl => x + "ng"}
|
||||
};
|
||||
p_form = x;
|
||||
t = V;
|
||||
};
|
||||
|
||||
mkPerAdj : Str -> {s: NounClass => Number => Str; p_form: Str; t: TType} = \x ->
|
||||
{
|
||||
s = table {
|
||||
NC9_10 => table {Sg => "" + x; Pl => "" + x};
|
||||
NC14_6 => table {Sg => "" + x; Pl => "" + x}
|
||||
};
|
||||
p_form = "mo" ++ x;
|
||||
t = P;
|
||||
};
|
||||
|
||||
mkVeryAdj : {s: NounClass => Number => Str; p_form: Str; t: TType} -> {s: NounClass => Number => Str; p_form: Str; t: TType} = \x ->
|
||||
{
|
||||
s = table{c => table{n => (x.s!c!n) ++ "thata"}}; p_form = x.p_form ++ "thata"; t = x.t
|
||||
};
|
||||
|
||||
mkVeryVerb : {s: NounClass => Number => Str; p_form: Str; t: TType} -> {s: NounClass => Number => Str; p_form: Str; t: TType} = \x ->
|
||||
{
|
||||
s = table{c => table{n => (x.s!c!n) ++ "thata"}}; p_form = x.p_form ++ "thata"; t = ModV
|
||||
};
|
||||
|
||||
smartVery : {s: NounClass => Number => Str; p_form: Str; t: TType} -> {s: NounClass => Number => Str; p_form: Str; t: TType} =
|
||||
\x -> case x.t of --(x.s!c!n)
|
||||
{
|
||||
(V | ModV) => mkVeryVerb x;
|
||||
--ModV => mkVeryVerb x;
|
||||
_ => mkVeryAdj x
|
||||
};
|
||||
|
||||
mkDemPron1 : NounClass => Number => Str = table
|
||||
{
|
||||
NC9_10 => table {Sg => "e"; Pl => "tse"};
|
||||
NC14_6 => table {Sg => "bo"; Pl => "a"}
|
||||
};
|
||||
|
||||
mkDemPron2 : NounClass => Number => Str = table
|
||||
{
|
||||
NC9_10 => table {Sg => "eo"; Pl => "tseo"};
|
||||
NC14_6 => table {Sg => "boo"; Pl => "ao"}
|
||||
};
|
||||
|
||||
smartQualRelPart : TType -> (NounClass => Number => Str) = \x -> case x of
|
||||
{
|
||||
P => mkQualRelPart_PName;
|
||||
_ => mkQualRelPart
|
||||
};
|
||||
|
||||
mkQualRelPart : NounClass => Number => Str = table
|
||||
{
|
||||
NC9_10 => table {Sg => "e"; Pl => "tse"};
|
||||
NC14_6 => table {Sg => "bo"; Pl => "a"}
|
||||
};
|
||||
|
||||
mkQualRelPart_PName : NounClass => Number => Str = table
|
||||
{
|
||||
NC9_10 => table {Sg => "ya"; Pl => "tsa"};
|
||||
NC14_6 => table {Sg => "ba"; Pl => "a"}
|
||||
};
|
||||
|
||||
smartDescrCop : TType -> (NounClass => Number => Str) = \x -> case x of
|
||||
{
|
||||
P => mkDescrCop_PName;
|
||||
_ => mkDescrCop
|
||||
};
|
||||
|
||||
mkDescrCop : NounClass => Number => Str = table
|
||||
{
|
||||
NC9_10 => table {Sg => "e"; Pl => "di"};
|
||||
NC14_6 => table {Sg => "bo"; Pl => "a"}
|
||||
};
|
||||
|
||||
mkDescrCop_PName : NounClass => Number => Str = table
|
||||
{
|
||||
NC9_10 => table {Sg => "ga"; Pl => "ga"};
|
||||
NC14_6 => table {Sg => "ga"; Pl => "ga"}
|
||||
};
|
||||
|
||||
mkPredDescrCop : TType -> (NounClass => Number => Str) = \x -> case x of
|
||||
{
|
||||
V => table {NC9_10 => table {Sg => "e" ++ "a"; Pl => "di" ++ "a"};
|
||||
NC14_6 => table {Sg => "bo" ++ "a"; Pl => "a" ++ "a"}};
|
||||
|
||||
_ => table {NC9_10 => table {Sg => "e"; Pl => "di"};
|
||||
NC14_6 => table {Sg => "bo"; Pl => "a"}}
|
||||
};
|
||||
|
||||
}
|
||||
140
testsuite/lpgf/foods/FoodsTur.gf
Normal file
140
testsuite/lpgf/foods/FoodsTur.gf
Normal file
@@ -0,0 +1,140 @@
|
||||
{-
|
||||
File : FoodsTur.gf
|
||||
Author : Server Çimen
|
||||
Version : 1.0
|
||||
Created on: August 26, 2009
|
||||
|
||||
This file contains concrete grammar of Foods abstract grammar for Turkish Language.
|
||||
This grammar is to be used for Fridge demo and developed in the scope of GF Resource
|
||||
Grammar Summer School.
|
||||
|
||||
-}
|
||||
|
||||
concrete FoodsTur of Foods = open Predef in {
|
||||
flags
|
||||
coding=utf8 ;
|
||||
lincat
|
||||
Comment = {s : Str} ;
|
||||
Quality = {s : Str ; c : Case; softness : Softness; h : Harmony} ;
|
||||
Kind = {s : Case => Number => Str} ;
|
||||
Item = {s : Str; n : Number} ;
|
||||
lin
|
||||
This = det Sg "bu" ;
|
||||
That = det Sg "şu" ;
|
||||
These = det Pl "bu" ;
|
||||
Those = det Pl "şu" ;
|
||||
-- Reason for excluding plural form of copula: In Turkish if subject is not a human being,
|
||||
-- then singular form of copula is used regardless of the number of subject. Since all
|
||||
-- possible subjects are non human, copula do not need to have plural form.
|
||||
Pred item quality = {s = item.s ++ quality.s ++ BIND ++ copula ! quality.softness ! quality.h} ;--! item.n} ;
|
||||
Mod quality kind = {s = case quality.c of {
|
||||
Nom => \\t,n => quality.s ++ kind.s ! t ! n ;
|
||||
Gen => \\t,n => quality.s ++ kind.s ! Gen ! n
|
||||
}
|
||||
} ;
|
||||
Wine = mkN "şarap" "şaraplar" "şarabı" "şarapları" ;
|
||||
Cheese = mkN "peynir" "peynirler" "peyniri" "peynirleri" ;
|
||||
Fish = mkN "balık" "balıklar" "balığı" "balıkları" ;
|
||||
Pizza = mkN "pizza" "pizzalar" "pizzası" "pizzaları" ;
|
||||
Very a = {s = "çok" ++ a.s ; c = a.c; softness = a.softness; h = a.h} ;
|
||||
Fresh = adj "taze" Nom;
|
||||
Warm = adj "ılık" Nom;
|
||||
Italian = adj "İtalyan" Gen ;
|
||||
Expensive = adj "pahalı" Nom;
|
||||
Delicious = adj "lezzetli" Nom;
|
||||
Boring = adj "sıkıcı" Nom;
|
||||
param
|
||||
Number = Sg | Pl ;
|
||||
Case = Nom | Gen ;
|
||||
Harmony = I_Har | Ih_Har | U_Har | Uh_Har ; --Ih = İ; Uh = Ü
|
||||
Softness = Soft | Hard ;
|
||||
oper
|
||||
det : Number -> Str -> {s : Case => Number => Str} -> {s : Str; n : Number} =
|
||||
\num,det,noun -> {s = det ++ noun.s ! Nom ! num; n = num} ;
|
||||
mkN = overload {
|
||||
mkN : Str -> Str -> {s : Case => Number => Str} = regNoun ;
|
||||
mkn : Str -> Str -> Str -> Str-> {s : Case => Number => Str} = noun ;
|
||||
} ;
|
||||
regNoun : Str -> Str -> {s : Case => Number => Str} =
|
||||
\peynir,peynirler -> noun peynir peynirler [] [] ;
|
||||
noun : Str -> Str -> Str -> Str-> {s : Case => Number => Str} =
|
||||
\sarap,saraplar,sarabi,saraplari -> {
|
||||
s = table {
|
||||
Nom => table {
|
||||
Sg => sarap ;
|
||||
Pl => saraplar
|
||||
} ;
|
||||
Gen => table {
|
||||
Sg => sarabi ;
|
||||
Pl => saraplari
|
||||
}
|
||||
}
|
||||
};
|
||||
{-
|
||||
Since there is a bug in overloading, this overload is useless.
|
||||
|
||||
mkA = overload {
|
||||
mkA : Str -> {s : Str; c : Case; softness : Softness; h : Harmony} = \base -> adj base Nom ;
|
||||
mkA : Str -> Case -> {s : Str; c : Case; softness : Softness; h : Harmony} = adj ;
|
||||
} ;
|
||||
-}
|
||||
adj : Str -> Case -> {s : Str; c : Case; softness : Softness; h : Harmony} =
|
||||
\italyan,ca -> {s = italyan ; c = ca; softness = (getSoftness italyan); h = (getHarmony italyan)} ;
|
||||
-- See the comment at lines 26 and 27 for excluded plural form of copula.
|
||||
copula : Softness => Harmony {-=> Number-} => Str =
|
||||
table {
|
||||
Soft => table {
|
||||
I_Har => "dır" ;--table {
|
||||
-- Sg => "dır" ;
|
||||
-- Pl => "dırlar"
|
||||
--} ;
|
||||
Ih_Har => "dir" ;--table {
|
||||
--Sg => "dir" ;
|
||||
--Pl => "dirler"
|
||||
--} ;
|
||||
U_Har => "dur" ;--table {
|
||||
-- Sg => "dur" ;
|
||||
-- Pl => "durlar"
|
||||
--} ;
|
||||
Uh_Har => "dür" --table {
|
||||
--Sg => "dür" ;
|
||||
--Pl => "dürler"
|
||||
--}
|
||||
} ;
|
||||
Hard => table {
|
||||
I_Har => "tır" ;--table {
|
||||
--Sg => "tır" ;
|
||||
--Pl => "tırlar"
|
||||
--} ;
|
||||
Ih_Har => "tir" ;--table {
|
||||
--Sg => "tir" ;
|
||||
--Pl => "tirler"
|
||||
--} ;
|
||||
U_Har => "tur" ;--table {
|
||||
-- Sg => "tur" ;
|
||||
-- Pl => "turlar"
|
||||
--} ;
|
||||
Uh_Har => "tür"--table {
|
||||
--Sg => "tür" ;
|
||||
--Pl => "türler"
|
||||
--}
|
||||
}
|
||||
} ;
|
||||
|
||||
getHarmony : Str -> Harmony
|
||||
= \base -> case base of {
|
||||
_+c@("ı"|"a"|"i"|"e"|"u"|"o"|"ü"|"ö")+
|
||||
("b"|"v"|"d"|"z"|"j"|"c"|"g"|"ğ"|"l"|"r"|"m"|"n"|"y"|"p"|"f"|"t"|"s"|"ş"|"ç"|"k"|"h")* =>
|
||||
case c of {
|
||||
("ı"|"a") => I_Har ;
|
||||
("i"|"e") => Ih_Har ;
|
||||
("u"|"o") => U_Har ;
|
||||
("ü"|"ö") => Uh_Har
|
||||
}
|
||||
} ;
|
||||
getSoftness : Str -> Softness
|
||||
= \base -> case base of {
|
||||
_+("f"|"s"|"t"|"k"|"ç"|"ş"|"h"|"p") => Hard ;
|
||||
_ => Soft
|
||||
} ;
|
||||
}
|
||||
53
testsuite/lpgf/foods/FoodsUrd.gf
Normal file
53
testsuite/lpgf/foods/FoodsUrd.gf
Normal file
@@ -0,0 +1,53 @@
|
||||
-- (c) 2009 Shafqat Virk under LGPL
|
||||
|
||||
concrete FoodsUrd of Foods = {
|
||||
|
||||
flags coding=utf8 ;
|
||||
|
||||
|
||||
param Number = Sg | Pl ;
|
||||
param Gender = Masc | Fem;
|
||||
|
||||
oper coupla : Number -> Str =\n -> case n of {Sg => "ہے" ; Pl => "ہیں"};
|
||||
|
||||
|
||||
lincat
|
||||
Comment = {s : Str} ;
|
||||
Item = {s: Str ; n: Number ; g:Gender};
|
||||
Kind = {s: Number => Str ; g:Gender};
|
||||
Quality = {s: Gender => Number => Str};
|
||||
|
||||
lin
|
||||
Pred item quality = {s = item.s ++ quality.s ! item.g ! item.n ++ coupla item.n} ;
|
||||
This kind = {s = "یھ" ++ kind.s ! Sg; n= Sg ; g = kind.g } ;
|
||||
These kind = {s = "یھ" ++ kind.s ! Pl; n = Pl ; g = kind.g} ;
|
||||
That kind = {s = "وہ" ++ kind.s ! Sg; n= Sg ; g = kind.g} ;
|
||||
Those kind = {s = "وہ" ++ kind.s ! Pl; n=Pl ; g = kind.g} ;
|
||||
Mod quality kind = {s = \\n => quality.s ! kind.g ! n ++ kind.s ! n ; g = kind.g};
|
||||
Wine = {s = table { Sg => "شراب" ; Pl => "شرابیں"} ; g = Fem};
|
||||
Cheese = {s = table { Sg => "پنیر" ; Pl => "پنیریں"} ; g = Fem};
|
||||
Fish = {s = table { Sg => "مچھلی" ; Pl => "مچھلیاں"} ; g = Fem};
|
||||
Pizza = {s = table { Sg => "پیزہ" ; Pl => "پیزے"} ; g = Masc};
|
||||
Very quality = {s = \\g,n => "بہت" ++ quality.s ! g ! n} ;
|
||||
Fresh = regAdj "تازہ" ;
|
||||
Warm = regAdj "گرم" ;
|
||||
Italian = regAdj "اٹا لوی" ;
|
||||
Expensive = regAdj "مہنگا" ;
|
||||
Delicious = regAdj "مزیدار" ;
|
||||
Boring = regAdj "فضول" ;
|
||||
|
||||
oper
|
||||
regAdj : Str -> {s: Gender => Number => Str} = \a -> case a of {
|
||||
x + "ا" => mkAdj a (x+"ے") (x+"ی");
|
||||
_ => mkAdj a a a
|
||||
};
|
||||
mkAdj : Str -> Str -> Str -> {s: Gender => Number => Str} = \s,p,f -> {
|
||||
s = table {
|
||||
Masc => table {
|
||||
Sg => s;
|
||||
Pl => p
|
||||
};
|
||||
Fem => \\_ => f
|
||||
}
|
||||
};
|
||||
}
|
||||
15
testsuite/lpgf/foods/LexFoods.gf
Normal file
15
testsuite/lpgf/foods/LexFoods.gf
Normal file
@@ -0,0 +1,15 @@
|
||||
-- (c) 2009 Aarne Ranta under LGPL
|
||||
|
||||
interface LexFoods = open Syntax in {
|
||||
oper
|
||||
wine_N : N ;
|
||||
pizza_N : N ;
|
||||
cheese_N : N ;
|
||||
fish_N : N ;
|
||||
fresh_A : A ;
|
||||
warm_A : A ;
|
||||
italian_A : A ;
|
||||
expensive_A : A ;
|
||||
delicious_A : A ;
|
||||
boring_A : A ;
|
||||
}
|
||||
18
testsuite/lpgf/foods/LexFoodsCat.gf
Normal file
18
testsuite/lpgf/foods/LexFoodsCat.gf
Normal file
@@ -0,0 +1,18 @@
|
||||
-- (c) 2009 Jordi Saludes under LGPL
|
||||
|
||||
instance LexFoodsCat of LexFoods =
|
||||
open SyntaxCat, ParadigmsCat, (M = MorphoCat) in {
|
||||
flags
|
||||
coding = utf8 ;
|
||||
oper
|
||||
wine_N = mkN "vi" "vins" M.Masc ;
|
||||
pizza_N = mkN "pizza" ;
|
||||
cheese_N = mkN "formatge" ;
|
||||
fish_N = mkN "peix" "peixos" M.Masc;
|
||||
fresh_A = mkA "fresc" "fresca" "frescos" "fresques" "frescament";
|
||||
warm_A = mkA "calent" ;
|
||||
italian_A = mkA "italià" "italiana" "italians" "italianes" "italianament" ;
|
||||
expensive_A = mkA "car" ;
|
||||
delicious_A = mkA "deliciós" "deliciosa" "deliciosos" "delicioses" "deliciosament";
|
||||
boring_A = mkA "aburrit" "aburrida" "aburrits" "aburrides" "aburridament" ;
|
||||
}
|
||||
21
testsuite/lpgf/foods/LexFoodsFin.gf
Normal file
21
testsuite/lpgf/foods/LexFoodsFin.gf
Normal file
@@ -0,0 +1,21 @@
|
||||
-- (c) 2009 Aarne Ranta under LGPL
|
||||
--# -coding=latin1
|
||||
|
||||
instance LexFoodsFin of LexFoods =
|
||||
open SyntaxFin, ParadigmsFin in {
|
||||
oper
|
||||
wine_N = mkN "viini" ;
|
||||
pizza_N = mkN "pizza" ;
|
||||
cheese_N = mkN "juusto" ;
|
||||
fish_N = mkN "kala" ;
|
||||
fresh_A = mkA "tuore" ;
|
||||
warm_A = mkA
|
||||
(mkN "lämmin" "lämpimän" "lämmintä" "lämpimänä" "lämpimään"
|
||||
"lämpiminä" "lämpimiä" "lämpimien" "lämpimissä" "lämpimiin"
|
||||
)
|
||||
"lämpimämpi" "lämpimin" ;
|
||||
italian_A = mkA "italialainen" ;
|
||||
expensive_A = mkA "kallis" ;
|
||||
delicious_A = mkA "herkullinen" ;
|
||||
boring_A = mkA "tylsä" ;
|
||||
}
|
||||
17
testsuite/lpgf/foods/LexFoodsGer.gf
Normal file
17
testsuite/lpgf/foods/LexFoodsGer.gf
Normal file
@@ -0,0 +1,17 @@
|
||||
-- (c) 2009 Aarne Ranta under LGPL
|
||||
--# -coding=latin1
|
||||
|
||||
instance LexFoodsGer of LexFoods =
|
||||
open SyntaxGer, ParadigmsGer in {
|
||||
oper
|
||||
wine_N = mkN "Wein" ;
|
||||
pizza_N = mkN "Pizza" "Pizzen" feminine ;
|
||||
cheese_N = mkN "Käse" "Käse" masculine ;
|
||||
fish_N = mkN "Fisch" ;
|
||||
fresh_A = mkA "frisch" ;
|
||||
warm_A = mkA "warm" "wärmer" "wärmste" ;
|
||||
italian_A = mkA "italienisch" ;
|
||||
expensive_A = mkA "teuer" ;
|
||||
delicious_A = mkA "köstlich" ;
|
||||
boring_A = mkA "langweilig" ;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user