From 03479648ad008966d15c7866630fef443f70f4dd Mon Sep 17 00:00:00 2001 From: Krasimir Angelov Date: Tue, 29 Aug 2017 19:51:33 +0200 Subject: document the embedded grammars in Haskell & Java --- doc/runtime-api.html | 175 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 107 insertions(+), 68 deletions(-) (limited to 'doc') diff --git a/doc/runtime-api.html b/doc/runtime-api.html index d8759e01b..100fd4ffb 100644 --- a/doc/runtime-api.html +++ b/doc/runtime-api.html @@ -550,13 +550,114 @@ There are also the methods UnAbs, UnInt, UnFloat and

+Constructing new trees is also easy. You can either use +readExpr to read trees from strings, or you can +construct new trees from existing pieces. This is possible by + +using the constructor for pgf.Expr: +
+>>> quant = pgf.readExpr("DetQuant IndefArt NumSg")
+>>> e2 = pgf.Expr("DetCN", [quant, e])
+>>> print(e2)
+DetCN (DetQuant IndefArt NumSg) (AdjCN (PositA red_A) (UseN theatre_N))
+
+
+ +using the functions mkApp, mkStr, mkInt, mkFloat and mkMeta: +
+Prelude PGF2> let Just quant = readExpr "DetQuant IndefArt NumSg"
+Prelude PGF2> let e2 = mkApp "DetCN" [quant, e]
+Prelude PGF2> print e2
+DetCN (DetQuant IndefArt NumSg) (AdjCN (PositA red_A) (UseN theatre_N))
+
+
+ +using the constructor for Expr: +
+Expr quant = Expr.readExpr("DetQuant IndefArt NumSg");
+Expr e2 = new Expr("DetCN", new Expr[] {quant, e});
+System.out.println(e2);
+
+
+ +using the constructor for Expr: +
+Expr quant = Expr.ReadExpr("DetQuant IndefArt NumSg");
+Expr e2 = new Expr("DetCN", new Expr[] {quant, e});
+Console.WriteLine(e2);
+
+
+ +

Embedded GF Grammars

+ +

If the host application needs to do a lot of expression manipulations, +then it is helpful to use a higher-level API to the grammar, +also known as "embedded grammars" in GF. The advantage is that +you can construct and analyze expressions in a more compact way.

+ + +

In Python you first have to embed the grammar by calling: +

+>>> gr.embed("App")
+<module 'App' (built-in)>
+
+After that whenever you need the API you should import the module: +
+>>> import App
+
+

+

Now creating new trees is just a matter of calling ordinary Python +functions: +

+>>> print(App.DetCN(quant,e))
+DetCN (DetQuant IndefArt NumSg) (AdjCN (PositA red_A) (UseN house_N))
+
+

+
+ +

In order to access the API you first need to generate +one boilerplate Haskell module with the compiler: +

+$ gf -make -output-format=haskell App.pgf
+
+This module will expose all functions in the abstract syntax +as data type constructors together with methods for conversion from +a generic expression to Haskell data and vice versa. When you need the API you can just import the module: +
+Prelude PGF2> import App
+
+

+

Now creating new trees is just a matter of writing ordinary Haskell +code: +

+Prelude PGF2 App> print (gf (GDetCN (GDetQuant GIndefArt GNumSg) (GAdjCN (GPositA Gred_A) (GUseN Ghouse_N))))
+
+The only difference is that to the name of every abstract syntax function +the compiler adds a capital 'G' in order to guarantee that there are no conflicts +and that all names are valid names for Haskell data constructors. Here gf is a function +which converts from the data type representation to generic GF expressions.

+ +

The converse function fg converts an expression to a data type expression. +This is useful for instance if you want to do pattern matching +on the structure of the expression: +

+visit = case fg e2 of
+          GDetCN quant cn -> do putStrLn "Found DetCN"
+                                visit cn
+          GAdjCN adj   cn -> do putStrLn "Found AdjCN"
+                                visit cn
+          e               -> return ()
+
+

+
+

-For more complex analyses you can use the visitor pattern. -In object oriented languages this is just a clumpsy way to do +Analysing expressions is also made easier by using the visitor pattern. +In object oriented languages this is a clumpsy way to do what is called pattern matching in most functional languages. You need to define a class which has one method for each function -in the abstract syntax of the grammar. If the functions is called +in the abstract syntax that you want to handle. If the functions is called f then you need a method called on_f. The method will be called each time when the corresponding function is encountered, and its arguments will be the arguments from the original tree. @@ -589,11 +690,11 @@ we call visit recursively to go deeper into the tree.

-For more complex analyses you can use the visitor pattern. -In object oriented languages this is just a clumpsy way to do +Analysing expressions is also made easier by using the visitor pattern. +In object oriented languages this is a clumpsy way to do what is called pattern matching in most functional languages. You need to define a class which has one method for each function -in the abstract syntax of the grammar. If the functions is called +in the abstract syntax that you want to handle. If the functions is called f then you need a method called on_f. The method will be called each time when the corresponding function is encountered, and its arguments will be the arguments from the original tree. @@ -627,68 +728,6 @@ we call visit recursively to go deeper into the tree.

-Constructing new trees is also easy. You can either use -readExpr to read trees from strings, or you can -construct new trees from existing pieces. This is possible by - -using the constructor for pgf.Expr: -
->>> quant = pgf.readExpr("DetQuant IndefArt NumSg")
->>> e2 = pgf.Expr("DetCN", [quant, e])
->>> print(e2)
-DetCN (DetQuant IndefArt NumSg) (AdjCN (PositA red_A) (UseN theatre_N))
-
-
- -using the functions mkApp, mkStr, mkInt, mkFloat and mkMeta: -
-Prelude PGF2> let Just quant = readExpr "DetQuant IndefArt NumSg"
-Prelude PGF2> let e2 = mkApp "DetCN" [quant, e]
-Prelude PGF2> print e2
-DetCN (DetQuant IndefArt NumSg) (AdjCN (PositA red_A) (UseN theatre_N))
-
-
- -using the constructor for Expr: -
-Expr quant = Expr.readExpr("DetQuant IndefArt NumSg");
-Expr e2 = new Expr("DetCN", new Expr[] {quant, e});
-System.out.println(e2);
-
-
- -using the constructor for Expr: -
-Expr quant = Expr.ReadExpr("DetQuant IndefArt NumSg");
-Expr e2 = new Expr("DetCN", new Expr[] {quant, e});
-Console.WriteLine(e2);
-
-
- - -

Embedded GF Grammars

- -The GF compiler allows for easy integration of grammars in Haskell -applications. For that purpose the compiler generates Haskell code -that makes the integration of grammars easier. Since Python is a -dynamic language the same can be done at runtime. Once you load -the grammar you can call the method embed, which will -dynamically create a Python module with one Python function -for every function in the abstract syntax of the grammar. -After that you can simply import the module: -
->>> gr.embed("App")
-<module 'App' (built-in)>
->>> import App
-
-Now creating new trees is just a matter of calling ordinary Python -functions: -
->>> print(App.DetCN(quant,e))
-DetCN (DetQuant IndefArt NumSg) (AdjCN (PositA red_A) (UseN house_N))
-
-
-

Access the Morphological Lexicon

There are two methods that gives you direct access to the morphological -- cgit v1.2.3