From b296099441674e76b4af696f6954cd1f8be0815b Mon Sep 17 00:00:00 2001 From: bjorn Date: Wed, 13 Aug 2008 12:08:11 +0000 Subject: [PATCH] Include concrete syntax flags in generated JS. --- lib/javascript/gflib.js | 3 ++- lib/javascript/grammar.js | 2 +- src/GF/Compile/GFCCtoJS.hs | 7 ++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/javascript/gflib.js b/lib/javascript/gflib.js index 4e8b8223d..7dea8c494 100644 --- a/lib/javascript/gflib.js +++ b/lib/javascript/gflib.js @@ -282,7 +282,8 @@ function Concrete(abstr) { this.parser = undefined; } */ -function GFConcrete(rules, parser) { +function GFConcrete(flags, rules, parser) { + this.flags = flags; this.rules = rules; if (parser) { this.parser = parser; diff --git a/lib/javascript/grammar.js b/lib/javascript/grammar.js index b4eae708c..2b7bf86a7 100644 --- a/lib/javascript/grammar.js +++ b/lib/javascript/grammar.js @@ -1 +1 @@ -var Food = new GFGrammar(new GFAbstract("Phrase",{Boring: new Type([], "Quality"), Cheese: new Type([], "Kind"), Delicious: new Type([], "Quality"), Expensive: new Type([], "Quality"), Fish: new Type([], "Kind"), Fresh: new Type([], "Quality"), Is: new Type(["Item", "Quality"], "Phrase"), Italian: new Type([], "Quality"), QKind: new Type(["Quality", "Kind"], "Kind"), That: new Type(["Kind"], "Item"), This: new Type(["Kind"], "Item"), Very: new Type(["Quality"], "Quality"), Warm: new Type([], "Quality"), Wine: new Type([], "Kind")}),{FoodEng: new GFConcrete({Boring: function(cs){return new Arr(new Str("boring"));}, Cheese: function(cs){return new Arr(new Str("cheese"));}, Delicious: function(cs){return new Arr(new Str("delicious"));}, Expensive: function(cs){return new Arr(new Str("expensive"));}, Fish: function(cs){return new Arr(new Str("fish"));}, Fresh: function(cs){return new Arr(new Str("fresh"));}, Is: function(cs){return new Arr(new Seq(Food.concretes["FoodEng"].rule("_6", cs), new Str("is"), Food.concretes["FoodEng"].rule("_7", cs)));}, Italian: function(cs){return new Arr(new Str("Italian"));}, QKind: function(cs){return new Arr(new Seq(Food.concretes["FoodEng"].rule("_6", cs), Food.concretes["FoodEng"].rule("_7", cs)));}, That: function(cs){return new Arr(new Seq(new Str("that"), Food.concretes["FoodEng"].rule("_6", cs)));}, This: function(cs){return new Arr(new Seq(new Str("this"), Food.concretes["FoodEng"].rule("_6", cs)));}, Very: function(cs){return new Arr(new Seq(new Str("very"), Food.concretes["FoodEng"].rule("_6", cs)));}, Warm: function(cs){return new Arr(new Str("warm"));}, Wine: function(cs){return new Arr(new Str("wine"));}, _21: function(cs){return new Arr(cs[0]);}, _6: function(cs){return cs[0].sel(new Int(0));}, _7: function(cs){return cs[1].sel(new Int(0));}, Item: function(cs){return Food.concretes["FoodEng"].rule("_21", cs);}, Kind: function(cs){return Food.concretes["FoodEng"].rule("_21", cs);}, Phrase: function(cs){return Food.concretes["FoodEng"].rule("_21", cs);}, Quality: function(cs){return Food.concretes["FoodEng"].rule("_21", cs);}, "Int": function(cs){return new Arr(cs[0]);}, "Float": function(cs){return new Arr(cs[0]);}, "String": function(cs){return new Arr(cs[0]);}}, new Parser("Phrase",[new Rule(2, new FunApp("Wine",[]),[],[[new Terminal("wine")]]), new Rule(1, new FunApp("Warm",[]),[],[[new Terminal("warm")]]), new Rule(1, new FunApp("Very",[new Arg(0)]),[1],[[new Terminal("very"), new ArgProj(0, 0)]]), new Rule(4, new FunApp("This",[new Arg(0)]),[2],[[new Terminal("this"), new ArgProj(0, 0)]]), new Rule(4, new FunApp("That",[new Arg(0)]),[2],[[new Terminal("that"), new ArgProj(0, 0)]]), new Rule(2, new FunApp("QKind",[new Arg(0), new Arg(1)]),[1, 2],[[new ArgProj(0, 0), new ArgProj(1, 0)]]), new Rule(1, new FunApp("Italian",[]),[],[[new Terminal("Italian")]]), new Rule(3, new FunApp("Is",[new Arg(0), new Arg(1)]),[4, 1],[[new ArgProj(0, 0), new Terminal("is"), new ArgProj(1, 0)]]), new Rule(1, new FunApp("Fresh",[]),[],[[new Terminal("fresh")]]), new Rule(2, new FunApp("Fish",[]),[],[[new Terminal("fish")]]), new Rule(1, new FunApp("Expensive",[]),[],[[new Terminal("expensive")]]), new Rule(1, new FunApp("Delicious",[]),[],[[new Terminal("delicious")]]), new Rule(2, new FunApp("Cheese",[]),[],[[new Terminal("cheese")]]), new Rule(1, new FunApp("Boring",[]),[],[[new Terminal("boring")]])],{Float:[-3], Int:[-2], Item:[4], Kind:[2], Phrase:[3], Quality:[1], String:[-1], _Var:[-4]})), FoodIta: new GFConcrete({Boring: function(cs){return new Arr(new Str("noioso"));}, Cheese: function(cs){return new Arr(new Str("formaggio"));}, Delicious: function(cs){return new Arr(new Str("delizioso"));}, Expensive: function(cs){return new Arr(new Str("caro"));}, Fish: function(cs){return new Arr(new Str("pesce"));}, Fresh: function(cs){return new Arr(new Str("fresco"));}, Is: function(cs){return new Arr(new Seq(Food.concretes["FoodIta"].rule("_6", cs), new Str("è"), Food.concretes["FoodIta"].rule("_7", cs)));}, Italian: function(cs){return new Arr(new Str("italiano"));}, QKind: function(cs){return new Arr(new Seq(Food.concretes["FoodIta"].rule("_7", cs), Food.concretes["FoodIta"].rule("_6", cs)));}, That: function(cs){return new Arr(new Seq(new Str("quello"), Food.concretes["FoodIta"].rule("_6", cs)));}, This: function(cs){return new Arr(new Seq(new Str("questo"), Food.concretes["FoodIta"].rule("_6", cs)));}, Very: function(cs){return new Arr(new Seq(new Str("molto"), Food.concretes["FoodIta"].rule("_6", cs)));}, Warm: function(cs){return new Arr(new Str("caldo"));}, Wine: function(cs){return new Arr(new Str("vino"));}, _21: function(cs){return new Arr(cs[0]);}, _6: function(cs){return cs[0].sel(new Int(0));}, _7: function(cs){return cs[1].sel(new Int(0));}, Item: function(cs){return Food.concretes["FoodIta"].rule("_21", cs);}, Kind: function(cs){return Food.concretes["FoodIta"].rule("_21", cs);}, Phrase: function(cs){return Food.concretes["FoodIta"].rule("_21", cs);}, Quality: function(cs){return Food.concretes["FoodIta"].rule("_21", cs);}, "Int": function(cs){return new Arr(cs[0]);}, "Float": function(cs){return new Arr(cs[0]);}, "String": function(cs){return new Arr(cs[0]);}}, new Parser("Phrase",[new Rule(2, new FunApp("Wine",[]),[],[[new Terminal("vino")]]), new Rule(1, new FunApp("Warm",[]),[],[[new Terminal("caldo")]]), new Rule(1, new FunApp("Very",[new Arg(0)]),[1],[[new Terminal("molto"), new ArgProj(0, 0)]]), new Rule(4, new FunApp("This",[new Arg(0)]),[2],[[new Terminal("questo"), new ArgProj(0, 0)]]), new Rule(4, new FunApp("That",[new Arg(0)]),[2],[[new Terminal("quello"), new ArgProj(0, 0)]]), new Rule(2, new FunApp("QKind",[new Arg(0), new Arg(1)]),[1, 2],[[new ArgProj(1, 0), new ArgProj(0, 0)]]), new Rule(1, new FunApp("Italian",[]),[],[[new Terminal("italiano")]]), new Rule(3, new FunApp("Is",[new Arg(0), new Arg(1)]),[4, 1],[[new ArgProj(0, 0), new Terminal("è"), new ArgProj(1, 0)]]), new Rule(1, new FunApp("Fresh",[]),[],[[new Terminal("fresco")]]), new Rule(2, new FunApp("Fish",[]),[],[[new Terminal("pesce")]]), new Rule(1, new FunApp("Expensive",[]),[],[[new Terminal("caro")]]), new Rule(1, new FunApp("Delicious",[]),[],[[new Terminal("delizioso")]]), new Rule(2, new FunApp("Cheese",[]),[],[[new Terminal("formaggio")]]), new Rule(1, new FunApp("Boring",[]),[],[[new Terminal("noioso")]])],{Float:[-3], Int:[-2], Item:[4], Kind:[2], Phrase:[3], Quality:[1], String:[-1], _Var:[-4]}))}); +var Food = new GFGrammar(new GFAbstract("Phrase",{Boring: new Type([], "Quality"), Cheese: new Type([], "Kind"), Delicious: new Type([], "Quality"), Expensive: new Type([], "Quality"), Fish: new Type([], "Kind"), Fresh: new Type([], "Quality"), Is: new Type(["Item", "Quality"], "Phrase"), Italian: new Type([], "Quality"), QKind: new Type(["Quality", "Kind"], "Kind"), That: new Type(["Kind"], "Item"), This: new Type(["Kind"], "Item"), Very: new Type(["Quality"], "Quality"), Warm: new Type([], "Quality"), Wine: new Type([], "Kind")}),{FoodEng: new GFConcrete({coding: "latin1"},{Boring: function(cs){return new Arr(new Str("boring"));}, Cheese: function(cs){return new Arr(new Str("cheese"));}, Delicious: function(cs){return new Arr(new Str("delicious"));}, Expensive: function(cs){return new Arr(new Str("expensive"));}, Fish: function(cs){return new Arr(new Str("fish"));}, Fresh: function(cs){return new Arr(new Str("fresh"));}, Is: function(cs){return new Arr(new Seq(Food.concretes["FoodEng"].rule("_6", cs), new Str("is"), Food.concretes["FoodEng"].rule("_7", cs)));}, Italian: function(cs){return new Arr(new Str("Italian"));}, QKind: function(cs){return new Arr(new Seq(Food.concretes["FoodEng"].rule("_6", cs), Food.concretes["FoodEng"].rule("_7", cs)));}, That: function(cs){return new Arr(new Seq(new Str("that"), Food.concretes["FoodEng"].rule("_6", cs)));}, This: function(cs){return new Arr(new Seq(new Str("this"), Food.concretes["FoodEng"].rule("_6", cs)));}, Very: function(cs){return new Arr(new Seq(new Str("very"), Food.concretes["FoodEng"].rule("_6", cs)));}, Warm: function(cs){return new Arr(new Str("warm"));}, Wine: function(cs){return new Arr(new Str("wine"));}, _21: function(cs){return new Arr(cs[0]);}, _6: function(cs){return cs[0].sel(new Int(0));}, _7: function(cs){return cs[1].sel(new Int(0));}, Item: function(cs){return Food.concretes["FoodEng"].rule("_21", cs);}, Kind: function(cs){return Food.concretes["FoodEng"].rule("_21", cs);}, Phrase: function(cs){return Food.concretes["FoodEng"].rule("_21", cs);}, Quality: function(cs){return Food.concretes["FoodEng"].rule("_21", cs);}, "Int": function(cs){return new Arr(cs[0]);}, "Float": function(cs){return new Arr(cs[0]);}, "String": function(cs){return new Arr(cs[0]);}}, new Parser("Phrase",[new Rule(2, new FunApp("Wine",[]),[],[[new Terminal("wine")]]), new Rule(1, new FunApp("Warm",[]),[],[[new Terminal("warm")]]), new Rule(1, new FunApp("Very",[new Arg(0)]),[1],[[new Terminal("very"), new ArgProj(0, 0)]]), new Rule(4, new FunApp("This",[new Arg(0)]),[2],[[new Terminal("this"), new ArgProj(0, 0)]]), new Rule(4, new FunApp("That",[new Arg(0)]),[2],[[new Terminal("that"), new ArgProj(0, 0)]]), new Rule(2, new FunApp("QKind",[new Arg(0), new Arg(1)]),[1, 2],[[new ArgProj(0, 0), new ArgProj(1, 0)]]), new Rule(1, new FunApp("Italian",[]),[],[[new Terminal("Italian")]]), new Rule(3, new FunApp("Is",[new Arg(0), new Arg(1)]),[4, 1],[[new ArgProj(0, 0), new Terminal("is"), new ArgProj(1, 0)]]), new Rule(1, new FunApp("Fresh",[]),[],[[new Terminal("fresh")]]), new Rule(2, new FunApp("Fish",[]),[],[[new Terminal("fish")]]), new Rule(1, new FunApp("Expensive",[]),[],[[new Terminal("expensive")]]), new Rule(1, new FunApp("Delicious",[]),[],[[new Terminal("delicious")]]), new Rule(2, new FunApp("Cheese",[]),[],[[new Terminal("cheese")]]), new Rule(1, new FunApp("Boring",[]),[],[[new Terminal("boring")]])],{Float:[-3], Int:[-2], Item:[4], Kind:[2], Phrase:[3], Quality:[1], String:[-1], _Var:[-4]})), FoodIta: new GFConcrete({coding: "latin1"},{Boring: function(cs){return new Arr(new Str("noioso"));}, Cheese: function(cs){return new Arr(new Str("formaggio"));}, Delicious: function(cs){return new Arr(new Str("delizioso"));}, Expensive: function(cs){return new Arr(new Str("caro"));}, Fish: function(cs){return new Arr(new Str("pesce"));}, Fresh: function(cs){return new Arr(new Str("fresco"));}, Is: function(cs){return new Arr(new Seq(Food.concretes["FoodIta"].rule("_6", cs), new Str("è"), Food.concretes["FoodIta"].rule("_7", cs)));}, Italian: function(cs){return new Arr(new Str("italiano"));}, QKind: function(cs){return new Arr(new Seq(Food.concretes["FoodIta"].rule("_7", cs), Food.concretes["FoodIta"].rule("_6", cs)));}, That: function(cs){return new Arr(new Seq(new Str("quello"), Food.concretes["FoodIta"].rule("_6", cs)));}, This: function(cs){return new Arr(new Seq(new Str("questo"), Food.concretes["FoodIta"].rule("_6", cs)));}, Very: function(cs){return new Arr(new Seq(new Str("molto"), Food.concretes["FoodIta"].rule("_6", cs)));}, Warm: function(cs){return new Arr(new Str("caldo"));}, Wine: function(cs){return new Arr(new Str("vino"));}, _21: function(cs){return new Arr(cs[0]);}, _6: function(cs){return cs[0].sel(new Int(0));}, _7: function(cs){return cs[1].sel(new Int(0));}, Item: function(cs){return Food.concretes["FoodIta"].rule("_21", cs);}, Kind: function(cs){return Food.concretes["FoodIta"].rule("_21", cs);}, Phrase: function(cs){return Food.concretes["FoodIta"].rule("_21", cs);}, Quality: function(cs){return Food.concretes["FoodIta"].rule("_21", cs);}, "Int": function(cs){return new Arr(cs[0]);}, "Float": function(cs){return new Arr(cs[0]);}, "String": function(cs){return new Arr(cs[0]);}}, new Parser("Phrase",[new Rule(2, new FunApp("Wine",[]),[],[[new Terminal("vino")]]), new Rule(1, new FunApp("Warm",[]),[],[[new Terminal("caldo")]]), new Rule(1, new FunApp("Very",[new Arg(0)]),[1],[[new Terminal("molto"), new ArgProj(0, 0)]]), new Rule(4, new FunApp("This",[new Arg(0)]),[2],[[new Terminal("questo"), new ArgProj(0, 0)]]), new Rule(4, new FunApp("That",[new Arg(0)]),[2],[[new Terminal("quello"), new ArgProj(0, 0)]]), new Rule(2, new FunApp("QKind",[new Arg(0), new Arg(1)]),[1, 2],[[new ArgProj(1, 0), new ArgProj(0, 0)]]), new Rule(1, new FunApp("Italian",[]),[],[[new Terminal("italiano")]]), new Rule(3, new FunApp("Is",[new Arg(0), new Arg(1)]),[4, 1],[[new ArgProj(0, 0), new Terminal("è"), new ArgProj(1, 0)]]), new Rule(1, new FunApp("Fresh",[]),[],[[new Terminal("fresco")]]), new Rule(2, new FunApp("Fish",[]),[],[[new Terminal("pesce")]]), new Rule(1, new FunApp("Expensive",[]),[],[[new Terminal("caro")]]), new Rule(1, new FunApp("Delicious",[]),[],[[new Terminal("delizioso")]]), new Rule(2, new FunApp("Cheese",[]),[],[[new Terminal("formaggio")]]), new Rule(1, new FunApp("Boring",[]),[],[[new Terminal("noioso")]])],{Float:[-3], Int:[-2], Item:[4], Kind:[2], Phrase:[3], Quality:[1], String:[-1], _Var:[-4]}))}); diff --git a/src/GF/Compile/GFCCtoJS.hs b/src/GF/Compile/GFCCtoJS.hs index 8259e7385..3fe8b1635 100644 --- a/src/GF/Compile/GFCCtoJS.hs +++ b/src/GF/Compile/GFCCtoJS.hs @@ -14,6 +14,7 @@ import Control.Monad (mplus) import Data.Array (Array) import qualified Data.Array as Array import Data.Maybe (fromMaybe) +import Data.Map (Map) import qualified Data.Map as Map pgf2js :: PGF -> String @@ -38,9 +39,10 @@ absdef2js (f,(typ,_)) = concrete2js :: String -> String -> (CId,Concr) -> JS.Property concrete2js start n (c, cnc) = - JS.Prop l (new "GFConcrete" ([(JS.EObj $ ((map (cncdef2js n (prCId c)) ds) ++ litslins))] ++ + JS.Prop l (new "GFConcrete" ([flags,(JS.EObj $ ((map (cncdef2js n (prCId c)) ds) ++ litslins))] ++ maybe [] (parser2js start) (parser cnc))) where + flags = mapToJSObj JS.EStr $ cflags cnc l = JS.IdentPropName (JS.Ident (prCId c)) ds = concatMap Map.assocs [lins cnc, opers cnc, lindefs cnc] litslins = [JS.Prop (JS.StringPropName "Int") (JS.EFun [children] [JS.SReturn $ new "Arr" [JS.EIndex (JS.EVar children) (JS.EInt 0)]]), @@ -115,3 +117,6 @@ sym2js (FSymTok t) = new "Terminal" [JS.EStr t] new :: String -> [JS.Expr] -> JS.Expr new f xs = JS.ENew (JS.Ident f) xs + +mapToJSObj :: (a -> JS.Expr) -> Map CId a -> JS.Expr +mapToJSObj f m = JS.EObj [ JS.Prop (JS.IdentPropName (JS.Ident (prCId k))) (f v) | (k,v) <- Map.toList m ]