tutorial exercises; put libdir in place in GF/src

This commit is contained in:
aarne
2007-07-04 14:10:41 +00:00
parent 51d3ade165
commit 2b5197d61d
3 changed files with 91 additions and 35 deletions

View File

@@ -30,7 +30,6 @@ Last update: %%date(%c)
==GF = Grammatical Framework== ==GF = Grammatical Framework==
The term GF is used for different things: The term GF is used for different things:
- a **program** used for working with grammars - a **program** used for working with grammars
- a **programming language** in which grammars can be written - a **programming language** in which grammars can be written
- a **theory** about grammars and languages - a **theory** about grammars and languages
@@ -39,7 +38,6 @@ The term GF is used for different things:
This tutorial is primarily about the GF program and This tutorial is primarily about the GF program and
the GF programming language. the GF programming language.
It will guide you It will guide you
- to use the GF program - to use the GF program
- to write GF grammars - to write GF grammars
- to write programs in which GF grammars are used as components - to write programs in which GF grammars are used as components
@@ -52,28 +50,26 @@ It will guide you
A grammar is a definition of a language. A grammar is a definition of a language.
From this definition, different language processing components From this definition, different language processing components
can be derived: can be derived:
- **parsing**: to analyse the language
- parsing: to analyse the language - **linearization**: to generate the language
- linearization: to generate the language - **translation**: to analyse one language and generate another
- translation: to analyse one language and generate another
A GF grammar can be seen as a declarative program from which these A GF grammar can be seen as a declarative program from which these
processing tasks can be automatically derived. In addition, many processing tasks can be automatically derived. In addition, many
other tasks are readily available for GF grammars: other tasks are readily available for GF grammars:
- **morphological analysis**: find out the possible inflection forms of words
- morphological analysis: find out the possible inflection forms of words - **morphological synthesis**: generate all inflection forms of words
- morphological synthesis: generate all inflection forms of words - **random generation**: generate random expressions
- random generation: generate random expressions - **corpus generation**: generate all expressions
- corpus generation: generate all expressions - **treebank generation**: generate a list of trees with multiple linearizations
- teaching quizzes: train morphology and translation - **teaching quizzes**: train morphology and translation
- multilingual authoring: create a document in many languages simultaneously - **multilingual authoring**: create a document in many languages simultaneously
- speech input: optimize a speech recognition system for your grammar - **speech input**: optimize a speech recognition system for your grammar
A typical GF application is based on a **multilingual grammar** involving A typical GF application is based on a **multilingual grammar** involving
translation on a special domain. Existing applications of this idea include translation on a special domain. Existing applications of this idea include
- [Alfa: http://www.cs.chalmers.se/~hallgren/Alfa/Tutorial/GFplugin.html]: - [Alfa: http://www.cs.chalmers.se/~hallgren/Alfa/Tutorial/GFplugin.html]:
a natural-language interface to a proof editor a natural-language interface to a proof editor
(languages: English, French, Swedish) (languages: English, French, Swedish)
@@ -169,8 +165,7 @@ belongs to resource grammars, this tutorial will explain the
programming concepts involved in morphology. This will moreover programming concepts involved in morphology. This will moreover
make it possible to grow the fragment covered by the food example. make it possible to grow the fragment covered by the food example.
The tutorial will in fact build a miniature resource grammar in order The tutorial will in fact build a miniature resource grammar in order
to illustrate the module structure of library-based application to give an introduction to linguistically oriented grammar writing.
grammar writing.
Thus it is by elaborating the initial ``food.cf`` example that Thus it is by elaborating the initial ``food.cf`` example that
the tutorial makes a guided tour through all concepts of GF. the tutorial makes a guided tour through all concepts of GF.
@@ -179,15 +174,17 @@ also the commands of the GF system are introduced as they
are needed. are needed.
To learn how to write GF grammars is not the only goal of To learn how to write GF grammars is not the only goal of
this tutorial. To learn the commands of the GF system means this tutorial. We will also explain the most important
that simple applications of grammars, such as translation and commands of the GF system. With these commands,
simple applications of grammars, such as translation and
quiz systems, can be built simply by writing scripts for the quiz systems, can be built simply by writing scripts for the
system. More complicated applications, such as natural-language system. More complicated applications, such as natural-language
interfaces and dialogue systems, also require programming in interfaces and dialogue systems, moreover require programming in
some general-purpose language. We will briefly explain how some general-purpose language. Thus will briefly explain how
GF grammars are used as components of Haskell, Java, Javascript, GF grammars are used as components of Haskell, Java, Javascript,
and Prolog grammars. The tutorial concludes with a couple of and Prolog grammars.
case studies showing how such complete systems can be built. %The tutorial concludes with a couple of
%case studies showing how such complete systems can be built.
@@ -196,6 +193,7 @@ case studies showing how such complete systems can be built.
The GF program is open-source free software, which you can download via the The GF program is open-source free software, which you can download via the
GF Homepage: GF Homepage:
[``http://www.cs.chalmers.se/~aarne/GF`` http://www.cs.chalmers.se/~aarne/GF] [``http://www.cs.chalmers.se/~aarne/GF`` http://www.cs.chalmers.se/~aarne/GF]
There you can download There you can download
@@ -204,14 +202,19 @@ There you can download
- grammar libraries and examples - grammar libraries and examples
If you want to compile GF from source, you need Haskell and Java If you want to compile GF from source, you need a Haskell compiler.
compilers. But normally you don't have to compile, and you definitely For the interactive editor, you also need a Java compilers.
But normally you don't have to compile, and you definitely
don't need to know Haskell or Java to use GF. don't need to know Haskell or Java to use GF.
We are assuming the availability of a Unix shell. Mac OS X users We are assuming the availability of a Unix shell. Linux and Mac OS X users
have it automatically, under the name "terminal". have it automatically, the latter under the name "terminal".
Windows users are recommended to install Cywgin, the free Unix shell for Windows. Windows users are recommended to install Cywgin, the free Unix shell for Windows.
%--!
==Running the GF program==
To start the GF program, assuming you have installed it, just type To start the GF program, assuming you have installed it, just type
``` ```
% gf % gf
@@ -325,6 +328,29 @@ you imported. Try parsing something else, and you fail
Unknown words: hello world Unknown words: hello world
``` ```
**Exercise**. Extend the grammar ``food.cf`` by ten new food kinds and
qualities, and run the parser with new kinds of examples.
**Exercise**. Add a rule that enables questions of the form
//is this cheese Italian//.
**Exercise**. Add the rule
```
IsVery. S ::= Item "is" "very" Quality ;
```
and see what happens when parsing ``this wine is very very Italian``.
You have just made the grammar **ambiguous**: it now assigns several
trees to some strings.
**Exercise**. Modify the grammar so that at most one ``Quality`` may
attach to a given ``Kind``. Thus //boring Italian fish// will no longer
be recognized.
%--! %--!
@@ -422,11 +448,22 @@ You get quite a few trees but not all of them: only up to a given
**depth** of trees. To see how you can get more, use the **depth** of trees. To see how you can get more, use the
``help = h`` command, ``help = h`` command,
``` ```
help gt > help gt
``` ```
**Quiz**. If the command ``gt`` generated all
**Exercise**. If the command ``gt`` generated all
trees in your grammar, it would never terminate. Why? trees in your grammar, it would never terminate. Why?
**Exercise**. Measure how many trees the grammar gives with depths 4 and 5,
respectively. You use the Unix **word count** command ``wc`` to count lines.
**Hint**. You can pipe the output of a GF command into a Unix command by
using the escape ``?``, as follows:
```
> generate_trees | ? wc
```
%--! %--!
@@ -450,7 +487,9 @@ This facility is good for test purposes: for instance, you
may want to see if a grammar is **ambiguous**, i.e. may want to see if a grammar is **ambiguous**, i.e.
contains strings that can be parsed in more than one way. contains strings that can be parsed in more than one way.
**Exercise**. Extend the grammar ``food.cf`` so that it produces ambiguous strings. **Exercise**. Extend the grammar ``food.cf`` so that it produces ambiguous strings,
and try out the ambiguity test.
@@ -670,6 +709,10 @@ and of the type in subsequent ``fun`` judgements,
``` ```
The order of judgements in a module is free. The order of judgements in a module is free.
**Exercise**. Extend the abstract syntax ``Food`` with ten new
kinds and qualities, and with questions of the form
//is this wine Italian//.
%--! %--!
@@ -703,6 +746,13 @@ apply as in ``abstract`` modules.
} }
``` ```
**Exercise**. Extend the concrete syntax ``FoodEng`` so that it
matches the abstract syntax defined in the exercise of the previous
section. What happens if the concrete syntax lacks some of the
new functions?
%--! %--!
==Modules and files== ==Modules and files==
@@ -1012,6 +1062,11 @@ are available:
> help -printer > help -printer
> help help > help help
``` ```
Another form of system commands are those usable in GF pipes. The escape symbol
is then ``?``.
```
> generate_trees | ? wc
```

View File

@@ -31,7 +31,7 @@ import GF.Shell.JGF
import GF.System.Signal import GF.System.Signal
import GF.Text.UTF8 import GF.Text.UTF8
import GF.Today (today,version) import GF.Today (today,version,libdir)
import GF.System.Arch import GF.System.Arch
import System (getArgs,system,getEnv) import System (getArgs,system,getEnv)
import Control.Monad (foldM,liftM) import Control.Monad (foldM,liftM)
@@ -121,7 +121,7 @@ helpMsg = unlines [
welcomeMsgLib = do welcomeMsgLib = do
lib <- catch lib <- catch
(getEnv "GF_LIB_PATH" >>= return . ("GF_LIB_PATH is set to" +++)) (getEnv "GF_LIB_PATH" >>= return . ("GF_LIB_PATH is set to" +++))
(const (return "Warning: GF_LIB_PATH is not defined.")) (const (return $ "GF_LIB_PATH is set to the default, " ++ libdir))
return $ welcomeMsg lib return $ welcomeMsg lib
welcomeMsg lib = welcomeMsg lib =

View File

@@ -17,6 +17,7 @@ module GF.Infra.UseIO where
import GF.Data.Operations import GF.Data.Operations
import GF.System.Arch (prCPU) import GF.System.Arch (prCPU)
import GF.Infra.Option import GF.Infra.Option
import GF.Today (libdir)
import System.Directory import System.Directory
import System.IO import System.IO
@@ -114,8 +115,8 @@ doesFileExistPath paths file = do
-- | path in environment variable has lower priority -- | path in environment variable has lower priority
extendPathEnv :: String -> String -> [FilePath] -> IO [FilePath] extendPathEnv :: String -> String -> [FilePath] -> IO [FilePath]
extendPathEnv lib var ps = do extendPathEnv lib var ps = do
b <- catch (getEnv lib) (const (return "")) -- e.g. GF_LIB_PATH b <- catch (getEnv lib) (const (return libdir)) -- e.g. GF_LIB_PATH
s <- catch (getEnv var) (const (return "")) -- e.g. GF_GRAMMAR_PATH s <- catch (getEnv var) (const (return "")) -- e.g. GF_GRAMMAR_PATH
let fs = pFilePaths s let fs = pFilePaths s
let ss = ps ++ fs let ss = ps ++ fs
liftM concat $ mapM allSubdirs $ ss ++ [b ++ "/" ++ s | s <- ss] liftM concat $ mapM allSubdirs $ ss ++ [b ++ "/" ++ s | s <- ss]
@@ -322,7 +323,7 @@ readFileLibraryIOE ini f =
initPath = addInitFilePath ini f initPath = addInitFilePath ini f
getLibPath :: IO String getLibPath :: IO String
getLibPath = do { getLibPath = do {
lp <- getEnv gfLibraryPath; lp <- catch (getEnv gfLibraryPath) (const (return libdir)) ;
return (if isSep (last lp) then lp else lp ++ ['/']); return (if isSep (last lp) then lp else lp ++ ['/']);
} }
reportOn f = "File " ++ f ++ " not found." reportOn f = "File " ++ f ++ " not found."