summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/gf-tutorial.txt146
-rw-r--r--examples/tutorial/embedded/Makefile4
-rw-r--r--examples/tutorial/embedded/Query.gf17
-rw-r--r--examples/tutorial/embedded/QueryEng.gf15
-rw-r--r--examples/tutorial/embedded/TransferDef.hs26
-rw-r--r--examples/tutorial/embedded/TransferLoop.hs21
-rw-r--r--examples/tutorial/resource-foods/FoodsSwe.gf5
-rw-r--r--examples/tutorial/resource-foods/LexFoodsIta.gf7
-rw-r--r--examples/tutorial/resource-foods/LexFoodsSwe.gf20
9 files changed, 162 insertions, 99 deletions
diff --git a/doc/gf-tutorial.txt b/doc/gf-tutorial.txt
index 7003dee1a..c556cbe64 100644
--- a/doc/gf-tutorial.txt
+++ b/doc/gf-tutorial.txt
@@ -4498,7 +4498,6 @@ the prefix is ``f`` instead of ``i``, and that ``fconst`` takes floating
point literals as arguments.
-%TODO: fix embedded grammars lesson
#NEW
@@ -4507,10 +4506,10 @@ point literals as arguments.
#Lchapeight
Goals:
-- use as parts of programs written in other programming Haskell and Java
+- use grammars as parts of programs written in Haskell and JavaScript
- implement stand-alone question-answering systems and translators based on
GF grammars
-- generate language models for speech recognition from grammars
+- generate language models for speech recognition from GF grammars
@@ -4519,11 +4518,11 @@ Goals:
==Functionalities of an embedded grammar format==
GF grammars can be used as parts of programs written in other programming
-languages. Haskell and Java.
+languages, to be called **host languages**.
This facility is based on several components:
-- a portable format for multilingual GF grammars
-- an interpreter for this format written in the host language
-- an API that enables reading grammar files and calling the interpreter
+- PGF: a portable format for multilingual GF grammars
+- a PGF interpreter written in the host language
+- a library in the host language that enables calling the interpreter
- a way to manipulate abstract syntax trees in the host language
@@ -4535,18 +4534,11 @@ This facility is based on several components:
The portable format is called PGF, "Portable Grammar Format".
-A file can be produced in GF by the command
-```
- > print_grammar | write_file FILE.pgf
-```
-There is also a batch compiler, executable from the operative system shell:
+This format is produced by the GF batch compiler ``gfc``,
+executable from the operative system shell:
```
% gfc --make SOURCE.gf
```
-//This applies to GF version 3 and upwards. Older GF used a format suffixed//
-``.gfcm``.
-//At the moment of writing, also the Java interpreter still uses the GFCM format.//
-
PGF is the recommended format in
which final grammar products are distributed, because they
are stripped from superfluous information and can be started and applied
@@ -4636,6 +4628,8 @@ The simplest way to translate is to ``echo`` input to the program:
```
The result is given in all languages except the input language.
+%TODO convert the output to UTF8
+
#NEW
@@ -4694,27 +4688,14 @@ To reply in the //same// language as the question:
#NEW
-===Exporting GF datatypes to Haskell===
+===Abstract syntax of the query system===
-To make it easy to define a transfer function, we export the
-abstract syntax to a system of Haskell datatypes:
-```
- % gfc --output-format=haskell Food.gfcc
-```
-It is also possible to produce the Haskell file together with GFCC, by
-```
- % gfc --make --output-format=haskell FoodEng.gf FoodIta.gf
+Input: abstract syntax judgements
```
-The result is a file named ``Food.hs``, containing a
-module named ``Food``.
-
-
-#NEW
+abstract Query = {
-===Example of exporting GF datatypes===
+ flags startcat=Question ;
-Input: abstract syntax judgements
-```
cat
Answer ; Question ; Object ;
@@ -4726,10 +4707,33 @@ Input: abstract syntax judgements
Yes : Answer ;
No : Answer ;
+}
+```
+
+
+#NEW
+
+===Exporting GF datatypes to Haskell===
+
+To make it easy to define a transfer function, we export the
+abstract syntax to a system of Haskell datatypes:
+```
+ % gfc --output-format=haskell Query.pgf
+```
+It is also possible to produce the Haskell file together with GFCC, by
+```
+ % gfc --make --output-format=haskell QueryEng.gf
```
+The result is a file named ``Query.hs``, containing a
+module named ``Query``.
+
+
+#NEW
+
Output: Haskell definitions
```
-newtype GInt = GInt Integer
+module Query where
+import PGF
data GAnswer =
GYes
@@ -4741,6 +4745,8 @@ data GQuestion =
GPrime GObject
| GOdd GObject
| GEven GObject
+
+newtype GInt = GInt Integer
```
All type and constructor names are prefixed with a ``G`` to prevent clashes.
@@ -4792,8 +4798,8 @@ instance Gf GQuestion where
```
For the programmer, it is enougo to know:
- all GF names are in Haskell prefixed with ``G``
-- ``gf`` translates from Haskell to GF
-- ``fg`` translates from GF to Haskell
+- ``gf`` translates from Haskell objects to GF trees
+- ``fg`` translates from GF trees to Haskell objects
@@ -4805,7 +4811,7 @@ For the programmer, it is enougo to know:
module TransferDef where
import PGF (Tree)
-import Math -- generated from GF
+import Query -- generated from GF
transfer :: Tree -> Tree
transfer = gf . answer . fg
@@ -4844,7 +4850,7 @@ import TransferDef (transfer)
main :: IO ()
main = do
- gr <- file2grammar "Math.pgf"
+ gr <- readPGF "Query.pgf"
loop (translate transfer gr)
loop :: (String -> String) -> IO ()
@@ -4855,7 +4861,7 @@ loop trans = do
loop trans
translate :: (Tree -> Tree) -> PGF -> String -> String
-translate tr gr = case parseAllLang gr (startCat gr) s of
+translate tr gr s = case parseAllLang gr (startCat gr) s of
(lg,t:_):_ -> linearize gr lg (tr t)
_ -> "NO PARSE"
```
@@ -4869,7 +4875,7 @@ translate tr gr = case parseAllLang gr (startCat gr) s of
To automate the production of the system, we write a ``Makefile`` as follows:
```
all:
- gfc --make -haskell MathEng.gf MathFre.gf
+ gfc --make --output-format=haskell QueryEng
ghc --make -o ./math TransferLoop.hs
strip math
```
@@ -4891,70 +4897,14 @@ Just to summarize, the source of the application consists of the following files
TransferLoop.hs -- Haskell Main module
```
-
#NEW
-===Translets: embedded translators in Java===
-
-**NOTICE**. Only for GF 2.9 and older at the moment.
-
-A Java system needs many more files than a Haskell system.
-To get started, fetch the package ``gfc2java`` from
-
-[``www.cs.chalmers.se/~bringert/darcs/gfc2java/`` http://www.cs.chalmers.se/~bringert/darcs/gfc2java/]
-
-by using the Darcs version control system as described in this page.
-
-The ``gfc2java`` package contains a script ``build-translet``, which
-can be applied
-to any ``.gfcm`` file to create a **translet**, a small translation GUI.
-
-For the ``Food``
-grammars of #Rchapthree, we first create a file ``food.gfcm`` by
-```
- % echo "pm | wf food.gfcm" | gf FoodEng.gf FoodIta.gf
-```
-and then run
-```
- % build_translet food.gfcm
-```
-The resulting file ``translate-food.jar`` can be run with
-```
- % java -jar translate-food.jar
-```
-The translet looks like this:
-
-[food-translet.png]
+TODO: web server applications
#NEW
-===Dialogue systems in Java===
-
-**NOTICE**. Only for GF 2.9 and older at the moment.
-
-A question-answer system is a special case of a **dialogue system**,
-where the user and
-the computer communicate by writing or, even more properly, by speech.
-The ``gf-java``
-homepage provides an example of a most simple dialogue system imaginable,
-where two
-the conversation has just two rules:
-- if the user says //here you go//, the system says //thanks//
-- if the user says //thanks//, the system says //you are welcome//
-
-
-The conversation can be made in both English and Swedish; the user's initiative
-decides which language the system replies in. Thus the structure is very similar
-to the ``math`` program #Rsecmathprogram.
-
-
-The GF and Java sources of the program can be
-found in
-
-[``www.cs.chalmers.se/~bringert/darcs/simpledemo http://www.cs.chalmers.se/~bringert/darcs/simpledemo``]
-
-again accessible with the Darcs version control system.
+TODO: JavaScript applications
#NEW
diff --git a/examples/tutorial/embedded/Makefile b/examples/tutorial/embedded/Makefile
new file mode 100644
index 000000000..f1a61cb92
--- /dev/null
+++ b/examples/tutorial/embedded/Makefile
@@ -0,0 +1,4 @@
+all:
+ gfc --make --output-format=haskell QueryEng.gf
+ ghc --make -o ./math TransferLoop.hs
+ strip math
diff --git a/examples/tutorial/embedded/Query.gf b/examples/tutorial/embedded/Query.gf
new file mode 100644
index 000000000..b1ba23a87
--- /dev/null
+++ b/examples/tutorial/embedded/Query.gf
@@ -0,0 +1,17 @@
+abstract Query = {
+
+ flags startcat=Question ;
+
+ cat
+ Answer ; Question ; Object ;
+
+ fun
+ Even : Object -> Question ;
+ Odd : Object -> Question ;
+ Prime : Object -> Question ;
+ Number : Int -> Object ;
+
+ Yes : Answer ;
+ No : Answer ;
+}
+
diff --git a/examples/tutorial/embedded/QueryEng.gf b/examples/tutorial/embedded/QueryEng.gf
new file mode 100644
index 000000000..a740056ee
--- /dev/null
+++ b/examples/tutorial/embedded/QueryEng.gf
@@ -0,0 +1,15 @@
+concrete QueryEng of Query = {
+ lincat
+ Answer, Question, Object = Str ;
+
+ lin
+ Even x = "is" ++ x ++ "even" ;
+ Odd x = "is" ++ x ++ "odd" ;
+ Prime x = "is" ++ x ++ "prime" ;
+ Number n = n.s ;
+
+ Yes = "yes" ;
+ No = "no" ;
+
+}
+
diff --git a/examples/tutorial/embedded/TransferDef.hs b/examples/tutorial/embedded/TransferDef.hs
new file mode 100644
index 000000000..37d81c6dc
--- /dev/null
+++ b/examples/tutorial/embedded/TransferDef.hs
@@ -0,0 +1,26 @@
+module TransferDef where
+
+import PGF (Tree)
+import Query -- generated from GF
+
+transfer :: Tree -> Tree
+transfer = gf . answer . fg
+
+answer :: GQuestion -> GAnswer
+answer p = case p of
+ GOdd x -> test odd x
+ GEven x -> test even x
+ GPrime x -> test prime x
+
+value :: GObject -> Int
+value e = case e of
+ GNumber (GInt i) -> fromInteger i
+
+test :: (Int -> Bool) -> GObject -> GAnswer
+test f x = if f (value x) then GYes else GNo
+
+prime :: Int -> Bool
+prime x = elem x primes where
+ primes = sieve [2 .. x]
+ sieve (p:xs) = p : sieve [ n | n <- xs, n `mod` p > 0 ]
+ sieve [] = []
diff --git a/examples/tutorial/embedded/TransferLoop.hs b/examples/tutorial/embedded/TransferLoop.hs
new file mode 100644
index 000000000..58498da11
--- /dev/null
+++ b/examples/tutorial/embedded/TransferLoop.hs
@@ -0,0 +1,21 @@
+module Main where
+
+import PGF
+import TransferDef (transfer)
+
+main :: IO ()
+main = do
+ gr <- readPGF "Query.pgf"
+ loop (translate transfer gr)
+
+loop :: (String -> String) -> IO ()
+loop trans = do
+ s <- getLine
+ if s == "quit" then putStrLn "bye" else do
+ putStrLn $ trans s
+ loop trans
+
+translate :: (Tree -> Tree) -> PGF -> String -> String
+translate tr gr s = case parseAllLang gr (startCat gr) s of
+ (lg,t:_):_ -> linearize gr lg (tr t)
+ _ -> "NO PARSE"
diff --git a/examples/tutorial/resource-foods/FoodsSwe.gf b/examples/tutorial/resource-foods/FoodsSwe.gf
new file mode 100644
index 000000000..a77f924ad
--- /dev/null
+++ b/examples/tutorial/resource-foods/FoodsSwe.gf
@@ -0,0 +1,5 @@
+--# -path=.:../foods:present
+
+concrete FoodsSwe of Foods = FoodsI with
+ (Syntax = SyntaxSwe),
+ (LexFoods = LexFoodsSwe) ;
diff --git a/examples/tutorial/resource-foods/LexFoodsIta.gf b/examples/tutorial/resource-foods/LexFoodsIta.gf
index be120a24e..2148953c3 100644
--- a/examples/tutorial/resource-foods/LexFoodsIta.gf
+++ b/examples/tutorial/resource-foods/LexFoodsIta.gf
@@ -1,6 +1,6 @@
--# -path=.:../foods:present:prelude
-instance LexFoodsIta of LexFoods = open SyntaxIta, ParadigmsIta in {
+instance LexFoodsIta of LexFoods = open SyntaxIta, ParadigmsIta, BeschIta in {
oper
wine_N = mkN "vino" ;
pizza_N = mkN "pizza" ;
@@ -12,4 +12,9 @@ instance LexFoodsIta of LexFoods = open SyntaxIta, ParadigmsIta in {
expensive_A = mkA "caro" ;
delicious_A = mkA "delizioso" ;
boring_A = mkA "noioso" ;
+ drink_V2 = mkV2 (verboV (bere_27 "bere")) ;
+ eat_V2 = mkV2 (mkV "mangiare") ;
+ pay_V2 = mkV2 (mkV "pagare") ;
+ gentleman_N = mkN "signore" ;
+ lady_N = mkN "signora" ;
}
diff --git a/examples/tutorial/resource-foods/LexFoodsSwe.gf b/examples/tutorial/resource-foods/LexFoodsSwe.gf
new file mode 100644
index 000000000..12a2aaeee
--- /dev/null
+++ b/examples/tutorial/resource-foods/LexFoodsSwe.gf
@@ -0,0 +1,20 @@
+instance LexFoodsSwe of LexFoods = open SyntaxSwe, ParadigmsSwe, IrregSwe in {
+ oper
+ wine_N = mkN "vin" "vinet" "viner" "vinerna" ;
+ pizza_N = mkN "pizza" ;
+ cheese_N = mkN "ost" ;
+ fish_N = mkN "fisk" ;
+ fresh_A = mkA "färsk" ;
+ warm_A = mkA "varm" ;
+ italian_A = mkA "italiensk" ;
+ expensive_A = mkA "dyr" ;
+ delicious_A = mkA "läcker" "läckert" "läckra" "läckrare" "läckrast" ;
+ boring_A = mkA "tråkig" ;
+
+ eat_V2 = mkV2 (mkV "äta" "åt" "ätit") ;
+ drink_V2 = mkV2 (mkV "dricka" "drack" "druckit") ;
+ pay_V2 = mkV2 "betala" ;
+ lady_N = mkN "dam" "damer" ;
+ gentleman_N = mkN "herr" ;
+
+}