forked from GitHub/comp-syntax-gu-mlt
python examples added
This commit is contained in:
47
python/Draw.gf
Normal file
47
python/Draw.gf
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
abstract Draw = {
|
||||||
|
|
||||||
|
flags startcat = Command ;
|
||||||
|
|
||||||
|
cat
|
||||||
|
Command ;
|
||||||
|
Object ;
|
||||||
|
ObjectRef ;
|
||||||
|
Shape ;
|
||||||
|
Colour ;
|
||||||
|
Size ;
|
||||||
|
Place ;
|
||||||
|
|
||||||
|
fun
|
||||||
|
drawCommand : Object -> Command ;
|
||||||
|
removeCommand : ObjectRef -> Command ;
|
||||||
|
moveCommand : ObjectRef -> Place -> Command ;
|
||||||
|
|
||||||
|
shapeObject : Size -> Colour -> Shape -> Object ;
|
||||||
|
|
||||||
|
theObjectRef : Object -> ObjectRef ;
|
||||||
|
itObjectRef : ObjectRef ;
|
||||||
|
|
||||||
|
circle_Shape : Shape ;
|
||||||
|
square_Shape : Shape ;
|
||||||
|
|
||||||
|
big_Size : Size ;
|
||||||
|
small_Size : Size ;
|
||||||
|
|
||||||
|
noSize : Size ;
|
||||||
|
|
||||||
|
green_Colour : Colour ;
|
||||||
|
red_Colour : Colour ;
|
||||||
|
blue_Colour : Colour ;
|
||||||
|
yellow_Colour : Colour ;
|
||||||
|
|
||||||
|
noColour : Colour ;
|
||||||
|
|
||||||
|
upPlace : Place ;
|
||||||
|
downPlace : Place ;
|
||||||
|
leftPlace : Place ;
|
||||||
|
rightPlace : Place ;
|
||||||
|
midPlace : Place ;
|
||||||
|
|
||||||
|
noPlace : Place ;
|
||||||
|
|
||||||
|
}
|
||||||
55
python/DrawEng.gf
Normal file
55
python/DrawEng.gf
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
concrete DrawEng of Draw =
|
||||||
|
|
||||||
|
open SyntaxEng, ParadigmsEng, LexiconEng, IrregEng
|
||||||
|
in {
|
||||||
|
|
||||||
|
lincat
|
||||||
|
Command = Utt ;
|
||||||
|
Object = CN ;
|
||||||
|
ObjectRef = NP ;
|
||||||
|
Shape = CN ;
|
||||||
|
Colour = AP ;
|
||||||
|
Size = AP ;
|
||||||
|
Place = Adv ;
|
||||||
|
|
||||||
|
lin
|
||||||
|
drawCommand object =
|
||||||
|
mkUtt (mkImp (mkVP (mkV2 draw_V) (mkNP a_Det object))) -- draw a circle
|
||||||
|
| mkUtt (mkNP a_Det object) -- a circle
|
||||||
|
| mkUtt object -- circle
|
||||||
|
;
|
||||||
|
removeCommand object =
|
||||||
|
mkUtt (mkImp (mkVP (mkV2 "remove") object)) ;
|
||||||
|
moveCommand object place =
|
||||||
|
mkUtt (mkImp (mkVP (mkVP (mkV2 "move") object) place)) ;
|
||||||
|
|
||||||
|
shapeObject size colour shape = mkCN size (mkCN colour shape) ;
|
||||||
|
|
||||||
|
theObjectRef object = mkNP the_Det object ;
|
||||||
|
itObjectRef = it_NP ;
|
||||||
|
|
||||||
|
circle_Shape = mkCN (mkN "circle") ;
|
||||||
|
square_Shape = mkCN (mkN "square") ;
|
||||||
|
|
||||||
|
big_Size = mkAP big_A ;
|
||||||
|
small_Size = mkAP small_A ;
|
||||||
|
noSize = mkAP (mkA "") ; ---
|
||||||
|
|
||||||
|
green_Colour = mkAP green_A ;
|
||||||
|
red_Colour = mkAP red_A ;
|
||||||
|
blue_Colour = mkAP blue_A ;
|
||||||
|
yellow_Colour = mkAP yellow_A ;
|
||||||
|
|
||||||
|
noColour = mkAP (mkA "") ; ---
|
||||||
|
|
||||||
|
upPlace = pmkAdv "up" ;
|
||||||
|
downPlace = pmkAdv "down" ;
|
||||||
|
leftPlace = pmkAdv "left" ;
|
||||||
|
rightPlace = pmkAdv "right" ;
|
||||||
|
midPlace = pmkAdv "to the middle" ;
|
||||||
|
|
||||||
|
noPlace = pmkAdv "" ;
|
||||||
|
|
||||||
|
oper
|
||||||
|
pmkAdv : Str -> Adv = ParadigmsEng.mkAdv ;
|
||||||
|
}
|
||||||
56
python/DrawFin.gf
Normal file
56
python/DrawFin.gf
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
concrete DrawFin of Draw =
|
||||||
|
|
||||||
|
open SyntaxFin, ParadigmsFin, LexiconFin
|
||||||
|
in {
|
||||||
|
|
||||||
|
lincat
|
||||||
|
Command = Utt ;
|
||||||
|
Object = CN ;
|
||||||
|
ObjectRef = NP ;
|
||||||
|
Shape = CN ;
|
||||||
|
Colour = AP ;
|
||||||
|
Size = AP ;
|
||||||
|
Place = Adv ;
|
||||||
|
|
||||||
|
lin
|
||||||
|
drawCommand object =
|
||||||
|
mkUtt (mkImp (mkVP (mkV2 "piirtää") (mkNP a_Det object))) -- draw a circle
|
||||||
|
| mkUtt (mkNP a_Det object) -- a circle
|
||||||
|
| mkUtt object -- circle
|
||||||
|
;
|
||||||
|
removeCommand object =
|
||||||
|
mkUtt (mkImp (mkVP (mkV2 "poistaa") object)) ;
|
||||||
|
moveCommand object place =
|
||||||
|
mkUtt (mkImp (mkVP (mkVP (mkV2 (mkV "siirtää") partitive) object) place)) ;
|
||||||
|
|
||||||
|
shapeObject size colour shape = mkCN size (mkCN colour shape) ;
|
||||||
|
|
||||||
|
theObjectRef object = mkNP the_Det object ;
|
||||||
|
itObjectRef = it_NP ;
|
||||||
|
|
||||||
|
circle_Shape = mkCN (mkN "ympyrä" "ympyröitä") ;
|
||||||
|
square_Shape = mkCN (mkN "neliö" "neliöitä") ;
|
||||||
|
|
||||||
|
big_Size = mkAP big_A ;
|
||||||
|
small_Size = mkAP small_A ;
|
||||||
|
noSize = mkAP (invarA "") ; ---
|
||||||
|
|
||||||
|
green_Colour = mkAP green_A ;
|
||||||
|
red_Colour = mkAP red_A ;
|
||||||
|
blue_Colour = mkAP blue_A ;
|
||||||
|
yellow_Colour = mkAP yellow_A ;
|
||||||
|
|
||||||
|
noColour = mkAP (invarA "") ; ---
|
||||||
|
|
||||||
|
upPlace = pmkAdv "ylöspäin" ;
|
||||||
|
downPlace = pmkAdv "alaspäin" ;
|
||||||
|
leftPlace = pmkAdv "vasemmalle" ;
|
||||||
|
rightPlace = pmkAdv "oikealle" ;
|
||||||
|
midPlace = pmkAdv "keskelle" ;
|
||||||
|
|
||||||
|
noPlace = pmkAdv "" ;
|
||||||
|
|
||||||
|
oper
|
||||||
|
pmkAdv : Str -> Adv = ParadigmsFin.mkAdv ;
|
||||||
|
|
||||||
|
}
|
||||||
60
python/DrawSwe.gf
Normal file
60
python/DrawSwe.gf
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
concrete DrawSwe of Draw =
|
||||||
|
|
||||||
|
open SyntaxSwe, ParadigmsSwe, LexiconSwe, IrregSwe, Prelude,
|
||||||
|
(G = GrammarSwe)
|
||||||
|
in {
|
||||||
|
|
||||||
|
lincat
|
||||||
|
Command = Utt ;
|
||||||
|
Object = CN ;
|
||||||
|
ObjectRef = NP ;
|
||||||
|
Shape = CN ;
|
||||||
|
Colour = AP ** {isAdj : Bool} ;
|
||||||
|
Size = AP ** {isAdj : Bool} ;
|
||||||
|
Place = Adv ;
|
||||||
|
|
||||||
|
lin
|
||||||
|
drawCommand object =
|
||||||
|
mkUtt (mkImp (mkVP (mkV2 "rita") (mkNP a_Det object))) -- draw a circle
|
||||||
|
| mkUtt (mkNP a_Det object) -- a circle
|
||||||
|
| mkUtt object -- circle
|
||||||
|
;
|
||||||
|
removeCommand object =
|
||||||
|
mkUtt (mkImp (mkVP (mkV2 (mkV (mkV "ta") "bort")) object)) ;
|
||||||
|
moveCommand object place =
|
||||||
|
mkUtt (mkImp (mkVP (mkVP (mkV2 "flytta") object) place)) ;
|
||||||
|
|
||||||
|
shapeObject size colour shape =
|
||||||
|
G.AdjCN size (G.AdjCN colour shape ** {isMod = colour.isAdj})
|
||||||
|
** {isMod = orB size.isAdj colour.isAdj} ;
|
||||||
|
|
||||||
|
theObjectRef object = mkNP the_Det object ;
|
||||||
|
itObjectRef = mkNP (mkPN "den") ; --- it_NP = det ;
|
||||||
|
|
||||||
|
circle_Shape = mkCN (mkN "cirkel" "cirkeln" "cirklar" "cirklarna") ;
|
||||||
|
square_Shape = mkCN (mkN "kvadrat" "kvadrater") ;
|
||||||
|
|
||||||
|
big_Size = mkrAP big_A ;
|
||||||
|
small_Size = mkrAP small_A ;
|
||||||
|
noSize = emptyAP ;
|
||||||
|
|
||||||
|
green_Colour = mkrAP green_A ;
|
||||||
|
red_Colour = mkrAP red_A ;
|
||||||
|
blue_Colour = mkrAP blue_A ;
|
||||||
|
yellow_Colour = mkrAP yellow_A ;
|
||||||
|
|
||||||
|
noColour = emptyAP ;
|
||||||
|
|
||||||
|
upPlace = pmkAdv "upp" ;
|
||||||
|
downPlace = pmkAdv "ner" ;
|
||||||
|
leftPlace = pmkAdv "åt vänster" ;
|
||||||
|
rightPlace = pmkAdv "åt höger" ;
|
||||||
|
midPlace = pmkAdv "till mitten" ;
|
||||||
|
|
||||||
|
noPlace = pmkAdv "" ;
|
||||||
|
oper
|
||||||
|
emptyAP : AP ** {isAdj : Bool} = mkAP (invarA "") ** {isAdj = False} ; ---
|
||||||
|
mkrAP : A -> AP ** {isAdj : Bool} = \a -> mkAP a ** {isAdj = True} ;
|
||||||
|
pmkAdv : Str -> Adv = ParadigmsSwe.mkAdv ;
|
||||||
|
}
|
||||||
|
|
||||||
11
python/Makefile
Normal file
11
python/Makefile
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
minilang:
|
||||||
|
gf -make ../lab2/grammar/english/MiniLangEng.gf ../lab2/grammar/swedish/MiniLangSwe.gf
|
||||||
|
|
||||||
|
query:
|
||||||
|
gf -make QueryEng.gf QuerySwe.gf
|
||||||
|
|
||||||
|
draw:
|
||||||
|
gf -make DrawEng.gf DrawSwe.gf DrawFin.gf
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
40
python/Query.gf
Normal file
40
python/Query.gf
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
abstract Query = {
|
||||||
|
|
||||||
|
flags startcat = Query ;
|
||||||
|
|
||||||
|
cat
|
||||||
|
Query ;
|
||||||
|
Kind ;
|
||||||
|
Property ;
|
||||||
|
Term ;
|
||||||
|
Element ;
|
||||||
|
|
||||||
|
fun
|
||||||
|
QWhich : Kind -> Property -> Query ; -- which numbers are prime
|
||||||
|
QWhether : Term -> Property -> Query ; -- is any number prime
|
||||||
|
QWhat : Element -> Query ; -- what is the factorial of 10
|
||||||
|
|
||||||
|
TAll : Kind -> Term ; -- all numbers
|
||||||
|
TAny : Kind -> Term ; -- any number
|
||||||
|
TElement : Element -> Term ; -- 42
|
||||||
|
|
||||||
|
PAnd : Property -> Property -> Property ; -- even and prime
|
||||||
|
POr : Property -> Property -> Property ; -- even or odd
|
||||||
|
PNot : Property -> Property ; -- not prime
|
||||||
|
|
||||||
|
KProperty : Property -> Kind -> Kind ; -- even number
|
||||||
|
|
||||||
|
-- lexicon
|
||||||
|
|
||||||
|
KNumber : Kind ;
|
||||||
|
|
||||||
|
EInteger : Int -> Element ;
|
||||||
|
PEven, POdd, PPrime : Property ;
|
||||||
|
PDivisible : Term -> Property ;
|
||||||
|
PSmaller, PGreater, PEqual : Term -> Property ;
|
||||||
|
PBetween : Term -> Term -> Property ;
|
||||||
|
|
||||||
|
EFactorial : Element -> Element ;
|
||||||
|
ESum, EProduct, EMinus, EDivided : Element -> Element -> Element ;
|
||||||
|
|
||||||
|
}
|
||||||
94
python/QueryEng.gf
Normal file
94
python/QueryEng.gf
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
concrete QueryEng of Query =
|
||||||
|
|
||||||
|
open
|
||||||
|
SyntaxEng, ParadigmsEng,
|
||||||
|
SymbolicEng,
|
||||||
|
MarkupEng,
|
||||||
|
(M = MakeStructuralEng)
|
||||||
|
in {
|
||||||
|
|
||||||
|
lincat
|
||||||
|
Query = Utt ;
|
||||||
|
Kind = CN ;
|
||||||
|
Property = AP ;
|
||||||
|
Term = NP ;
|
||||||
|
Element = NP ;
|
||||||
|
|
||||||
|
lin
|
||||||
|
QWhich kind property =
|
||||||
|
mkUtt (mkQS (mkQCl (mkIP whichPl_IDet kind) property)) -- which numbers are prime
|
||||||
|
| mkUtt (mkImp (mkVP (mkV2 "list") (mkNP all_Predet (mkNP aPl_Det (mkCN property kind))))) -- list all prime numbers
|
||||||
|
| mkUtt (mkNP aPl_Det (mkCN property kind)) -- prime numbers
|
||||||
|
;
|
||||||
|
|
||||||
|
QWhether term property =
|
||||||
|
mkUtt (mkQS (mkQCl (mkCl term property))) -- is 51 prime
|
||||||
|
| mkUtt (mkQS (mkCl term property)) -- 51 is prime
|
||||||
|
;
|
||||||
|
|
||||||
|
QWhat element =
|
||||||
|
mkUtt (mkQS (mkQCl what_IP element)) -- what is 2 + 2
|
||||||
|
| mkUtt (mkImp (mkVP (mkV2 "compute") element)) -- compute 2 + 2
|
||||||
|
| mkUtt element -- 2 + 2
|
||||||
|
;
|
||||||
|
|
||||||
|
TAll kind =
|
||||||
|
mkNP all_Predet (mkNP aPl_Det kind) -- all numbers
|
||||||
|
| mkNP every_Det kind -- every number
|
||||||
|
;
|
||||||
|
|
||||||
|
TAny kind =
|
||||||
|
mkNP someSg_Det kind -- some number
|
||||||
|
| mkNP somePl_Det kind -- some numbers
|
||||||
|
| mkNP (M.mkDet "any" singular) kind -- any number
|
||||||
|
| mkNP (M.mkDet "any" plural) kind -- any numbers
|
||||||
|
;
|
||||||
|
|
||||||
|
TElement element = element ;
|
||||||
|
|
||||||
|
PAnd p q = mkAP and_Conj p q ;
|
||||||
|
POr p q = mkAP or_Conj p q ;
|
||||||
|
PNot p = mkAP (lin AdA {s = "not"}) p ;
|
||||||
|
|
||||||
|
KProperty property kind = mkCN property kind ;
|
||||||
|
|
||||||
|
-- lexicon
|
||||||
|
|
||||||
|
KNumber = mkCN (mkN "number") ;
|
||||||
|
EInteger i = symb i ;
|
||||||
|
PEven = mkAP (mkA "even") ;
|
||||||
|
POdd = mkAP (mkA "odd") ;
|
||||||
|
PPrime = mkAP (mkA "prime") ;
|
||||||
|
PDivisible term = mkAP (mkA2 (mkA "divisible") by8means_Prep) term ;
|
||||||
|
PSmaller term = mkAP (mkA "small") term ;
|
||||||
|
PGreater term = mkAP (mkA "great") term ;
|
||||||
|
PEqual term = mkAP (mkA2 (mkA "equal") to_Prep) term ;
|
||||||
|
PBetween x y = mkAP (mkA2 (mkA "between") (mkPrep "")) (mkNP and_Conj x y) ; ---
|
||||||
|
|
||||||
|
ESum x y =
|
||||||
|
mkNP the_Det (mkCN (mkN2 (mkN "sum")) (mkNP and_Conj x y)) -- the sum of x and y
|
||||||
|
| mkNP (mkConj "+" singular) x y -- x + y
|
||||||
|
| parenthNP (mkNP (mkConj "+" singular) x y) -- ( x + y )
|
||||||
|
;
|
||||||
|
EMinus x y =
|
||||||
|
mkNP the_Det (mkCN (mkN2 (mkN "difference")) (mkNP and_Conj x y)) -- the difference of x and y
|
||||||
|
| mkNP (mkConj "-" singular) x y -- x - y
|
||||||
|
| parenthNP (mkNP (mkConj "-" singular) x y) -- x - y
|
||||||
|
;
|
||||||
|
EProduct x y =
|
||||||
|
mkNP the_Det (mkCN (mkN2 (mkN "product")) (mkNP and_Conj x y)) -- the product of x and y
|
||||||
|
| mkNP (mkConj "*" singular) x y -- x * y
|
||||||
|
;
|
||||||
|
EDivided x y =
|
||||||
|
mkNP (mkConj "divided by" singular) x y -- the product of x and y
|
||||||
|
| mkNP (mkConj "/" singular) x y -- x * y
|
||||||
|
;
|
||||||
|
EFactorial x =
|
||||||
|
mkNP the_Det (mkCN (mkN2 (mkN "factorial")) x) -- the factorial of x
|
||||||
|
| mkNP x (ParadigmsEng.mkAdv "!") -- x !
|
||||||
|
;
|
||||||
|
|
||||||
|
oper
|
||||||
|
parenthNP : NP -> NP = \np -> MarkupNP (lin Mark {begin = "(" ; end = ")"}) np ;
|
||||||
|
|
||||||
|
}
|
||||||
45
python/QuerySwe.gf
Normal file
45
python/QuerySwe.gf
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
concrete QuerySwe of Query =
|
||||||
|
|
||||||
|
open
|
||||||
|
SyntaxSwe, ParadigmsSwe, SymbolicSwe, (L = LexiconSwe)
|
||||||
|
in {
|
||||||
|
|
||||||
|
lincat
|
||||||
|
Query = Utt ;
|
||||||
|
Kind = CN ;
|
||||||
|
Property = AP ;
|
||||||
|
Term = NP ;
|
||||||
|
Element = NP ;
|
||||||
|
|
||||||
|
lin
|
||||||
|
QWhich kind property = mkUtt (mkQS (mkQCl (mkIP whichPl_IDet kind) property)) ;
|
||||||
|
QWhether term property = mkUtt (mkQS (mkQCl (mkCl term property))) ;
|
||||||
|
QWhat element = mkUtt (mkQS (mkQCl what_IP element)) ;
|
||||||
|
|
||||||
|
TAll kind = mkNP all_Predet (mkNP aPl_Det kind) ;
|
||||||
|
TAny kind = mkNP someSg_Det kind ;
|
||||||
|
TElement element = element ;
|
||||||
|
|
||||||
|
PAnd p q = mkAP and_Conj p q ;
|
||||||
|
POr p q = mkAP or_Conj p q ;
|
||||||
|
PNot p = mkAP (lin AdA {s = "inte"}) p ; ---
|
||||||
|
|
||||||
|
KProperty property kind = mkCN property kind ;
|
||||||
|
|
||||||
|
-- lexicon
|
||||||
|
|
||||||
|
KNumber = mkCN (mkN "tal" "tal") ;
|
||||||
|
EInteger i = symb i ;
|
||||||
|
PEven = mkAP (mkA "jämn") ;
|
||||||
|
POdd = mkAP (invarA "udda") ;
|
||||||
|
PPrime = mkAP (mkA "prim") ; ----
|
||||||
|
PDivisible term = mkAP (mkA2 (mkA "delbar") with_Prep) term ;
|
||||||
|
PSmaller term = mkAP L.small_A term ;
|
||||||
|
PGreater term = mkAP L.big_A term ;
|
||||||
|
PBetween x y = mkAP (mkA2 (invarA "mellan") (mkPrep "")) (mkNP and_Conj x y) ; ---
|
||||||
|
|
||||||
|
ESum x y = mkNP the_Det (mkCN (mkN2 (mkN "summa")) (mkNP and_Conj x y)) ;
|
||||||
|
EProduct x y = mkNP the_Det (mkCN (mkN2 (mkN "produkt")) (mkNP and_Conj x y)) ;
|
||||||
|
EFactorial x = mkNP the_Det (mkCN (mkN2 (mkN "fakultet")) x) ;
|
||||||
|
|
||||||
|
}
|
||||||
122
python/README.md
Normal file
122
python/README.md
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
# Examples of embedded GF grammars in Python
|
||||||
|
|
||||||
|
The grammars use the Python binding available in
|
||||||
|
|
||||||
|
https://github.com/GrammaticalFramework/gf-core
|
||||||
|
|
||||||
|
see
|
||||||
|
|
||||||
|
`src/runtime/python/`
|
||||||
|
|
||||||
|
for installing the Python module `pgf`, and
|
||||||
|
|
||||||
|
`src/runtime/c/`
|
||||||
|
|
||||||
|
for the C runtime library that the bindings are based on.
|
||||||
|
You don't need Haskell to build these.
|
||||||
|
|
||||||
|
A general tutorial on the Python bindings can be found in
|
||||||
|
|
||||||
|
http://www.grammaticalframework.org/doc/runtime-api.html#python
|
||||||
|
|
||||||
|
A guide to GF for Python programmers can be found in
|
||||||
|
|
||||||
|
https://daherb.github.io/GF-for-Python-programmers/
|
||||||
|
|
||||||
|
|
||||||
|
## Translator
|
||||||
|
|
||||||
|
A minimal translator can be found in
|
||||||
|
|
||||||
|
[`minitranslator.py`](./minitranslator.py)
|
||||||
|
|
||||||
|
This program reads one line of input and translates it from English to Swedish by using `MiniGrammar.pgf`. Example:
|
||||||
|
```
|
||||||
|
$ echo "the cat is black" | python3 minitranslator.py
|
||||||
|
katten är svart
|
||||||
|
```
|
||||||
|
A more general version is in
|
||||||
|
|
||||||
|
[`translator.py`](./translator.py)
|
||||||
|
|
||||||
|
This program reads input line by line, tokenizes it (by a simple tokenizer), and uses an arbitrary pgf and language codes. Example:
|
||||||
|
```
|
||||||
|
$ cat findrawscript.txt | python3 translator.py Draw Fin Eng
|
||||||
|
# translating with Draw.pgf from DrawFin to DrawEng
|
||||||
|
draw a small red circle
|
||||||
|
draw a big yellow square
|
||||||
|
move the small red circle
|
||||||
|
remove it
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Drawing figures
|
||||||
|
|
||||||
|
A minimal drawing program with natural language input can found in
|
||||||
|
|
||||||
|
[`minidraw.py`](./minidraw.py)
|
||||||
|
|
||||||
|
This program reads one line of input in English and converts it to an action of drawing a circle or a square. Example:
|
||||||
|
```
|
||||||
|
$ python3 minidraw.py
|
||||||
|
draw a circle
|
||||||
|
```
|
||||||
|
The result is [this window](./dump-minidraw.png).
|
||||||
|
The program uses the simple graphics library from
|
||||||
|
|
||||||
|
https://mcsp.wartburg.edu/zelle/python/graphics.py
|
||||||
|
|
||||||
|
We also presuppose the grammar to be compiled with
|
||||||
|
`
|
||||||
|
make draw
|
||||||
|
`
|
||||||
|
A more complete version (using the same grammar) is in
|
||||||
|
|
||||||
|
[`draw.py`](./draw.py)
|
||||||
|
|
||||||
|
This program opens a session where it reads input line by line, in a language specified by a language code. Example:
|
||||||
|
```
|
||||||
|
$ python3 draw.py Eng
|
||||||
|
draw a small red circle
|
||||||
|
draw a blue square
|
||||||
|
move it
|
||||||
|
move the small red circle
|
||||||
|
```
|
||||||
|
The result is [this window](./dump-draw.png).
|
||||||
|
|
||||||
|
The grammar, [`Draw.gf`](./Draw.gf), illustrates a few things...
|
||||||
|
|
||||||
|
|
||||||
|
## Answering queries
|
||||||
|
|
||||||
|
A minimal query answering program with natural language input can found in
|
||||||
|
|
||||||
|
[`miniquery.py`](./miniquery.py)
|
||||||
|
|
||||||
|
This program reads one line of input in English and executes a query, which is either asking if a number is prime, or calculating a sum. Examples:
|
||||||
|
```
|
||||||
|
$ echo "is 143 prime" | python3 miniquery.py
|
||||||
|
False
|
||||||
|
$ echo "1 + 2 + 3" | python3 miniquery.py
|
||||||
|
6
|
||||||
|
```
|
||||||
|
We presuppose the grammar to be compiled with
|
||||||
|
`
|
||||||
|
make query
|
||||||
|
`
|
||||||
|
A more complete version (using the same grammar) is in
|
||||||
|
|
||||||
|
[`query.py`](./query.py)
|
||||||
|
|
||||||
|
This program uses a large grammar with more predicates, operations, and logical forms such as quantifiers. It still reads just one line of input, but allows the language to be specified by a language code. Example:
|
||||||
|
```
|
||||||
|
$ echo "what is the factorial of 12" | python3 query.py Eng
|
||||||
|
479001600
|
||||||
|
$ echo "prime numbers between 200 and 300" | python3 query.py Eng
|
||||||
|
[211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293]
|
||||||
|
WARNING: ambiguous
|
||||||
|
$ echo "are all prime numbers odd" | python3 query.py Eng
|
||||||
|
False
|
||||||
|
```
|
||||||
|
The grammar, [`Query.gf`](./Query.gf), illustrates a few things...
|
||||||
|
|
||||||
193
python/draw.py
Normal file
193
python/draw.py
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
# drawing figures with natural language commands
|
||||||
|
# presupposes 'gf -make DrawEng.gf (DrawSwe.gf ...)'
|
||||||
|
|
||||||
|
import pgf
|
||||||
|
from graphics import *
|
||||||
|
import sys
|
||||||
|
from random import randrange
|
||||||
|
|
||||||
|
# we assume this abstract syntax
|
||||||
|
absmodule = "Draw"
|
||||||
|
|
||||||
|
# change this to change input language
|
||||||
|
langname = absmodule + "Eng"
|
||||||
|
|
||||||
|
# the size of canvas
|
||||||
|
hsize, vsize = 1000,1000
|
||||||
|
|
||||||
|
# the mid point of the canvas
|
||||||
|
midpoint = (hsize/2,vsize/2)
|
||||||
|
|
||||||
|
# unit size granularity
|
||||||
|
sizeunit = hsize//10
|
||||||
|
|
||||||
|
# big and small size factors
|
||||||
|
bigsize = 2
|
||||||
|
smallsize = 0.2
|
||||||
|
|
||||||
|
# limits of radius and diameter/2
|
||||||
|
maxradius = sizeunit
|
||||||
|
minradius = sizeunit/2
|
||||||
|
|
||||||
|
# distance of movement
|
||||||
|
distunit = 2*sizeunit
|
||||||
|
|
||||||
|
def execute(command,win):
|
||||||
|
"top level: execute a Command in a window (given in main)"
|
||||||
|
fun,args = command.unpack()
|
||||||
|
|
||||||
|
if fun == "drawCommand":
|
||||||
|
obj = shape(args[0])
|
||||||
|
obj.draw(win)
|
||||||
|
return str(args[0]),obj,fun
|
||||||
|
|
||||||
|
if fun == "removeCommand":
|
||||||
|
key = reference(args[0])
|
||||||
|
return key,None,fun
|
||||||
|
|
||||||
|
if fun == "moveCommand":
|
||||||
|
key = reference(args[0])
|
||||||
|
return key,direction(args[1]),fun
|
||||||
|
|
||||||
|
def reference(objectref):
|
||||||
|
fun,args = objectref.unpack()
|
||||||
|
if fun == "theObjectRef":
|
||||||
|
return(str(args[0]))
|
||||||
|
else:
|
||||||
|
return(str(objectref))
|
||||||
|
|
||||||
|
def shape(obj):
|
||||||
|
"draw a Shape of random size and position, possibly with colour and rough size specified"
|
||||||
|
fun,args = obj.unpack()
|
||||||
|
|
||||||
|
sz,xx = args[0].unpack()
|
||||||
|
if sz == "big_Size":
|
||||||
|
factor = bigsize
|
||||||
|
elif sz == "small_Size":
|
||||||
|
factor = smallsize
|
||||||
|
else:
|
||||||
|
factor = 1
|
||||||
|
|
||||||
|
midx,midy = midpoint
|
||||||
|
x1 = midx + randrange(-midx,midx,1)
|
||||||
|
y1 = midy + randrange(-midy,midy,1)
|
||||||
|
r = factor * randrange(minradius, maxradius, 1)
|
||||||
|
d = 2 * r
|
||||||
|
x2 = x1 + d
|
||||||
|
y2 = y1 + d
|
||||||
|
sh,xx = args[2].unpack()
|
||||||
|
if sh == "circle_Shape":
|
||||||
|
shap = Circle(Point(x1,y1),r)
|
||||||
|
elif sh == "square_Shape":
|
||||||
|
shap = Rectangle(Point(x1,y1),Point(x2,y2))
|
||||||
|
else:
|
||||||
|
shap = None
|
||||||
|
|
||||||
|
co,xx = args[1].unpack()
|
||||||
|
if co == "green_Colour":
|
||||||
|
shap.setFill('green')
|
||||||
|
elif co == "red_Colour":
|
||||||
|
shap.setFill('red')
|
||||||
|
elif co == "blue_Colour":
|
||||||
|
shap.setFill('blue')
|
||||||
|
elif co == "yellow_Colour":
|
||||||
|
shap.setFill('yellow')
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return shap
|
||||||
|
|
||||||
|
def direction(place):
|
||||||
|
fun,args = place.unpack()
|
||||||
|
if fun == "upPlace":
|
||||||
|
return 0,-distunit
|
||||||
|
if fun == "downPlace":
|
||||||
|
return 0,distunit
|
||||||
|
if fun == "leftPlace":
|
||||||
|
return -distunit,0
|
||||||
|
if fun == "rightPlace":
|
||||||
|
return distunit,0
|
||||||
|
else:
|
||||||
|
return randrange(-2*distunit,2*distunit,1),randrange(-2*distunit,2*distunit,1)
|
||||||
|
|
||||||
|
def addRef(ref,obj,refs):
|
||||||
|
"adds a reference and object to the top of the stack"
|
||||||
|
return [(ref,obj)] + refs
|
||||||
|
|
||||||
|
def lookupRef(ref,refs):
|
||||||
|
"return the first value and index of ref in a list of pairs refs"
|
||||||
|
i = 0
|
||||||
|
for ro in refs:
|
||||||
|
r,obj = ro
|
||||||
|
if matchRef(ref,r):
|
||||||
|
return r,obj,i
|
||||||
|
else:
|
||||||
|
i = i + 1
|
||||||
|
return None,None,None
|
||||||
|
|
||||||
|
def removeRef(ref,refs):
|
||||||
|
"remove the first pair matching ref in refs"
|
||||||
|
r,obj,i = lookupRef(ref,refs)
|
||||||
|
refs.pop(i)
|
||||||
|
return refs
|
||||||
|
|
||||||
|
def matchRef(ref,r):
|
||||||
|
if ref == "itObjectRef":
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
refws = ref.split()
|
||||||
|
rws = r.split()
|
||||||
|
m = True
|
||||||
|
for i in range(1,4):
|
||||||
|
if (refws[i][0:2] != "no") and (refws[i] != rws[i]):
|
||||||
|
return False
|
||||||
|
return m
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"initialize with a window, process Command input line by line; optional language argument"
|
||||||
|
win = GraphWin("GF Draw", hsize, vsize)
|
||||||
|
refs = []
|
||||||
|
latest = "it"
|
||||||
|
gr = pgf.readPGF(absmodule + ".pgf")
|
||||||
|
lang = langname
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
lang = absmodule + sys.argv[1]
|
||||||
|
eng = gr.languages[lang]
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
line = input("")
|
||||||
|
except EOFError:
|
||||||
|
break
|
||||||
|
if not(line):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
px = eng.parse(line.lower())
|
||||||
|
p,tree = px.__next__()
|
||||||
|
key,obj,co = execute(tree,win)
|
||||||
|
if co == "drawCommand":
|
||||||
|
refs = addRef(key,obj,refs)
|
||||||
|
elif co == "removeCommand":
|
||||||
|
ref,sh,i = lookupRef(key,refs)
|
||||||
|
if sh is None:
|
||||||
|
print("no such object")
|
||||||
|
else:
|
||||||
|
sh.undraw()
|
||||||
|
refs = removeRef(key,refs)
|
||||||
|
elif co == "moveCommand":
|
||||||
|
x,y = obj
|
||||||
|
ref,sh,i = lookupRef(key,refs)
|
||||||
|
if sh is None:
|
||||||
|
print("no such object")
|
||||||
|
else:
|
||||||
|
sh.move(x,y)
|
||||||
|
refs = [(ref,sh)] + refs[:i] + refs[i+1:]
|
||||||
|
else:
|
||||||
|
print("nothing else can be done")
|
||||||
|
print(refs) ## debugging
|
||||||
|
except pgf.ParseError:
|
||||||
|
print("# NO PARSE", line)
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
||||||
4
python/findrawscript.txt
Normal file
4
python/findrawscript.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
piirrä pieni punainen ympyrä
|
||||||
|
piirrä suuri keltainen neliö
|
||||||
|
siirrä pientä punaista ympyrää
|
||||||
|
poista se
|
||||||
1015
python/graphics.py
Normal file
1015
python/graphics.py
Normal file
File diff suppressed because it is too large
Load Diff
51
python/minidraw.py
Normal file
51
python/minidraw.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# minimal drawing from natural language input: just draw one square or circle
|
||||||
|
# presupposes 'gf -make DrawEng.gf'
|
||||||
|
|
||||||
|
import pgf
|
||||||
|
from graphics import *
|
||||||
|
|
||||||
|
# we assume this abstract syntax
|
||||||
|
absmodule = "Draw"
|
||||||
|
|
||||||
|
# change this to change input language
|
||||||
|
langname = absmodule + "Eng"
|
||||||
|
|
||||||
|
def execute(command,win):
|
||||||
|
"interpret drawCommand; other commands ignored"
|
||||||
|
fun,args = command.unpack()
|
||||||
|
|
||||||
|
if fun == "drawCommand":
|
||||||
|
obj = shape(args[0])
|
||||||
|
obj.draw(win)
|
||||||
|
else:
|
||||||
|
print("command not available")
|
||||||
|
|
||||||
|
|
||||||
|
def shape(obj):
|
||||||
|
"draw Shape, ignoring given colour and size in this simple example"
|
||||||
|
fun,args = obj.unpack()
|
||||||
|
sh,xx = args[2].unpack()
|
||||||
|
|
||||||
|
if sh == "circle_Shape":
|
||||||
|
shap = Circle(Point(300,300),200)
|
||||||
|
elif sh == "square_Shape":
|
||||||
|
shap = Rectangle(Point(200,200),Point(600,600))
|
||||||
|
else:
|
||||||
|
shap = None
|
||||||
|
|
||||||
|
return shap
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"execute one line of input, quit by second Enter"
|
||||||
|
win = GraphWin("GF Draw", 1000, 1000)
|
||||||
|
gr = pgf.readPGF(absmodule + ".pgf")
|
||||||
|
eng = gr.languages[langname]
|
||||||
|
line = input()
|
||||||
|
px = eng.parse(line.lower())
|
||||||
|
p,tree = px.__next__()
|
||||||
|
execute(tree,win)
|
||||||
|
input()
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
||||||
72
python/miniquery.py
Normal file
72
python/miniquery.py
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
# a minimal query system for arithmetic, using Montague-style semantics
|
||||||
|
# and an embedded GF grammar
|
||||||
|
# examples: "is 131 prime", "2 + 2"
|
||||||
|
# presupposes 'gf -make QueryEng (QuerySwe ...)'
|
||||||
|
|
||||||
|
import pgf
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# we assume this abstract syntax
|
||||||
|
absmodule = "Query"
|
||||||
|
|
||||||
|
# change this to change input language
|
||||||
|
langname = absmodule + "Eng"
|
||||||
|
|
||||||
|
# the meaning of "number" in unrestricted quantification
|
||||||
|
allNumbers = range(1,10000)
|
||||||
|
|
||||||
|
def answer(tree):
|
||||||
|
"top level Query interpreter"
|
||||||
|
fun,args = tree.unpack()
|
||||||
|
|
||||||
|
if fun == "QWhether":
|
||||||
|
ans = predicate(args[1])(value(args[0]))
|
||||||
|
else: # QWhat
|
||||||
|
ans = value(args[0])
|
||||||
|
|
||||||
|
return str(ans)
|
||||||
|
|
||||||
|
def predicate(property):
|
||||||
|
"takes Property or Kind to int -> bool"
|
||||||
|
prop,pargs = property.unpack()
|
||||||
|
if prop == "PPrime":
|
||||||
|
return prime
|
||||||
|
else:
|
||||||
|
print("property not available")
|
||||||
|
|
||||||
|
def value(term):
|
||||||
|
"takes Term to int, does not cover quantifiers"
|
||||||
|
fun,args = term.unpack()
|
||||||
|
if fun == "TElement":
|
||||||
|
return value(args[0])
|
||||||
|
elif fun == "EInteger":
|
||||||
|
return int(args[0].unpack())
|
||||||
|
elif fun == "ESum":
|
||||||
|
return value(args[0]) + value(args[1])
|
||||||
|
else:
|
||||||
|
print("term not availeble")
|
||||||
|
|
||||||
|
def prime(n):
|
||||||
|
"simple way to decide if a positive number is prime"
|
||||||
|
if n == 1:
|
||||||
|
r = False
|
||||||
|
else:
|
||||||
|
r = True
|
||||||
|
for k in range(2,n//2+1):
|
||||||
|
if n % k == 0: return False
|
||||||
|
return r
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"main function to be called from stdio"
|
||||||
|
|
||||||
|
# read in the grammar, set up the input language
|
||||||
|
grammar = pgf.readPGF(absmodule + ".pgf")
|
||||||
|
lang = grammar.languages[langname]
|
||||||
|
|
||||||
|
# read a line of input, parse in lang, return answer
|
||||||
|
line = input("")
|
||||||
|
parseresult = lang.parse(line)
|
||||||
|
prob,tree = parseresult.__next__()
|
||||||
|
print(answer(tree))
|
||||||
|
|
||||||
|
main()
|
||||||
25
python/minitranslator.py
Normal file
25
python/minitranslator.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# minimal translator that reads one line from stdio and translates from Eng to Swe with Minilang
|
||||||
|
# presupposes 'make minilang'
|
||||||
|
|
||||||
|
import pgf
|
||||||
|
|
||||||
|
# change these three to translate with other grammars and languages
|
||||||
|
absmodule = "MiniLang"
|
||||||
|
fromname = absmodule + "Eng"
|
||||||
|
toname = absmodule + "Swe"
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# read in the grammar, set up to and from languages
|
||||||
|
grammar = pgf.readPGF(absmodule + ".pgf")
|
||||||
|
fromlang = grammar.languages[fromname]
|
||||||
|
tolang = grammar.languages[toname]
|
||||||
|
|
||||||
|
# read a line of input, parse in "from" language, linearize in "to" language
|
||||||
|
line = input("")
|
||||||
|
parseresult = fromlang.parse(line)
|
||||||
|
prob,tree = parseresult.__next__()
|
||||||
|
print(tolang.linearize(tree))
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
||||||
151
python/query.py
Normal file
151
python/query.py
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
# a simple query system for arithmetic, using Montague-style semantics
|
||||||
|
# and an embedded GF grammar
|
||||||
|
# examples: "is 131 prime", "which numbers are prime", "365 * 24 * 60"
|
||||||
|
# presupposes 'gf -make QueryEng (QuerySwe ...)'
|
||||||
|
|
||||||
|
import pgf
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# we assume this abstract syntax
|
||||||
|
absmodule = "Query"
|
||||||
|
|
||||||
|
# change this to change input language
|
||||||
|
langname = absmodule + "Eng"
|
||||||
|
|
||||||
|
# the meaning of "number" in unrestricted quantification
|
||||||
|
allNumbers = range(1,10000)
|
||||||
|
|
||||||
|
def answer(tree):
|
||||||
|
"top level Query interpreter"
|
||||||
|
fun,args = tree.unpack()
|
||||||
|
|
||||||
|
if fun == "QWhich":
|
||||||
|
ans = enumerate(lambda x: predicate(args[0])(x) and predicate(args[1])(x), allNumbers)
|
||||||
|
elif fun == "QWhether":
|
||||||
|
ans = quantifier(args[0])(predicate(args[1]))
|
||||||
|
else: # QWhat
|
||||||
|
ans = value(args[0])
|
||||||
|
|
||||||
|
return str(ans)
|
||||||
|
|
||||||
|
def predicate(property):
|
||||||
|
"takes Property or Kind to int -> bool"
|
||||||
|
prop,pargs = property.unpack()
|
||||||
|
if prop == "PAnd":
|
||||||
|
return lambda x: predicate(pargs[0])(x) and predicate(pargs[1])(x)
|
||||||
|
elif prop == "POr":
|
||||||
|
return lambda x: predicate(pargs[0])(x) or predicate(pargs[1])(x)
|
||||||
|
elif prop == "PNot":
|
||||||
|
return lambda x: not predicate(pargs[0])(x)
|
||||||
|
elif prop == "PEven":
|
||||||
|
return lambda x: x % 2 == 0
|
||||||
|
elif prop == "POdd":
|
||||||
|
return lambda x: x % 2 != 0
|
||||||
|
elif prop == "PEqual":
|
||||||
|
return lambda x: quantifier(pargs[0])(lambda y: x == y)
|
||||||
|
elif prop == "PSmaller":
|
||||||
|
return lambda x: quantifier(pargs[0])(lambda y: x < y)
|
||||||
|
elif prop == "PGreater":
|
||||||
|
return lambda x: quantifier(pargs[0])(lambda y: x > y)
|
||||||
|
elif prop == "PBetween":
|
||||||
|
return lambda y: quantifier(pargs[0])(lambda x: quantifier(pargs[1])(lambda z: x < y and y < z))
|
||||||
|
elif prop == "PPrime":
|
||||||
|
return prime
|
||||||
|
|
||||||
|
# works also for Kind:
|
||||||
|
elif prop == "KNumber":
|
||||||
|
return lambda x: True
|
||||||
|
elif prop == "KProperty":
|
||||||
|
return lambda x: predicate(pargs[0])(x) and predicate(pargs[1])(x)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("not a valid property",property)
|
||||||
|
|
||||||
|
def quantifier(term):
|
||||||
|
"takes Term to (int -> bool) -> bool"
|
||||||
|
fun,args = term.unpack()
|
||||||
|
if fun == "TElement":
|
||||||
|
return lambda p: p(value(args[0]))
|
||||||
|
elif fun == "TAll":
|
||||||
|
return lambda p: forAll(lambda x: not predicate(args[0])(x) or p(x), allNumbers)
|
||||||
|
elif fun == "TAny":
|
||||||
|
return lambda p: forSome(lambda x: predicate(args[0])(x) and p(x), allNumbers)
|
||||||
|
else:
|
||||||
|
print("not a valid term",term)
|
||||||
|
|
||||||
|
def value(element):
|
||||||
|
"takes Element to int"
|
||||||
|
fun,args = element.unpack()
|
||||||
|
if fun == "EInteger":
|
||||||
|
return int(args[0].unpack())
|
||||||
|
elif fun == "ESum":
|
||||||
|
return value(args[0]) + value(args[1])
|
||||||
|
elif fun == "EProduct":
|
||||||
|
return value(args[0]) * value(args[1])
|
||||||
|
elif fun == "EMinus":
|
||||||
|
return value(args[0]) - value(args[1])
|
||||||
|
elif fun == "EDivided":
|
||||||
|
return value(args[0]) / value(args[1]) ## // ?
|
||||||
|
elif fun == "EFactorial":
|
||||||
|
return factorial(value(args[0]))
|
||||||
|
else:
|
||||||
|
print("not a valid element",element)
|
||||||
|
|
||||||
|
def prime(n):
|
||||||
|
"simple way to decide if a positive number is prime"
|
||||||
|
if n == 1:
|
||||||
|
r = False
|
||||||
|
else:
|
||||||
|
r = True
|
||||||
|
for k in range(2,n//2+1):
|
||||||
|
if n % k == 0: return False
|
||||||
|
return r
|
||||||
|
|
||||||
|
def forAll(p,ns):
|
||||||
|
"universal quantifier over a list"
|
||||||
|
for n in ns:
|
||||||
|
if not p(n): return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def forSome(p,ns):
|
||||||
|
"existential quantifier over a list"
|
||||||
|
for n in ns:
|
||||||
|
if p(n): return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def enumerate(p,ns):
|
||||||
|
"filter over a list"
|
||||||
|
r = []
|
||||||
|
for n in ns:
|
||||||
|
if p(n): r = r + [n]
|
||||||
|
return r
|
||||||
|
|
||||||
|
def enumer(p,ns):
|
||||||
|
return [n for n in ns if p(n)]
|
||||||
|
|
||||||
|
def factorial(n):
|
||||||
|
"factorial of positive numbers"
|
||||||
|
r = 1
|
||||||
|
for k in range(1,n+1):
|
||||||
|
r = k*r
|
||||||
|
return r
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"main function to be called from stdio, language code as optional argument"
|
||||||
|
|
||||||
|
# read in the grammar, set up the input language
|
||||||
|
grammar = pgf.readPGF(absmodule + ".pgf")
|
||||||
|
langcode = langname
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
langcode = absmodule + sys.argv[1]
|
||||||
|
lang = grammar.languages[langcode]
|
||||||
|
|
||||||
|
# read a line of input, parse in lang, return answer
|
||||||
|
line = input("")
|
||||||
|
parseresult = lang.parse(line)
|
||||||
|
prob,tree = parseresult.__next__()
|
||||||
|
# print(tree) ## debugging
|
||||||
|
print(answer(tree))
|
||||||
|
for r in parseresult: print("WARNING: ambiguous")
|
||||||
|
|
||||||
|
main()
|
||||||
68
python/translator.py
Normal file
68
python/translator.py
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
# translator for arbitrary pgf grammar and language pair, given as arguments
|
||||||
|
|
||||||
|
import pgf
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def trim(s0):
|
||||||
|
"lower-case first word and tokenize"
|
||||||
|
s = s0.strip()
|
||||||
|
if not(s):
|
||||||
|
return s
|
||||||
|
s = (s[0].lower() + s[1:])
|
||||||
|
r = ""
|
||||||
|
for c in s:
|
||||||
|
if c in [',','.',':','(',')']:
|
||||||
|
r = r + ' ' + c + ' '
|
||||||
|
else:
|
||||||
|
r = r + c
|
||||||
|
return r
|
||||||
|
|
||||||
|
def missing(eng,s):
|
||||||
|
"words in a sentence not found in morphological analysis"
|
||||||
|
ws = s.split()
|
||||||
|
ms = []
|
||||||
|
for w in ws:
|
||||||
|
if not eng.lookupMorpho(w): # strange behaviour of eng
|
||||||
|
ms = ms + [w]
|
||||||
|
return ms
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"translation loop, reads stdio line by line"
|
||||||
|
if len(sys.argv) < 4:
|
||||||
|
print(" usage: python3 translator.py <pgf-file-prefix> <from-lang-suffix> <to-lang-suffix> -debug?")
|
||||||
|
print(" e.g. python3 translator.py CSETranslator Eng Swe")
|
||||||
|
print(" The program reads and writes stdio line by line, e.g")
|
||||||
|
print(" cat ../course_plans/TIN214Eng.txt | python3 translator.py CSEShallow Eng Swe")
|
||||||
|
return
|
||||||
|
pgfm = sys.argv[1]
|
||||||
|
pgff = pgfm + ".pgf"
|
||||||
|
ceng = pgfm + sys.argv[2]
|
||||||
|
cswe = pgfm + sys.argv[3]
|
||||||
|
debug = len(sys.argv) == 5 and sys.argv[4] == "-debug"
|
||||||
|
gr = pgf.readPGF(pgff)
|
||||||
|
eng = gr.languages[ceng]
|
||||||
|
swe = gr.languages[cswe]
|
||||||
|
print("#","translating with",pgff,"from",ceng,"to",cswe)
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
line = input("")
|
||||||
|
except EOFError:
|
||||||
|
break
|
||||||
|
t = trim(line)
|
||||||
|
if not(t):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
px = eng.parse(t)
|
||||||
|
p,e = px.__next__()
|
||||||
|
if debug:
|
||||||
|
print("# TREE", e)
|
||||||
|
print(swe.linearize(e))
|
||||||
|
except pgf.ParseError:
|
||||||
|
print("# NO PARSE", t)
|
||||||
|
if debug:
|
||||||
|
print("# MISSING", missing(eng,t))
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user