1
0
forked from GitHub/gf-core

fixed some tutorial grammars and updated embedded section (JavaScript and web TODO)

This commit is contained in:
aarne
2008-11-11 09:21:59 +00:00
parent ca59050abc
commit db18350b1e
9 changed files with 163 additions and 100 deletions

View File

@@ -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===
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
```
The result is a file named ``Food.hs``, containing a
module named ``Food``.
#NEW
===Example of exporting GF datatypes===
===Abstract syntax of the query system===
Input: abstract syntax judgements
```
abstract Query = {
flags startcat=Question ;
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

View File

@@ -0,0 +1,4 @@
all:
gfc --make --output-format=haskell QueryEng.gf
ghc --make -o ./math TransferLoop.hs
strip math

View File

@@ -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 ;
}

View File

@@ -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" ;
}

View File

@@ -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 [] = []

View File

@@ -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"

View File

@@ -0,0 +1,5 @@
--# -path=.:../foods:present
concrete FoodsSwe of Foods = FoodsI with
(Syntax = SyntaxSwe),
(LexFoods = LexFoodsSwe) ;

View File

@@ -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" ;
}

View File

@@ -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" ;
}