mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-21 17:12:50 -06:00
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:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
cabal: ["3.2"]
|
cabal: ["latest"]
|
||||||
ghc:
|
ghc:
|
||||||
- "8.6.5"
|
- "8.6.5"
|
||||||
- "8.8.3"
|
- "8.8.3"
|
||||||
@@ -33,7 +33,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
|
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
|
id: setup-haskell-cabal
|
||||||
name: Setup Haskell
|
name: Setup Haskell
|
||||||
with:
|
with:
|
||||||
@@ -53,19 +53,19 @@ jobs:
|
|||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
cabal configure --enable-tests --enable-benchmarks --test-show-details=direct
|
cabal configure --enable-tests --test-show-details=direct
|
||||||
cabal build all
|
cabal build
|
||||||
|
|
||||||
# - name: Test
|
- name: Test
|
||||||
# run: |
|
run: |
|
||||||
# cabal test all
|
PATH="$PWD/dist/build/gf:$PATH" cabal test gf-tests
|
||||||
|
|
||||||
stack:
|
stack:
|
||||||
name: stack / ghc ${{ matrix.ghc }}
|
name: stack / ghc ${{ matrix.ghc }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
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: ["7.10.3","8.0.2", "8.2.2", "8.4.4", "8.6.5", "8.8.4"]
|
||||||
# ghc: ["8.8.3"]
|
# ghc: ["8.8.3"]
|
||||||
|
|
||||||
@@ -73,11 +73,12 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
|
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
|
name: Setup Haskell Stack
|
||||||
with:
|
with:
|
||||||
# ghc-version: ${{ matrix.ghc }}
|
ghc-version: ${{ matrix.ghc }}
|
||||||
stack-version: ${{ matrix.stack }}
|
stack-version: 'latest'
|
||||||
|
enable-stack: true
|
||||||
|
|
||||||
- uses: actions/cache@v1
|
- uses: actions/cache@v1
|
||||||
name: Cache ~/.stack
|
name: Cache ~/.stack
|
||||||
@@ -87,9 +88,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
stack build --system-ghc --stack-yaml stack-ghc${{ matrix.ghc }}.yaml
|
stack build --system-ghc --stack-yaml stack-ghc${{ matrix.ghc }}.yaml --test --no-run-tests
|
||||||
# stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks
|
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: |
|
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:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
release:
|
release:
|
||||||
|
types: ["created"]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
@@ -10,11 +11,13 @@ jobs:
|
|||||||
|
|
||||||
ubuntu:
|
ubuntu:
|
||||||
name: Build Ubuntu package
|
name: Build Ubuntu package
|
||||||
runs-on: ubuntu-18.04
|
strategy:
|
||||||
# strategy:
|
matrix:
|
||||||
# matrix:
|
os:
|
||||||
# ghc: ["8.6.5"]
|
- ubuntu-18.04
|
||||||
# cabal: ["2.4"]
|
- ubuntu-20.04
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -53,19 +56,33 @@ jobs:
|
|||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: gf-${{ github.sha }}-ubuntu
|
name: gf-${{ github.event.release.tag_name }}-${{ matrix.os }}.deb
|
||||||
path: dist/gf_*.deb
|
path: dist/gf_*.deb
|
||||||
if-no-files-found: error
|
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:
|
macos:
|
||||||
name: Build macOS package
|
name: Build macOS package
|
||||||
runs-on: macos-10.15
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
ghc: ["8.6.5"]
|
ghc: ["8.6.5"]
|
||||||
cabal: ["2.4"]
|
cabal: ["2.4"]
|
||||||
|
os: ["macos-10.15"]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -92,19 +109,33 @@ jobs:
|
|||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: gf-${{ github.sha }}-macos
|
name: gf-${{ github.event.release.tag_name }}-macos
|
||||||
path: dist/gf-*.pkg
|
path: dist/gf-*.pkg
|
||||||
if-no-files-found: error
|
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:
|
windows:
|
||||||
name: Build Windows package
|
name: Build Windows package
|
||||||
runs-on: windows-2019
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
ghc: ["8.6.5"]
|
ghc: ["8.6.5"]
|
||||||
cabal: ["2.4"]
|
cabal: ["2.4"]
|
||||||
|
os: ["windows-2019"]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -136,16 +167,18 @@ jobs:
|
|||||||
cp /mingw64/bin/libpgf-0.dll /c/tmp-dist/c
|
cp /mingw64/bin/libpgf-0.dll /c/tmp-dist/c
|
||||||
cp /mingw64/bin/libgu-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
|
- name: Build Java bindings
|
||||||
shell: msys2 {0}
|
shell: msys2 {0}
|
||||||
run: |
|
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
|
cd src/runtime/java
|
||||||
make \
|
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"
|
WINDOWS_LDFLAGS="-L\"/mingw64/lib\" -no-undefined"
|
||||||
make install
|
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
|
cp jpgf.jar /c/tmp-dist/java
|
||||||
|
|
||||||
- name: Build Python bindings
|
- name: Build Python bindings
|
||||||
@@ -157,7 +190,7 @@ jobs:
|
|||||||
cd src/runtime/python
|
cd src/runtime/python
|
||||||
python setup.py build
|
python setup.py build
|
||||||
python setup.py install
|
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
|
- name: Setup Haskell
|
||||||
uses: actions/setup-haskell@v1
|
uses: actions/setup-haskell@v1
|
||||||
@@ -180,6 +213,18 @@ jobs:
|
|||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: gf-${{ github.sha }}-windows
|
name: gf-${{ github.event.release.tag_name }}-windows
|
||||||
path: C:\tmp-dist\*
|
path: C:\tmp-dist\*
|
||||||
if-no-files-found: error
|
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
|
*.jar
|
||||||
*.gfo
|
*.gfo
|
||||||
*.pgf
|
*.pgf
|
||||||
|
*.lpgf
|
||||||
debian/.debhelper
|
debian/.debhelper
|
||||||
debian/debhelper-build-stamp
|
debian/debhelper-build-stamp
|
||||||
debian/gf
|
debian/gf
|
||||||
@@ -48,7 +49,7 @@ src/runtime/java/.libs/
|
|||||||
src/runtime/python/build/
|
src/runtime/python/build/
|
||||||
.cabal-sandbox
|
.cabal-sandbox
|
||||||
cabal.sandbox.config
|
cabal.sandbox.config
|
||||||
.stack-work
|
.stack-work*
|
||||||
DATA_DIR
|
DATA_DIR
|
||||||
|
|
||||||
stack*.yaml.lock
|
stack*.yaml.lock
|
||||||
@@ -73,3 +74,10 @@ doc/icfp-2012.html
|
|||||||
download/*.html
|
download/*.html
|
||||||
gf-book/index.html
|
gf-book/index.html
|
||||||
src/www/gf-web-api.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
|
# This gets the numeric part of the version from the cabal file
|
||||||
VERSION=$(shell sed -ne "s/^version: *\([0-9.]*\).*/\1/p" gf.cabal)
|
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
|
all: build
|
||||||
|
|
||||||
dist/setup-config: gf.cabal Setup.hs WebSetup.hs
|
dist/setup-config: gf.cabal Setup.hs WebSetup.hs
|
||||||
cabal configure
|
ifneq ($(STACK),1)
|
||||||
|
cabal ${CMD_PFX}configure
|
||||||
|
endif
|
||||||
|
|
||||||
build: dist/setup-config
|
build: dist/setup-config
|
||||||
cabal build
|
${CMD} ${CMD_PFX}build
|
||||||
|
|
||||||
install:
|
install:
|
||||||
cabal copy
|
ifeq ($(STACK),1)
|
||||||
cabal register
|
stack install
|
||||||
|
else
|
||||||
|
cabal ${CMD_PFX}copy
|
||||||
|
cabal ${CMD_PFX}register
|
||||||
|
endif
|
||||||
|
|
||||||
doc:
|
doc:
|
||||||
cabal haddock
|
${CMD} ${CMD_PFX}haddock
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
cabal clean
|
${CMD} ${CMD_PFX}clean
|
||||||
bash bin/clean_html
|
bash bin/clean_html
|
||||||
|
|
||||||
gf:
|
|
||||||
cabal build rgl-none
|
|
||||||
strip dist/build/gf/gf
|
|
||||||
|
|
||||||
html::
|
html::
|
||||||
bash bin/update_html
|
bash bin/update_html
|
||||||
|
|
||||||
@@ -35,7 +52,7 @@ html::
|
|||||||
deb:
|
deb:
|
||||||
dpkg-buildpackage -b -uc
|
dpkg-buildpackage -b -uc
|
||||||
|
|
||||||
# Make an OS X Installer package
|
# Make a macOS installer package
|
||||||
pkg:
|
pkg:
|
||||||
FMT=pkg bash bin/build-binary-dist.sh
|
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-1) xenial bionic cosmic; urgency=low
|
||||||
|
|
||||||
* GF 3.10.4
|
* GF 3.10.4
|
||||||
|
|||||||
10
debian/rules
vendored
10
debian/rules
vendored
@@ -16,9 +16,9 @@ override_dh_shlibdeps:
|
|||||||
override_dh_auto_configure:
|
override_dh_auto_configure:
|
||||||
cd src/runtime/c && bash setup.sh configure --prefix=/usr
|
cd src/runtime/c && bash setup.sh configure --prefix=/usr
|
||||||
cd src/runtime/c && bash setup.sh build
|
cd src/runtime/c && bash setup.sh build
|
||||||
cabal update
|
cabal v1-update
|
||||||
cabal install --only-dependencies
|
cabal v1-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-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
|
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/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
|
cd src/runtime/java && make CFLAGS="-I$(CURDIR)/src/runtime/c -L$(CURDIR)/src/runtime/c/.libs" INSTALL_PATH=/usr
|
||||||
echo $(SET_LDL)
|
echo $(SET_LDL)
|
||||||
-$(SET_LDL) cabal build
|
-$(SET_LDL) cabal v1-build
|
||||||
|
|
||||||
override_dh_auto_install:
|
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/c && bash setup.sh copy prefix=$(CURDIR)/debian/gf/usr
|
||||||
cd src/runtime/python && python setup.py install --prefix=$(CURDIR)/debian/gf/usr
|
cd src/runtime/python && python setup.py install --prefix=$(CURDIR)/debian/gf/usr
|
||||||
cd src/runtime/java && make INSTALL_PATH=$(CURDIR)/debian/gf/usr install
|
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
|
GF Developers Guide
|
||||||
|
|
||||||
2018-07-26
|
2021-07-15
|
||||||
|
|
||||||
%!options(html): --toc
|
%!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 ==
|
== Setting up your system for building GF ==
|
||||||
|
|
||||||
To build GF from source you need to install some tools on your
|
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
|
%**On Linux** the best option is to install the tools via the standard
|
||||||
software distribution channels, i.e. by using the //Software Center//
|
%software distribution channels, i.e. by using the //Software Center//
|
||||||
in Ubuntu or the corresponding tool in other popular Linux distributions.
|
%in Ubuntu or the corresponding tool in other popular Linux distributions.
|
||||||
Or, from a Terminal window, the following command should be enough:
|
|
||||||
|
|
||||||
- On Ubuntu: ``sudo apt-get install haskell-platform git libghc6-haskeline-dev``
|
%**On Mac OS and Windows**, the tools can be downloaded from their respective
|
||||||
- On Fedora: ``sudo dnf install haskell-platform git ghc-haskeline-devel``
|
%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
|
- **On other operating systems**, see the [installation guide https://docs.haskellstack.org/en/stable/install_and_upgrade].
|
||||||
web sites, as described below.
|
|
||||||
|
|
||||||
=== The Haskell Platform ===
|
|
||||||
|
|
||||||
GF is written in Haskell, so first of all you need
|
%If you already have Stack installed, upgrade it to the latest version by running: ``stack upgrade``
|
||||||
the //Haskell Platform//, e.g. version 8.0.2 or 7.10.3. Downloads
|
|
||||||
and installation instructions are available from here:
|
|
||||||
|
|
||||||
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 ===
|
=== Git ===
|
||||||
|
|
||||||
To get the GF source code, you also need //Git//.
|
To get the GF source code, you also need //Git//, a distributed version control system.
|
||||||
//Git// is a distributed version control system, see
|
|
||||||
https://git-scm.com/downloads for more information.
|
|
||||||
|
|
||||||
=== 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.
|
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)
|
- **On Mac OS and Windows**, this should work automatically.
|
||||||
required by //haskeline// are installed. Here is one way to do this:
|
|
||||||
|
- **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 Ubuntu: ``sudo apt-get install libghc-haskeline-dev``
|
||||||
- On Fedora: ``sudo dnf install ghc-haskeline-devel``
|
- 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
|
Once you have all tools in place you can get the GF source code from
|
||||||
just want to compile and use GF then it is enough to have read-only
|
[GitHub https://github.com/GrammaticalFramework/]:
|
||||||
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.
|
|
||||||
|
|
||||||
=== 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-core.git
|
||||||
$ git clone https://github.com/GrammaticalFramework/gf-rgl.git
|
$ git clone https://github.com/GrammaticalFramework/gf-rgl.git
|
||||||
```
|
```
|
||||||
|
|
||||||
This will create directories ``gf-core`` and ``gf-rgl`` in the current directory.
|
To get new updates, run the following anywhere in your local copy of the repository:
|
||||||
|
|
||||||
|
|
||||||
==== Updating your copy ====
|
|
||||||
|
|
||||||
To get all new patches from each repo:
|
|
||||||
```
|
```
|
||||||
$ git pull
|
$ git pull
|
||||||
```
|
```
|
||||||
This can be done anywhere in your local repository.
|
|
||||||
|
|
||||||
|
=== Contribute your changes: fork the main repository ===
|
||||||
|
|
||||||
==== Recording local changes ====[record]
|
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.
|
||||||
|
|
||||||
Since every copy is a repository, you can have local version control
|
+ **Creating and cloning a fork —**
|
||||||
of your changes.
|
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.
|
||||||
If you have added files, you first need to tell your local repository to
|
|
||||||
keep them under revision control:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git add file1 file2 ...
|
$ git clone https://github.com/<YOUR_USERNAME>/gf-core.git
|
||||||
```
|
```
|
||||||
|
|
||||||
To record changes, use:
|
+ **Updating your copy —**
|
||||||
|
Once you have cloned your fork, you need to set up the main repository as a remote:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git commit file1 file2 ...
|
$ git remote add upstream https://github.com/GrammaticalFramework/gf-core.git
|
||||||
```
|
```
|
||||||
|
|
||||||
This creates a patch against the previous version and stores it in your
|
Then you can get the latest updates by running the following:
|
||||||
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.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git push
|
$ git pull upstream master
|
||||||
```
|
```
|
||||||
|
|
||||||
It is also possible for anyone else to contribute by
|
+ **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.
|
||||||
|
|
||||||
- creating a fork of the GF repository on GitHub,
|
+ **Pull request —**
|
||||||
- working with local clone of the fork (obtained with ``git clone``),
|
When you want to contribute your changes to the main gf-core repository,
|
||||||
- pushing changes to the fork,
|
[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]
|
||||||
- and finally sending 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
|
== Compilation from source ==
|
||||||
case, all you need to do to compile and install GF, after downloading the
|
|
||||||
source code as described above, is
|
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
|
$ cabal install
|
||||||
```
|
```
|
||||||
|
|
||||||
This will automatically download any additional Haskell libraries needed to
|
//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.//
|
||||||
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
|
== Compiling GF with C runtime system support ==
|
||||||
//configure//, //build// and //install// steps.
|
|
||||||
|
|
||||||
=== Configure ===
|
The C runtime system is a separate implementation of the PGF runtime services.
|
||||||
|
|
||||||
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.
|
|
||||||
It makes it possible to work with very large, ambiguous grammars, using
|
It makes it possible to work with very large, ambiguous grammars, using
|
||||||
probabilistic models to obtain probable parses. The C run-time system might
|
probabilistic models to obtain probable parses. The C runtime system might
|
||||||
also be easier to use than the Haskell run-time system on certain platforms,
|
also be easier to use than the Haskell runtime system on certain platforms,
|
||||||
e.g. Android and iOS.
|
e.g. Android and iOS.
|
||||||
|
|
||||||
To install the C run-time system, go to the ``src/runtime/c`` directory
|
To install the C runtime 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``.
|
|
||||||
|
|
||||||
When the C run-time system is installed, you can install GF with C run-time
|
- **On Linux and Mac OS —**
|
||||||
support by doing
|
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
|
||||||
cabal install -fserver -fc-runtime
|
|
||||||
```
|
|
||||||
from the top directory. This give you three new things:
|
|
||||||
|
|
||||||
- ``PGF2``: a module to import in Haskell programs, providing a binding to
|
``$ bash install.sh``
|
||||||
the C run-time system.
|
|
||||||
|
|
||||||
- The GF shell can be started with ``gf -cshell`` or ``gf -crun`` to use
|
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.
|
the C run-time system instead of the Haskell run-time system.
|
||||||
Only limited functionality is available when running the shell in these
|
Only limited functionality is available when running the shell in these
|
||||||
modes (use the ``help`` command in the shell for details).
|
modes (use the ``help`` command in the shell for details).
|
||||||
|
|
||||||
- ``gf -server`` mode is extended with new requests to call the C run-time
|
(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 -fc-runtime
|
||||||
|
```
|
||||||
|
|
||||||
|
from the top directory (``gf-core``).
|
||||||
|
|
||||||
|
If you use stack, uncomment the following lines in the ``stack.yaml`` file:
|
||||||
|
|
||||||
|
```
|
||||||
|
flags:
|
||||||
|
gf:
|
||||||
|
c-runtime: true
|
||||||
|
extra-lib-dirs:
|
||||||
|
- /usr/local/lib
|
||||||
|
```
|
||||||
|
and then run ``stack install`` from the top directory (``gf-core``).
|
||||||
|
|
||||||
|
|
||||||
|
//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``.
|
system, e.g. ``c-parse``, ``c-linearize`` and ``c-translate``.
|
||||||
|
|
||||||
|
- **How —**
|
||||||
|
If you use cabal, run the following command:
|
||||||
|
|
||||||
=== Python and Java bindings ===
|
```
|
||||||
|
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 ==
|
== Compilation of RGL ==
|
||||||
|
|
||||||
As of 2018-07-26, the RGL is distributed separately from the GF compiler and runtimes.
|
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 ===
|
=== Simple ===
|
||||||
To install the RGL, you can use the following commands from within the ``gf-rgl`` repository:
|
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 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
|
https://github.com/GrammaticalFramework/gf-core/actions/workflows/build-binary-packages.yml
|
||||||
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.
|
|
||||||
|
|
||||||
Under Ubuntu, Haskell executables are statically linked against other Haskell
|
|
||||||
libraries, so the .deb packages are fairly self-contained.
|
|
||||||
|
|
||||||
==== Preparations ====
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo apt-get install dpkg-dev debhelper
|
|
||||||
```
|
|
||||||
|
|
||||||
==== Creating the package ====
|
|
||||||
|
|
||||||
Make sure the ``debian/changelog`` starts with an entry that describes the
|
|
||||||
version you are building. Then run
|
|
||||||
|
|
||||||
```
|
|
||||||
make deb
|
|
||||||
```
|
|
||||||
|
|
||||||
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 test suite ==
|
== Running the test suite ==
|
||||||
|
|
||||||
**NOTE:** The test suite has not been maintained recently, so expect many
|
The GF test suite is run with one of the following commands from the top directory:
|
||||||
tests to fail.
|
|
||||||
%% // TH 2012-08-06
|
|
||||||
|
|
||||||
GF has testsuite. It is run with the following command:
|
|
||||||
```
|
```
|
||||||
$ cabal test
|
$ cabal test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```
|
||||||
|
$ stack test
|
||||||
|
```
|
||||||
|
|
||||||
The testsuite architecture for GF is very simple but still very flexible.
|
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.
|
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
|
This is everything that we need to organize a testsuite. The root of the
|
||||||
testsuite is the testsuite/ directory. It contains subdirectories which
|
testsuite is the ``testsuite/`` directory. It contains subdirectories
|
||||||
themself contain GF batch files (with extension .gfs). The above command
|
which themselves contain GF batch files (with extension ``.gfs``).
|
||||||
searches the subdirectories of the testsuite/ directory for files with extension
|
The above command searches the subdirectories of the ``testsuite/`` directory
|
||||||
.gfs and when it finds one it is executed with the GF interpreter.
|
for files with extension ``.gfs`` and when it finds one, it is executed with
|
||||||
The output of the script is stored in file with extension .out and is compared
|
the GF interpreter. The output of the script is stored in file with extension ``.out``
|
||||||
with the content of the corresponding file with extension .gold, if there is one.
|
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.
|
|
||||||
|
|
||||||
Every time when you make some changes to GF that have to be tested, instead of
|
Every time when you make some changes to GF that have to be tested,
|
||||||
writing the commands by hand in the GF shell, add them to one .gfs file in the testsuite
|
instead of writing the commands by hand in the GF shell, add them to one ``.gfs``
|
||||||
and run the test. In this way you can use the same test later and we will be sure
|
file in the testsuite subdirectory where its ``.gf`` file resides and run the test.
|
||||||
that we will not incidentaly break your code later.
|
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==
|
==Atom==
|
||||||
[language-gf https://atom.io/packages/language-gf], by John J. Camilleri
|
[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==
|
==Eclipse==
|
||||||
|
|
||||||
[GF Eclipse Plugin https://github.com/GrammaticalFramework/gf-eclipse-plugin/], by John J. Camilleri
|
[GF Eclipse Plugin https://github.com/GrammaticalFramework/gf-eclipse-plugin/], by John J. Camilleri
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
---
|
---
|
||||||
title: Grammatical Framework Download and Installation
|
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).
|
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.
|
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
|
#### 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:
|
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
|
#### macOS
|
||||||
|
|
||||||
To install the package, just double-click it and follow the installer instructions.
|
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
|
#### 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).
|
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
|
[GF is on Hackage](http://hackage.haskell.org/package/gf), so under
|
||||||
normal circumstances the procedure is fairly simple:
|
normal circumstances the procedure is fairly simple:
|
||||||
@@ -89,7 +93,7 @@ Here is one way to do this:
|
|||||||
**GHC version**
|
**GHC version**
|
||||||
|
|
||||||
The GF source code has been updated to compile with GHC versions 7.10 through to 8.8.
|
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
|
## Installing from the latest developer source code
|
||||||
|
|
||||||
If you haven't already, clone the repository with:
|
If you haven't already, clone the repository with:
|
||||||
@@ -116,7 +120,7 @@ or, if you're a Stack user:
|
|||||||
stack install
|
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
|
For more info on working with the GF source code, see the
|
||||||
[GF Developers Guide](../doc/gf-developers.html).
|
[GF Developers Guide](../doc/gf-developers.html).
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<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>
|
</head>
|
||||||
<body>
|
<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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
title: GF 3.11 Release Notes
|
title: GF 3.11 Release Notes
|
||||||
date: ... December 2020
|
date: 25 July 2021
|
||||||
...
|
---
|
||||||
|
|
||||||
## Installation
|
## 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.
|
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).
|
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.
|
since the release of GF 3.10 in December 2018.
|
||||||
|
|
||||||
## General
|
## General
|
||||||
|
|
||||||
- Make the test suite work again.
|
- Make the test suite work again.
|
||||||
- Compatibility with new versions of GHC, including multiple Stack files for the different versions.
|
- Compatibility with new versions of GHC, including multiple Stack files for the different versions.
|
||||||
- Updates to build scripts and CI.
|
- Support for newer version of Ubuntu 20.04 in the precompiled binaries.
|
||||||
- Bug fixes.
|
- Updates to build scripts and CI workflows.
|
||||||
|
- Bug fixes and code cleanup.
|
||||||
|
|
||||||
## GF compiler and run-time library
|
## 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 CoNLL output to `visualize_tree` shell command.
|
||||||
- Add canonical GF as output format in the compiler.
|
- Add canonical GF as output format in the compiler.
|
||||||
- Add PGF JSON 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).
|
- 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 Haskell export.
|
||||||
|
- Improvements to the GF shell.
|
||||||
|
- Improvements to canonical GF compilation.
|
||||||
- Improvements to the C runtime.
|
- Improvements to the C runtime.
|
||||||
- Improvements to `gf -server` mode.
|
- Improvements to `gf -server` mode.
|
||||||
- Clearer compiler error messages.
|
- Clearer compiler error messages.
|
||||||
|
|||||||
565
gf.cabal
565
gf.cabal
@@ -1,17 +1,16 @@
|
|||||||
name: gf
|
name: gf
|
||||||
version: 3.10.4-git
|
version: 3.11.0-git
|
||||||
|
|
||||||
cabal-version: >= 1.22
|
cabal-version: 1.22
|
||||||
build-type: Custom
|
build-type: Custom
|
||||||
license: OtherLicense
|
license: OtherLicense
|
||||||
license-file: LICENSE
|
license-file: LICENSE
|
||||||
category: Natural Language Processing, Compiler
|
category: Natural Language Processing, Compiler
|
||||||
synopsis: Grammatical Framework
|
synopsis: Grammatical Framework
|
||||||
description: GF, Grammatical Framework, is a programming language for multilingual grammar applications
|
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
|
bug-reports: https://github.com/GrammaticalFramework/gf-core/issues
|
||||||
maintainer: Thomas Hallgren
|
tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.10.4
|
||||||
tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.3
|
|
||||||
|
|
||||||
data-dir: src
|
data-dir: src
|
||||||
extra-source-files: WebSetup.hs
|
extra-source-files: WebSetup.hs
|
||||||
@@ -42,11 +41,11 @@ data-files:
|
|||||||
|
|
||||||
custom-setup
|
custom-setup
|
||||||
setup-depends:
|
setup-depends:
|
||||||
base,
|
base >= 4.9.1 && < 4.15,
|
||||||
Cabal >= 1.22.0.0,
|
Cabal >= 1.22.0.0,
|
||||||
directory,
|
directory >= 1.3.0 && < 1.4,
|
||||||
filepath,
|
filepath >= 1.4.1 && < 1.5,
|
||||||
process >=1.0.1.1
|
process >= 1.0.1.1 && < 1.7
|
||||||
|
|
||||||
source-repository head
|
source-repository head
|
||||||
type: git
|
type: git
|
||||||
@@ -74,20 +73,28 @@ flag c-runtime
|
|||||||
|
|
||||||
library
|
library
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
build-depends: base >= 4.6 && <5,
|
build-depends:
|
||||||
array,
|
-- GHC 8.0.2 to GHC 8.10.4
|
||||||
containers,
|
array >= 0.5.1 && < 0.6,
|
||||||
bytestring,
|
base >= 4.9.1 && < 4.15,
|
||||||
utf8-string,
|
bytestring >= 0.10.8 && < 0.11,
|
||||||
random,
|
containers >= 0.5.7 && < 0.7,
|
||||||
pretty,
|
exceptions >= 0.8.3 && < 0.11,
|
||||||
mtl,
|
ghc-prim >= 0.5.0 && < 0.7,
|
||||||
exceptions,
|
hashable >= 1.2.6 && < 1.4,
|
||||||
fail,
|
mtl >= 2.2.1 && < 2.3,
|
||||||
-- For compatability with ghc < 8
|
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.
|
-- We need transformers-compat >= 0.6.3, but that is only in newer snapshots where it is redundant.
|
||||||
transformers-compat,
|
transformers-compat >= 0.5.1.4 && < 0.7
|
||||||
ghc-prim
|
|
||||||
|
if impl(ghc<8.0)
|
||||||
|
build-depends:
|
||||||
|
fail >= 4.9.0 && < 4.10
|
||||||
|
|
||||||
hs-source-dirs: src/runtime/haskell
|
hs-source-dirs: src/runtime/haskell
|
||||||
|
|
||||||
other-modules:
|
other-modules:
|
||||||
@@ -105,11 +112,13 @@ library
|
|||||||
ghc-prof-options: -fprof-auto
|
ghc-prof-options: -fprof-auto
|
||||||
|
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
|
LPGF
|
||||||
PGF
|
PGF
|
||||||
PGF.Internal
|
PGF.Internal
|
||||||
PGF.Haskell
|
PGF.Haskell
|
||||||
|
|
||||||
other-modules:
|
other-modules:
|
||||||
|
LPGF.Internal
|
||||||
PGF.Data
|
PGF.Data
|
||||||
PGF.Macros
|
PGF.Macros
|
||||||
PGF.Binary
|
PGF.Binary
|
||||||
@@ -136,8 +145,12 @@ library
|
|||||||
|
|
||||||
if flag(c-runtime)
|
if flag(c-runtime)
|
||||||
exposed-modules: PGF2
|
exposed-modules: PGF2
|
||||||
other-modules: PGF2.FFI PGF2.Expr PGF2.Type
|
other-modules:
|
||||||
GF.Interactive2 GF.Command.Commands2
|
PGF2.FFI
|
||||||
|
PGF2.Expr
|
||||||
|
PGF2.Type
|
||||||
|
GF.Interactive2
|
||||||
|
GF.Command.Commands2
|
||||||
hs-source-dirs: src/runtime/haskell-bind
|
hs-source-dirs: src/runtime/haskell-bind
|
||||||
build-tools: hsc2hs
|
build-tools: hsc2hs
|
||||||
extra-libraries: pgf gu
|
extra-libraries: pgf gu
|
||||||
@@ -146,8 +159,14 @@ library
|
|||||||
|
|
||||||
---- GF compiler as a library:
|
---- GF compiler as a library:
|
||||||
|
|
||||||
build-depends: filepath, directory>=1.2, time,
|
build-depends:
|
||||||
process, haskeline, parallel>=3, json
|
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
|
hs-source-dirs: src/compiler
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
@@ -158,12 +177,19 @@ library
|
|||||||
GF.Grammar.Canonical
|
GF.Grammar.Canonical
|
||||||
|
|
||||||
other-modules:
|
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.Grammar
|
||||||
|
|
||||||
GF.Data.Operations GF.Infra.Option GF.Infra.UseIO
|
GF.Data.Operations
|
||||||
|
GF.Infra.Option
|
||||||
|
GF.Infra.UseIO
|
||||||
|
|
||||||
GF.Command.Abstract
|
GF.Command.Abstract
|
||||||
GF.Command.CommandInfo
|
GF.Command.CommandInfo
|
||||||
@@ -185,6 +211,7 @@ library
|
|||||||
GF.Compile.Export
|
GF.Compile.Export
|
||||||
GF.Compile.GenerateBC
|
GF.Compile.GenerateBC
|
||||||
GF.Compile.GeneratePMCFG
|
GF.Compile.GeneratePMCFG
|
||||||
|
GF.Compile.GrammarToLPGF
|
||||||
GF.Compile.GrammarToPGF
|
GF.Compile.GrammarToPGF
|
||||||
GF.Compile.Multi
|
GF.Compile.Multi
|
||||||
GF.Compile.Optimize
|
GF.Compile.Optimize
|
||||||
@@ -213,6 +240,7 @@ library
|
|||||||
GF.Data.ErrM
|
GF.Data.ErrM
|
||||||
GF.Data.Graph
|
GF.Data.Graph
|
||||||
GF.Data.Graphviz
|
GF.Data.Graphviz
|
||||||
|
GF.Data.IntMapBuilder
|
||||||
GF.Data.Relation
|
GF.Data.Relation
|
||||||
GF.Data.Str
|
GF.Data.Str
|
||||||
GF.Data.Utilities
|
GF.Data.Utilities
|
||||||
@@ -273,12 +301,17 @@ library
|
|||||||
cpp-options: -DC_RUNTIME
|
cpp-options: -DC_RUNTIME
|
||||||
|
|
||||||
if flag(server)
|
if flag(server)
|
||||||
build-depends: httpd-shed>=0.4.0.3, network>=2.3 && <2.7,
|
build-depends:
|
||||||
cgi>=3001.2.2.0
|
cgi >= 3001.3.0.2 && < 3001.6,
|
||||||
|
httpd-shed >= 0.4.0 && < 0.5,
|
||||||
|
network>=2.3 && <2.7
|
||||||
if flag(network-uri)
|
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
|
else
|
||||||
build-depends: network<2.6
|
build-depends:
|
||||||
|
network >= 2.5 && <2.6
|
||||||
|
|
||||||
cpp-options: -DSERVER_MODE
|
cpp-options: -DSERVER_MODE
|
||||||
other-modules:
|
other-modules:
|
||||||
@@ -295,7 +328,10 @@ library
|
|||||||
Fold
|
Fold
|
||||||
ExampleDemo
|
ExampleDemo
|
||||||
ExampleService
|
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)
|
if flag(interrupt)
|
||||||
cpp-options: -DUSE_INTERRUPT
|
cpp-options: -DUSE_INTERRUPT
|
||||||
@@ -304,17 +340,24 @@ library
|
|||||||
other-modules: GF.System.NoSignal
|
other-modules: GF.System.NoSignal
|
||||||
|
|
||||||
if impl(ghc>=7.8)
|
if impl(ghc>=7.8)
|
||||||
build-tools: happy>=1.19, alex>=3.1
|
build-tools:
|
||||||
|
happy>=1.19,
|
||||||
|
alex>=3.1
|
||||||
-- ghc-options: +RTS -A20M -RTS
|
-- ghc-options: +RTS -A20M -RTS
|
||||||
else
|
else
|
||||||
build-tools: happy, alex>=3
|
build-tools:
|
||||||
|
happy,
|
||||||
|
alex>=3
|
||||||
|
|
||||||
ghc-options: -fno-warn-tabs
|
ghc-options: -fno-warn-tabs
|
||||||
|
|
||||||
if os(windows)
|
if os(windows)
|
||||||
build-depends: Win32
|
build-depends:
|
||||||
|
Win32 >= 2.3.1.1 && < 2.7
|
||||||
else
|
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)
|
if impl(ghc>=8.2)
|
||||||
ghc-options: -fhide-source-paths
|
ghc-options: -fhide-source-paths
|
||||||
@@ -323,7 +366,9 @@ executable gf
|
|||||||
hs-source-dirs: src/programs
|
hs-source-dirs: src/programs
|
||||||
main-is: gf-main.hs
|
main-is: gf-main.hs
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
build-depends: gf, base
|
build-depends:
|
||||||
|
gf,
|
||||||
|
base
|
||||||
ghc-options: -threaded
|
ghc-options: -threaded
|
||||||
--ghc-options: -fwarn-unused-imports
|
--ghc-options: -fwarn-unused-imports
|
||||||
|
|
||||||
@@ -337,20 +382,442 @@ executable gf
|
|||||||
if impl(ghc>=8.2)
|
if impl(ghc>=8.2)
|
||||||
ghc-options: -fhide-source-paths
|
ghc-options: -fhide-source-paths
|
||||||
|
|
||||||
executable pgf-shell
|
-- executable pgf-shell
|
||||||
--if !flag(c-runtime)
|
-- --if !flag(c-runtime)
|
||||||
buildable: False
|
-- buildable: False
|
||||||
main-is: pgf-shell.hs
|
-- main-is: pgf-shell.hs
|
||||||
hs-source-dirs: src/runtime/haskell-bind/examples
|
-- hs-source-dirs: src/runtime/haskell-bind/examples
|
||||||
build-depends: gf, base, containers, mtl, lifted-base
|
-- build-depends:
|
||||||
default-language: Haskell2010
|
-- gf,
|
||||||
if impl(ghc>=7.0)
|
-- base,
|
||||||
ghc-options: -rtsopts
|
-- containers,
|
||||||
|
-- mtl,
|
||||||
|
-- lifted-base
|
||||||
|
-- default-language: Haskell2010
|
||||||
|
-- if impl(ghc>=7.0)
|
||||||
|
-- ghc-options: -rtsopts
|
||||||
|
|
||||||
test-suite gf-tests
|
test-suite gf-tests
|
||||||
type: exitcode-stdio-1.0
|
type: exitcode-stdio-1.0
|
||||||
main-is: run.hs
|
main-is: run.hs
|
||||||
hs-source-dirs: testsuite
|
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
|
build-tool-depends: gf:gf
|
||||||
default-language: Haskell2010
|
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>
|
||||||
|
|
||||||
<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.
|
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://webchat.freenode.net/?channels=gf">open a web chat</a>
|
You can <a href="https://web.libera.chat/?channels=#gf">open a web chat</a>
|
||||||
or <a href="/irc/">browse the channel logs</a>.
|
or <a href="https://www.grammaticalframework.org/irc/?C=M;O=D">browse the channel logs</a>.
|
||||||
</p>
|
</p>
|
||||||
<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>.
|
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">
|
<div class="col-md-6">
|
||||||
<h2>News</h2>
|
<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">
|
<dl class="row">
|
||||||
<dt class="col-sm-3 text-center text-nowrap">2021-05-05</dt>
|
<dt class="col-sm-3 text-center text-nowrap">2021-05-05</dt>
|
||||||
<dd class="col-sm-9">
|
<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>
|
</dd>
|
||||||
<dt class="col-sm-3 text-center text-nowrap">2021-03-01</dt>
|
<dt class="col-sm-3 text-center text-nowrap">2021-03-01</dt>
|
||||||
<dd class="col-sm-9">
|
<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>
|
</dd>
|
||||||
<dt class="col-sm-3 text-center text-nowrap">2020-09-29</dt>
|
<dt class="col-sm-3 text-center text-nowrap">2020-09-29</dt>
|
||||||
<dd class="col-sm-9">
|
<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.GrammarToPGF(mkCanon2pgf)
|
||||||
|
import GF.Compile.GrammarToLPGF(mkCanon2lpgf)
|
||||||
import GF.Compile.ReadFiles(ModEnv,getOptionsFromFile,getAllFiles,
|
import GF.Compile.ReadFiles(ModEnv,getOptionsFromFile,getAllFiles,
|
||||||
importsOfModule)
|
importsOfModule)
|
||||||
import GF.CompileOne(compileOne)
|
import GF.CompileOne(compileOne)
|
||||||
@@ -14,7 +15,7 @@ import GF.Infra.UseIO(IOE,FullPath,liftIO,getLibraryDirectory,putIfVerb,
|
|||||||
justModuleName,extendPathEnv,putStrE,putPointE)
|
justModuleName,extendPathEnv,putStrE,putPointE)
|
||||||
import GF.Data.Operations(raise,(+++),err)
|
import GF.Data.Operations(raise,(+++),err)
|
||||||
|
|
||||||
import Control.Monad(foldM,when,(<=<),filterM,liftM)
|
import Control.Monad(foldM,when,(<=<),filterM)
|
||||||
import GF.System.Directory(doesFileExist,getModificationTime)
|
import GF.System.Directory(doesFileExist,getModificationTime)
|
||||||
import System.FilePath((</>),isRelative,dropFileName)
|
import System.FilePath((</>),isRelative,dropFileName)
|
||||||
import qualified Data.Map as Map(empty,insert,elems) --lookup
|
import qualified Data.Map as Map(empty,insert,elems) --lookup
|
||||||
@@ -24,12 +25,16 @@ import GF.Text.Pretty(render,($$),(<+>),nest)
|
|||||||
|
|
||||||
import PGF.Internal(optimizePGF)
|
import PGF.Internal(optimizePGF)
|
||||||
import PGF(PGF,defaultProbabilities,setProbabilities,readProbabilitiesFromFile)
|
import PGF(PGF,defaultProbabilities,setProbabilities,readProbabilitiesFromFile)
|
||||||
|
import LPGF(LPGF)
|
||||||
|
|
||||||
-- | Compiles a number of source files and builds a 'PGF' structure for them.
|
-- | Compiles a number of source files and builds a 'PGF' structure for them.
|
||||||
-- This is a composition of 'link' and 'batchCompile'.
|
-- This is a composition of 'link' and 'batchCompile'.
|
||||||
compileToPGF :: Options -> [FilePath] -> IOE PGF
|
compileToPGF :: Options -> [FilePath] -> IOE PGF
|
||||||
compileToPGF opts fs = link opts . snd =<< batchCompile opts fs
|
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
|
-- | Link a grammar into a 'PGF' that can be used to 'PGF.linearize' and
|
||||||
-- 'PGF.parse' with the "PGF" run-time system.
|
-- 'PGF.parse' with the "PGF" run-time system.
|
||||||
link :: Options -> (ModuleName,Grammar) -> IOE PGF
|
link :: Options -> (ModuleName,Grammar) -> IOE PGF
|
||||||
@@ -42,6 +47,14 @@ link opts (cnc,gr) =
|
|||||||
return $ setProbabilities probs
|
return $ setProbabilities probs
|
||||||
$ if flag optOptimizePGF opts then optimizePGF pgf else pgf
|
$ 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
|
-- | Returns the name of the abstract syntax corresponding to the named concrete syntax
|
||||||
srcAbsName gr cnc = err (const cnc) id $ abstractOfConcrete gr cnc
|
srcAbsName gr cnc = err (const cnc) id $ abstractOfConcrete gr cnc
|
||||||
|
|
||||||
|
|||||||
@@ -30,11 +30,12 @@ import Debug.Trace(trace)
|
|||||||
normalForm :: GlobalEnv -> L Ident -> Term -> Term
|
normalForm :: GlobalEnv -> L Ident -> Term -> Term
|
||||||
normalForm (GE gr rv opts _) loc = err (bugloc loc) id . nfx (GE gr rv opts loc)
|
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
|
nfx env@(GE _ _ _ loc) t = do
|
||||||
v <- eval env [] t
|
v <- eval env [] t
|
||||||
case value2term loc [] v of
|
return (value2term loc [] v)
|
||||||
Left i -> fail ("variable #"++show i++" is out of scope")
|
-- Old value2term error message:
|
||||||
Right t -> return t
|
-- Left i -> fail ("variable #"++show i++" is out of scope")
|
||||||
|
|
||||||
eval :: GlobalEnv -> Env -> Term -> Err Value
|
eval :: GlobalEnv -> Env -> Term -> Err Value
|
||||||
eval (GE gr rvs opts loc) env t = ($ (map snd env)) # value cenv t
|
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)
|
(v1,v2) -> if flag optPlusAsBind (opts env)
|
||||||
then VC v1 (VC (VApp BIND []) v2)
|
then VC v1 (VC (VApp BIND []) v2)
|
||||||
else let loc = gloc env
|
else let loc = gloc env
|
||||||
vt v = case value2term loc (local env) v of
|
vt v = value2term loc (local env) v
|
||||||
Left i -> Error ('#':show i)
|
-- Old value2term error message:
|
||||||
Right t -> t
|
-- Left i -> Error ('#':show i)
|
||||||
originalMsg = render $ ppL loc (hang "unsupported token gluing" 4
|
originalMsg = render $ ppL loc (hang "unsupported token gluing" 4
|
||||||
(Glue (vt v1) (vt v2)))
|
(Glue (vt v1) (vt v2)))
|
||||||
term = render $ pp $ 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
|
(v1,v2) -> ok2 VS v1 v2
|
||||||
|
|
||||||
match loc cs v =
|
match loc cs v =
|
||||||
case value2term loc [] v of
|
err bad return (matchPattern cs (value2term loc [] v))
|
||||||
Left i -> bad ("variable #"++show i++" is out of scope")
|
-- Old value2term error message:
|
||||||
Right t -> err bad return (matchPattern cs t)
|
-- Left i -> bad ("variable #"++show i++" is out of scope")
|
||||||
where
|
where
|
||||||
bad = fail . ("In pattern matching: "++)
|
bad = fail . ("In pattern matching: "++)
|
||||||
|
|
||||||
@@ -383,9 +384,8 @@ valueTable env i cs =
|
|||||||
wild = case i of TWild _ -> True; _ -> False
|
wild = case i of TWild _ -> True; _ -> False
|
||||||
|
|
||||||
convertv cs' vty =
|
convertv cs' vty =
|
||||||
case value2term (gloc env) [] vty of
|
convert' cs' =<< paramValues'' env (value2term (gloc env) [] vty)
|
||||||
Left i -> fail ("variable #"++show i++" is out of scope")
|
-- Old value2term error message: Left i -> fail ("variable #"++show i++" is out of scope")
|
||||||
Right pty -> convert' cs' =<< paramValues'' env pty
|
|
||||||
|
|
||||||
convert cs' ty = convert' cs' =<< paramValues' env ty
|
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 (_,VString n) = pp n
|
||||||
pf (_,v) = ppV v
|
pf (_,v) = ppV v
|
||||||
pa (_,v) = ppV v
|
pa (_,v) = ppV v
|
||||||
ppV v = case value2term' True loc [] v of
|
ppV v = ppTerm Unqualified 10 (value2term' True loc [] v)
|
||||||
Left i -> "variable #" <> pp i <+> "is out of scope"
|
-- Old value2term error message:
|
||||||
Right t -> ppTerm Unqualified 10 t
|
-- Left i -> "variable #" <> pp i <+> "is out of scope"
|
||||||
|
|
||||||
-- | Convert a value back to a term
|
-- | Convert a value back to a term
|
||||||
value2term :: GLocation -> [Ident] -> Value -> Either Int Term
|
value2term :: GLocation -> [Ident] -> Value -> Term
|
||||||
value2term = value2term' False
|
value2term = value2term' False
|
||||||
|
|
||||||
|
value2term' :: Bool -> p -> [Ident] -> Value -> Term
|
||||||
value2term' stop loc xs v0 =
|
value2term' stop loc xs v0 =
|
||||||
case v0 of
|
case v0 of
|
||||||
VApp pre vs -> liftM (foldl App (Q (cPredef,predefName pre))) (mapM v2t vs)
|
VApp pre vs -> applyMany (Q (cPredef,predefName pre)) vs
|
||||||
VCApp f vs -> liftM (foldl App (QC f)) (mapM v2t vs)
|
VCApp f vs -> applyMany (QC f) vs
|
||||||
VGen j vs -> liftM2 (foldl App) (var j) (mapM v2t vs)
|
VGen j vs -> applyMany (var j) vs
|
||||||
VMeta j env vs -> liftM (foldl App (Meta j)) (mapM v2t vs)
|
VMeta j env vs -> applyMany (Meta j) vs
|
||||||
VProd bt v x f -> liftM2 (Prod bt x) (v2t v) (v2t' x f)
|
VProd bt v x f -> Prod bt x (v2t v) (v2t' x f)
|
||||||
VAbs bt x f -> liftM (Abs bt x) (v2t' x f)
|
VAbs bt x f -> Abs bt x (v2t' x f)
|
||||||
VInt n -> return (EInt n)
|
VInt n -> EInt n
|
||||||
VFloat f -> return (EFloat f)
|
VFloat f -> EFloat f
|
||||||
VString s -> return (if null s then Empty else K s)
|
VString s -> if null s then Empty else K s
|
||||||
VSort s -> return (Sort s)
|
VSort s -> Sort s
|
||||||
VImplArg v -> liftM ImplArg (v2t v)
|
VImplArg v -> ImplArg (v2t v)
|
||||||
VTblType p res -> liftM2 Table (v2t p) (v2t res)
|
VTblType p res -> Table (v2t p) (v2t res)
|
||||||
VRecType rs -> liftM RecType (mapM (\(l,v) -> fmap ((,) l) (v2t v)) rs)
|
VRecType rs -> RecType [(l, v2t v) | (l,v) <- rs]
|
||||||
VRec as -> liftM R (mapM (\(l,v) -> v2t v >>= \t -> return (l,(Nothing,t))) as)
|
VRec as -> R [(l, (Nothing, v2t v)) | (l,v) <- as]
|
||||||
VV t _ vs -> liftM (V t) (mapM v2t vs)
|
VV t _ vs -> V t (map v2t vs)
|
||||||
VT wild v cs -> v2t v >>= \t -> liftM (T ((if wild then TWild else TTyped) t)) (mapM nfcase cs)
|
VT wild v cs -> T ((if wild then TWild else TTyped) (v2t v)) (map nfcase cs)
|
||||||
VFV vs -> liftM FV (mapM v2t vs)
|
VFV vs -> FV (map v2t vs)
|
||||||
VC v1 v2 -> liftM2 C (v2t v1) (v2t v2)
|
VC v1 v2 -> C (v2t v1) (v2t v2)
|
||||||
VS v1 v2 -> liftM2 S (v2t v1) (v2t v2)
|
VS v1 v2 -> S (v2t v1) (v2t v2)
|
||||||
VP v l -> v2t v >>= \t -> return (P t l)
|
VP v l -> P (v2t v) l
|
||||||
VPatt p -> return (EPatt p)
|
VPatt p -> EPatt p
|
||||||
VPattType v -> v2t v >>= return . EPattType
|
VPattType v -> EPattType $ v2t v
|
||||||
VAlts v vvs -> liftM2 Alts (v2t v) (mapM (\(x,y) -> liftM2 (,) (v2t x) (v2t y)) vvs)
|
VAlts v vvs -> Alts (v2t v) [(v2t x, v2t y) | (x,y) <- vvs]
|
||||||
VStrs vs -> liftM Strs (mapM v2t vs)
|
VStrs vs -> Strs (map v2t vs)
|
||||||
-- VGlue v1 v2 -> Glue (v2t v1) (v2t v2)
|
-- VGlue v1 v2 -> Glue (v2t v1) (v2t v2)
|
||||||
-- VExtR v1 v2 -> ExtR (v2t v1) (v2t v2)
|
-- VExtR v1 v2 -> ExtR (v2t v1) (v2t v2)
|
||||||
VError err -> return (Error err)
|
VError err -> Error err
|
||||||
|
|
||||||
where
|
where
|
||||||
|
applyMany f vs = foldl App f (map v2t vs)
|
||||||
v2t = v2txs xs
|
v2t = v2txs xs
|
||||||
v2txs = value2term' stop loc
|
v2txs = value2term' stop loc
|
||||||
v2t' x f = v2txs (x:xs) (bind f (gen xs))
|
v2t' x f = v2txs (x:xs) (bind f (gen xs))
|
||||||
|
|
||||||
var j
|
var j
|
||||||
| j<length xs = Right (Vr (reverse xs !! j))
|
| j<length xs = Vr (reverse xs !! j)
|
||||||
| otherwise = Left j
|
| otherwise = error ("variable #"++show j++" is out of scope")
|
||||||
|
|
||||||
|
|
||||||
pushs xs e = foldr push e xs
|
pushs xs e = foldr push e xs
|
||||||
push x (env,xs) = ((x,gen xs):env,x:xs)
|
push x (env,xs) = ((x,gen xs):env,x:xs)
|
||||||
gen xs = VGen (length 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)
|
where (env',xs') = pushs (pattVars p) ([],xs)
|
||||||
|
|
||||||
bind (Bind f) x = if stop
|
bind (Bind f) x = if stop
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ instance Predef Int where
|
|||||||
|
|
||||||
instance Predef Bool where
|
instance Predef Bool where
|
||||||
toValue = boolV
|
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
|
instance Predef String where
|
||||||
toValue = string
|
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
|
lockRecType c t' ---- locking to be removed AR 20/6/2009
|
||||||
|
|
||||||
_ | ty == typeTok -> return typeStr
|
_ | ty == typeTok -> return typeStr
|
||||||
_ | isPredefConstant ty -> return ty
|
|
||||||
|
|
||||||
_ -> composOp (comp g) 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)
|
Bound ty1 -> do v <- liftErr (eval ge env ty1)
|
||||||
unify ge scope (vapply (geLoc ge) v vs) ty2
|
unify ge scope (vapply (geLoc ge) v vs) ty2
|
||||||
Unbound scope' _ -> case value2term (geLoc ge) (scopeVars scope') ty2 of
|
Unbound scope' _ -> case value2term (geLoc ge) (scopeVars scope') ty2 of
|
||||||
Left i -> let (v,_) = reverse scope !! i
|
-- Left i -> let (v,_) = reverse scope !! i
|
||||||
in tcError ("Variable" <+> pp v <+> "has escaped")
|
-- in tcError ("Variable" <+> pp v <+> "has escaped")
|
||||||
Right ty2' -> do ms2 <- getMetaVars (geLoc ge) [(scope,ty2)]
|
ty2' -> do ms2 <- getMetaVars (geLoc ge) [(scope,ty2)]
|
||||||
if i `elem` ms2
|
if i `elem` ms2
|
||||||
then tcError ("Occurs check for" <+> ppMeta i <+> "in:" $$
|
then tcError ("Occurs check for" <+> ppMeta i <+> "in:" $$
|
||||||
nest 2 (ppTerm Unqualified 0 ty2'))
|
nest 2 (ppTerm Unqualified 0 ty2'))
|
||||||
@@ -765,9 +765,9 @@ zonkTerm (Meta i) = do
|
|||||||
zonkTerm t = composOp zonkTerm t
|
zonkTerm t = composOp zonkTerm t
|
||||||
|
|
||||||
tc_value2term loc xs v =
|
tc_value2term loc xs v =
|
||||||
case value2term loc xs v of
|
return $ value2term loc xs v
|
||||||
Left i -> tcError ("Variable #" <+> pp i <+> "has escaped")
|
-- Old value2term error message:
|
||||||
Right t -> return t
|
-- Left i -> tcError ("Variable #" <+> pp i <+> "has escaped")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
-- Thierry Coquand's type checking algorithm that creates a trace
|
-- Thierry Coquand's type checking algorithm that creates a trace
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
module GF.Compile.TypeCheck.TC (AExp(..),
|
module GF.Compile.TypeCheck.TC (
|
||||||
|
AExp(..),
|
||||||
Theory,
|
Theory,
|
||||||
checkExp,
|
checkExp,
|
||||||
inferExp,
|
inferExp,
|
||||||
@@ -321,4 +322,3 @@ mkAnnot :: (Val -> AExp) -> Err (Val,[(Val,Val)]) -> Err (AExp,Val,[(Val,Val)])
|
|||||||
mkAnnot a ti = do
|
mkAnnot a ti = do
|
||||||
(v,cs) <- ti
|
(v,cs) <- ti
|
||||||
return (a v, v, cs)
|
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
|
buildAnyTree m = go Map.empty
|
||||||
where
|
where
|
||||||
go map [] = return map
|
go map [] = return map
|
||||||
go map ((c,j):is) = do
|
go map ((c,j):is) =
|
||||||
case Map.lookup c map of
|
case Map.lookup c map of
|
||||||
Just i -> case unifyAnyInfo m i j of
|
Just i -> case unifyAnyInfo m i j of
|
||||||
Ok k -> go (Map.insert c k map) is
|
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
|
||||||
import PGF.Internal(concretes,optimizePGF,unionPGF)
|
import PGF.Internal(concretes,optimizePGF,unionPGF)
|
||||||
import PGF.Internal(putSplitAbs,encodeFile,runPut)
|
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.CompileInParallel as P(parallelBatchCompile)
|
||||||
import GF.Compile.Export
|
import GF.Compile.Export
|
||||||
import GF.Compile.ConcreteToHaskell(concretes2haskell)
|
import GF.Compile.ConcreteToHaskell(concretes2haskell)
|
||||||
@@ -11,7 +13,8 @@ import GF.Compile.GrammarToCanonical--(concretes2canonical)
|
|||||||
import GF.Compile.CFGtoPGF
|
import GF.Compile.CFGtoPGF
|
||||||
import GF.Compile.GetGrammar
|
import GF.Compile.GetGrammar
|
||||||
import GF.Grammar.BNFC
|
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.Ident(showIdent)
|
||||||
import GF.Infra.UseIO
|
import GF.Infra.UseIO
|
||||||
@@ -23,10 +26,11 @@ import GF.Text.Pretty(render,render80)
|
|||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
|
import Data.Time(UTCTime)
|
||||||
import qualified Data.ByteString.Lazy as BSL
|
import qualified Data.ByteString.Lazy as BSL
|
||||||
import GF.Grammar.CanonicalJSON (encodeJSON)
|
import GF.Grammar.CanonicalJSON (encodeJSON)
|
||||||
import System.FilePath
|
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
|
-- | 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@)
|
-- 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
|
-- 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
|
-- source grammar files (as indicated by the 'UTCTime' argument), it is not
|
||||||
-- recreated. Calls 'writePGF' and 'writeOutputs'.
|
-- 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):_)) =
|
linkGrammars opts (t_src,~cnc_grs@(~(cnc,gr):_)) =
|
||||||
do let abs = render (srcAbsName gr cnc)
|
do let abs = render (srcAbsName gr cnc)
|
||||||
pgfFile = outputPath opts (grammarName' opts abs<.>"pgf")
|
pgfFile = outputPath opts (grammarName' opts abs<.>"pgf")
|
||||||
@@ -145,7 +153,7 @@ unionPGFFiles opts fs =
|
|||||||
pgfFile = outputPath opts (grammarName opts pgf <.> "pgf")
|
pgfFile = outputPath opts (grammarName opts pgf <.> "pgf")
|
||||||
if pgfFile `elem` fs
|
if pgfFile `elem` fs
|
||||||
then putStrLnE $ "Refusing to overwrite " ++ pgfFile
|
then putStrLnE $ "Refusing to overwrite " ++ pgfFile
|
||||||
else writePGF opts pgf
|
else void $ writePGF opts pgf
|
||||||
writeOutputs opts pgf
|
writeOutputs opts pgf
|
||||||
|
|
||||||
readPGFVerbose f =
|
readPGFVerbose f =
|
||||||
@@ -162,26 +170,39 @@ writeOutputs opts pgf = do
|
|||||||
-- | Write the result of compiling a grammar (e.g. with 'compileToPGF' or
|
-- | Write the result of compiling a grammar (e.g. with 'compileToPGF' or
|
||||||
-- 'link') to a @.pgf@ file.
|
-- 'link') to a @.pgf@ file.
|
||||||
-- A split PGF file is output if the @-split-pgf@ option is used.
|
-- 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 =
|
writePGF opts pgf =
|
||||||
if flag optSplitPGF opts then writeSplitPGF else writeNormalPGF
|
if flag optSplitPGF opts then writeSplitPGF else writeNormalPGF
|
||||||
where
|
where
|
||||||
writeNormalPGF =
|
writeNormalPGF =
|
||||||
do let outfile = outputPath opts (grammarName opts pgf <.> "pgf")
|
do let outfile = outputPath opts (grammarName opts pgf <.> "pgf")
|
||||||
writing opts outfile $ encodeFile outfile pgf
|
writing opts outfile $ encodeFile outfile pgf
|
||||||
|
return [outfile]
|
||||||
|
|
||||||
writeSplitPGF =
|
writeSplitPGF =
|
||||||
do let outfile = outputPath opts (grammarName opts pgf <.> "pgf")
|
do let outfile = outputPath opts (grammarName opts pgf <.> "pgf")
|
||||||
writing opts outfile $ BSL.writeFile outfile (runPut (putSplitAbs pgf))
|
writing opts outfile $ BSL.writeFile outfile (runPut (putSplitAbs pgf))
|
||||||
--encodeFile_ outfile (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")
|
let outfile = outputPath opts (showCId (fst cnc) <.> "pgf_c")
|
||||||
writing opts outfile $ encodeFile outfile cnc
|
writing opts outfile $ encodeFile outfile cnc
|
||||||
|
return outfile
|
||||||
|
|
||||||
|
return (outfile:outfiles)
|
||||||
|
|
||||||
writeOutput :: Options -> FilePath-> String -> IOE ()
|
writeLPGF :: Options -> LPGF -> IOE FilePath
|
||||||
writeOutput opts file str = writing opts path $ writeUTF8File path str
|
writeLPGF opts lpgf = do
|
||||||
where path = outputPath opts file
|
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
|
-- * 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
|
data TypeBinding = TypeBinding VarId Type deriving Show
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- ** Concreate syntax
|
-- ** Concrete syntax
|
||||||
|
|
||||||
-- | Concrete Syntax
|
-- | Concrete Syntax
|
||||||
data Concrete = Concrete ModId ModId Flags [ParamDef] [LincatDef] [LinDef]
|
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 PredefId = PredefId Id deriving (Eq,Ord,Show)
|
||||||
newtype LabelId = LabelId 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
|
-- | Name of param type or param value
|
||||||
newtype ParamId = ParamId QualId deriving (Eq,Ord,Show)
|
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 ModId = ModId Id deriving (Eq,Ord,Show)
|
||||||
|
|
||||||
newtype CatId = CatId 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
|
newtype Flags = Flags [(FlagName,FlagValue)] deriving Show
|
||||||
type FlagName = Id
|
type FlagName = Id
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
-- pattern matching for both concrete and abstract syntax. AR -- 16\/6\/2003
|
-- pattern matching for both concrete and abstract syntax. AR -- 16\/6\/2003
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
module GF.Grammar.PatternMatch (matchPattern,
|
module GF.Grammar.PatternMatch (
|
||||||
|
matchPattern,
|
||||||
testOvershadow,
|
testOvershadow,
|
||||||
findMatch,
|
findMatch,
|
||||||
measurePatt
|
measurePatt
|
||||||
|
|||||||
@@ -362,4 +362,3 @@ getLet :: Term -> ([LocalDef], Term)
|
|||||||
getLet (Let l e) = let (ls,e') = getLet e
|
getLet (Let l e) = let (ls,e') = getLet e
|
||||||
in (l:ls,e')
|
in (l:ls,e')
|
||||||
getLet e = ([],e)
|
getLet e = ([],e)
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
-- (Description of the module)
|
-- (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,
|
Val(..), Env,
|
||||||
-- ** Annotated tree used in editing
|
-- ** Annotated tree used in editing
|
||||||
Binds, Constraints, MetaSubst,
|
Binds, Constraints, MetaSubst,
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ data Verbosity = Quiet | Normal | Verbose | Debug
|
|||||||
data Phase = Preproc | Convert | Compile | Link
|
data Phase = Preproc | Convert | Compile | Link
|
||||||
deriving (Show,Eq,Ord)
|
deriving (Show,Eq,Ord)
|
||||||
|
|
||||||
data OutputFormat = FmtPGFPretty
|
data OutputFormat = FmtLPGF
|
||||||
|
| FmtPGFPretty
|
||||||
| FmtCanonicalGF
|
| FmtCanonicalGF
|
||||||
| FmtCanonicalJson
|
| FmtCanonicalJson
|
||||||
| FmtJavaScript
|
| FmtJavaScript
|
||||||
@@ -335,7 +336,7 @@ optDescr =
|
|||||||
Option ['f'] ["output-format"] (ReqArg outFmt "FMT")
|
Option ['f'] ["output-format"] (ReqArg outFmt "FMT")
|
||||||
(unlines ["Output format. FMT can be one of:",
|
(unlines ["Output format. FMT can be one of:",
|
||||||
"Canonical GF grammar: canonical_gf, canonical_json, (and haskell with option --haskell=concrete)",
|
"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,
|
"Single concrete only: bnf, ebnf, fa, gsl, jsgf, regexp, slf, srgs_xml, srgs_abnf, vxml, ....", -- cf, lbnf,
|
||||||
"Abstract only: haskell, ..."]), -- prolog_abs,
|
"Abstract only: haskell, ..."]), -- prolog_abs,
|
||||||
Option [] ["sisr"] (ReqArg sisrFmt "FMT")
|
Option [] ["sisr"] (ReqArg sisrFmt "FMT")
|
||||||
@@ -477,7 +478,8 @@ outputFormats = map fst outputFormatsExpl
|
|||||||
|
|
||||||
outputFormatsExpl :: [((String,OutputFormat),String)]
|
outputFormatsExpl :: [((String,OutputFormat),String)]
|
||||||
outputFormatsExpl =
|
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_gf", FmtCanonicalGF),"Canonical GF source files"),
|
||||||
(("canonical_json", FmtCanonicalJson),"Canonical JSON source files"),
|
(("canonical_json", FmtCanonicalJson),"Canonical JSON source files"),
|
||||||
(("js", FmtJavaScript),"JavaScript (whole grammar)"),
|
(("js", FmtJavaScript),"JavaScript (whole grammar)"),
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ import GF.Server(server)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
import GF.Command.Messages(welcome)
|
import GF.Command.Messages(welcome)
|
||||||
import GF.Infra.UseIO (Output)
|
|
||||||
-- Provides an orphan instance of MonadFail for StateT in ghc versions < 8
|
-- Provides an orphan instance of MonadFail for StateT in ghc versions < 8
|
||||||
import Control.Monad.Trans.Instances ()
|
import Control.Monad.Trans.Instances ()
|
||||||
|
|
||||||
@@ -56,6 +55,7 @@ mainGFI opts files = do
|
|||||||
|
|
||||||
shell opts files = flip evalStateT (emptyGFEnv opts) $
|
shell opts files = flip evalStateT (emptyGFEnv opts) $
|
||||||
do mapStateT runSIO $ importInEnv opts files
|
do mapStateT runSIO $ importInEnv opts files
|
||||||
|
modify $ \ gfenv0 -> gfenv0 {history = [unwords ("i":files)]}
|
||||||
loop
|
loop
|
||||||
|
|
||||||
#ifdef SERVER_MODE
|
#ifdef SERVER_MODE
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ mainGFI opts files = do
|
|||||||
|
|
||||||
shell opts files = flip evalStateT (emptyGFEnv opts) $
|
shell opts files = flip evalStateT (emptyGFEnv opts) $
|
||||||
do mapStateT runSIO $ importInEnv opts files
|
do mapStateT runSIO $ importInEnv opts files
|
||||||
|
modify $ \ gfenv0 -> gfenv0 {history = [unwords ("i":files)]}
|
||||||
loop
|
loop
|
||||||
|
|
||||||
{-
|
{-
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import Data.Version
|
|||||||
import System.Directory
|
import System.Directory
|
||||||
import System.Environment (getArgs)
|
import System.Environment (getArgs)
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import GF.System.Console (setConsoleEncoding)
|
-- import GF.System.Console (setConsoleEncoding)
|
||||||
|
|
||||||
-- | Run the GF main program, taking arguments from the command line.
|
-- | Run the GF main program, taking arguments from the command line.
|
||||||
-- (It calls 'setConsoleEncoding' and 'getOptions', then 'mainOpts'.)
|
-- (It calls 'setConsoleEncoding' and 'getOptions', then 'mainOpts'.)
|
||||||
@@ -28,6 +28,7 @@ main = do
|
|||||||
|
|
||||||
-- | Get and parse GF command line arguments. Fix relative paths.
|
-- | Get and parse GF command line arguments. Fix relative paths.
|
||||||
-- Calls 'getArgs' and 'parseOptions'.
|
-- Calls 'getArgs' and 'parseOptions'.
|
||||||
|
getOptions :: IO (Options, [FilePath])
|
||||||
getOptions = do
|
getOptions = do
|
||||||
args <- getArgs
|
args <- getArgs
|
||||||
case parseOptions args of
|
case parseOptions args of
|
||||||
|
|||||||
@@ -110,4 +110,3 @@ prepunctuate p (x:xs) = x : map (p <>) xs
|
|||||||
|
|
||||||
($++$) :: Doc -> Doc -> Doc
|
($++$) :: Doc -> Doc -> Doc
|
||||||
x $++$ y = x $$ emptyLine $$ y
|
x $++$ y = x $$ emptyLine $$ y
|
||||||
|
|
||||||
|
|||||||
@@ -125,4 +125,3 @@ prepunctuate p (x:xs) = x : map (p <>) xs
|
|||||||
|
|
||||||
($++$) :: Doc -> Doc -> Doc
|
($++$) :: Doc -> Doc -> Doc
|
||||||
x $++$ y = x $$ emptyLine $$ y
|
x $++$ y = x $$ emptyLine $$ y
|
||||||
|
|
||||||
|
|||||||
@@ -300,9 +300,7 @@ transAncientGreek = mkTransliteration "ancient Greek" allTrans allCodes where
|
|||||||
|
|
||||||
transAmharic :: Transliteration
|
transAmharic :: Transliteration
|
||||||
transAmharic = mkTransliteration "Amharic" allTrans allCodes where
|
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* l. l- l' l( l) l l? l* "++
|
||||||
" H. H- H' H( H) H H? H* m. m- m' m( m) m m? m* "++
|
" 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* "++
|
" s. s- s' s( s) s s? s* r. r- r' r( r) r r? r* "++
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ For Linux users
|
|||||||
|
|
||||||
You will need the packages: autoconf, automake, libtool, make
|
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:
|
The compilation steps are:
|
||||||
|
|
||||||
$ autoreconf -i
|
$ autoreconf -i
|
||||||
@@ -28,7 +31,7 @@ For Mac OSX users
|
|||||||
The following is what I did to make it work on MacOSX 10.8:
|
The following is what I did to make it work on MacOSX 10.8:
|
||||||
|
|
||||||
- Install XCode and XCode command line tools
|
- Install XCode and XCode command line tools
|
||||||
- Install Homebrew: http://mxcl.github.com/homebrew/
|
- Install Homebrew: https://brew.sh
|
||||||
|
|
||||||
$ brew install automake autoconf libtool
|
$ brew install automake autoconf libtool
|
||||||
$ glibtoolize
|
$ 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
|
touch
|
||||||
return (Just s)
|
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 :: Int -> Expr
|
||||||
mkInt val =
|
mkInt val =
|
||||||
unsafePerformIO $ do
|
unsafePerformIO $ do
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
name: pgf2
|
name: pgf2
|
||||||
version: 1.3.0
|
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
|
synopsis: Bindings to the C version of the PGF runtime
|
||||||
description:
|
description:
|
||||||
GF, Grammatical Framework, is a programming language for multilingual grammar applications.
|
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.
|
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.
|
This package provides Haskell bindings to that runtime.
|
||||||
homepage: https://www.grammaticalframework.org
|
homepage: https://www.grammaticalframework.org/
|
||||||
license: LGPL-3
|
bug-reports: https://github.com/GrammaticalFramework/gf-core/issues
|
||||||
license-file: LICENSE
|
|
||||||
author: Krasimir Angelov
|
author: Krasimir Angelov
|
||||||
category: Natural Language Processing
|
|
||||||
build-type: Simple
|
|
||||||
extra-source-files: CHANGELOG.md, README.md
|
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
|
library
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
@@ -23,9 +26,9 @@ library
|
|||||||
PGF2.Expr,
|
PGF2.Expr,
|
||||||
PGF2.Type
|
PGF2.Type
|
||||||
build-depends:
|
build-depends:
|
||||||
base >=4.3 && <5,
|
base >= 4.9.1 && < 4.15,
|
||||||
containers,
|
containers >= 0.5.7 && < 0.7,
|
||||||
pretty
|
pretty >= 1.1.3 && < 1.2
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
build-tools: hsc2hs
|
build-tools: hsc2hs
|
||||||
extra-libraries: pgf gu
|
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 (PUSH_ACCUM (LFlt d)) = putWord8 78 >> put d
|
||||||
put (POP_ACCUM ) = putWord8 80
|
put (POP_ACCUM ) = putWord8 80
|
||||||
put (ADD ) = putWord8 84
|
put (ADD ) = putWord8 84
|
||||||
|
get = fail "Missing implementation for ‘get’ in the instance declaration for ‘Binary Instr’"
|
||||||
|
|
||||||
instance Binary Type where
|
instance Binary Type where
|
||||||
put (DTyp hypos cat exps) = put (hypos,cat,exps)
|
put (DTyp hypos cat exps) = put (hypos,cat,exps)
|
||||||
|
|||||||
@@ -1,29 +1,32 @@
|
|||||||
name: pgf
|
name: pgf
|
||||||
version: 3.10.1-git
|
version: 3.11.0-git
|
||||||
|
|
||||||
cabal-version: >= 1.20
|
cabal-version: 1.22
|
||||||
build-type: Simple
|
build-type: Simple
|
||||||
license: OtherLicense
|
license: OtherLicense
|
||||||
category: Natural Language Processing
|
category: Natural Language Processing
|
||||||
synopsis: Grammatical Framework
|
synopsis: Grammatical Framework
|
||||||
description: A library for interpreting the Portable Grammar Format (PGF)
|
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
|
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
|
library
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
build-depends:
|
build-depends:
|
||||||
array,
|
array >= 0.5.1 && < 0.6,
|
||||||
base >= 4.6 && <5,
|
base >= 4.9.1 && < 4.15,
|
||||||
bytestring,
|
bytestring >= 0.10.8 && < 0.11,
|
||||||
containers,
|
containers >= 0.5.7 && < 0.7,
|
||||||
-- exceptions,
|
ghc-prim >= 0.5.0 && < 0.7,
|
||||||
ghc-prim,
|
mtl >= 2.2.1 && < 2.3,
|
||||||
mtl,
|
pretty >= 1.1.3 && < 1.2,
|
||||||
pretty,
|
random >= 1.1 && < 1.3,
|
||||||
random,
|
utf8-string >= 1.0.1.1 && < 1.1
|
||||||
utf8-string
|
|
||||||
|
if impl(ghc<8.0)
|
||||||
|
build-depends:
|
||||||
|
fail >= 4.9.0 && < 4.10
|
||||||
|
|
||||||
other-modules:
|
other-modules:
|
||||||
-- not really part of GF but I have changed the original binary library
|
-- 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="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="../minibar/minibar.css">
|
||||||
<link rel="stylesheet" type="text/css" href="../syntax-editor/editor.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">
|
<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/ast.js"></script>
|
||||||
<script type="text/javascript" src="../syntax-editor/editor_menu.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="../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="../wordnet/js/gf-wordnet.js"></script>
|
||||||
<script type="text/javascript" src="https://www.grammaticalframework.org/wordnet/js/tsnejs.js"></script>
|
<script src="https://unpkg.com/vis-network@9.0.4/standalone/umd/vis-network.min.js"></script>
|
||||||
<script type="text/javascript" src="https://www.grammaticalframework.org/wordnet/js/wordcloud2.js"></script>
|
<script type="text/javascript" src="../wordnet/js/wordcloud2.js"></script>
|
||||||
|
|
||||||
<div id="search_popup" class="search_popup">
|
<div id="search_popup" class="search_popup">
|
||||||
<table id="domains" class="selector">
|
<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.
|
# But committing a symlink can be problematic on Windows, so it's a real copy.
|
||||||
# See: https://github.com/GrammaticalFramework/gf-core/pull/106
|
# 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:
|
extra-deps:
|
||||||
- network-2.6.3.6
|
- network-2.6.3.6
|
||||||
- httpd-shed-0.4.0.3
|
- 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:
|
# flags:
|
||||||
# gf:
|
# 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