From 0ef8dced529708e6ea71d23ad8dd2f0734ec0918 Mon Sep 17 00:00:00 2001 From: bringert Date: Fri, 15 Dec 2006 16:08:39 +0000 Subject: [PATCH] Include update function in generated VoiceXML. Generated linearization javaScript now uses the same abstract syntax representation as SISR. --- lib/javascript/gflib.js | 62 ++++++++++++++++++++++++------ src/GF/Speech/GrammarToVoiceXML.hs | 7 +++- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/lib/javascript/gflib.js b/lib/javascript/gflib.js index f40b2ab55..630c01a3d 100644 --- a/lib/javascript/gflib.js +++ b/lib/javascript/gflib.js @@ -2,20 +2,52 @@ function Fun(name) { this.name = name; - this.children = copy_arguments(arguments, 1); } Fun.prototype.toString = function () { return this.show(0); } ; Fun.prototype.show = function (prec) { var s = this.name; - for (var i = 0; i < this.children.length; i++) { - s += " " + this.children[i].show(1); + var cs = this.getChildren(); + for (var c in cs) { + s += " " + c.show(1); } - if (prec > 0 && this.children.length > 0) { + if (prec > 0 && cs.length > 0) { s = "(" + s + ")" ; } return s; +}; +Fun.prototype.getChild = function (i) { + return this['arg'+i]; +}; +Fun.prototype.setChild = function (i,c) { + this['arg'+i] = c; +}; +/* Gets an array containing all the children. Modifying the array does not + change the tree, but modifying the elements of the array does. */ +Fun.prototype.getChildren = function () { + var a = new Array(); + for (var i = 0; ; i++) { + var c = this.getChild(i); + if (isUndefined(c)) { break; } + a.push(c); + } + return a; } ; +/* Hack to get around the fact that our SISR doesn't build real Fun objects. */ +function copyTree(x) { + if (typeof x == 'string' && x == '?') { + return '?'; + } else { + var t = new Fun(x.name); + for (var i = 0; ; i++) { + var c = x['arg' + i]; + if (isUndefined(c)) { break; } + t.setChild(i, copyTree(c)); + } + return t; + } +} + function parseTree(str) { return parseTree_(str.match(new RegExp("[\\w\\']+|\\(|\\)","g")), 0); } @@ -31,15 +63,15 @@ function parseTree_(tokens, prec) { var tree = new Fun(t); if (prec == 0) { var c; - while ((c = parseTree_(tokens, 1)) !== null) { - tree.children.push(c); + var i; + for (i = 0; (c = parseTree_(tokens, 1)) !== null; i++) { + tree.setChild(i,c); } } return tree; } } - /* Concrete syntax terms */ function Arr() { this.values = copy_arguments(arguments, 0); } @@ -84,15 +116,23 @@ Linearizer.prototype.rule = function (name, cs) { return this.rules[name](cs); } Linearizer.prototype.addRule = function (name, f) { this.rules[name] = f; }; Linearizer.prototype.linearize = function (tree) { return this.linearizeToTerm(tree).print(); }; Linearizer.prototype.linearizeToTerm = function (tree) { - var cs = new Array(); - for (var i = 0; i < tree.children.length; i++) { - cs[i] = this.linearizeToTerm(tree.children[i]); + if (typeof tree == 'string' && tree == '?') { + return new Meta(); + } else { + var cs = tree.getChildren(); + for (var i = 0; i < cs.length; i++) { + cs[i] = this.linearizeToTerm(cs[i]); + } + return this.rule(tree.name, cs); } - return this.rule(tree.name, cs); }; /* Utilities */ +function isString(a) { return typeof a == 'string'; } +function isArray(a) { return a && typeof a == 'object' && a.constructor == Array; } +function isUndefined(a) { return typeof a == 'undefined'; } + function copy_arguments(args, start) { var arr = new Array(); for (var i = 0; i < args.length - start; i++) { diff --git a/src/GF/Speech/GrammarToVoiceXML.hs b/src/GF/Speech/GrammarToVoiceXML.hs index b2142b50c..2e3ea1096 100644 --- a/src/GF/Speech/GrammarToVoiceXML.hs +++ b/src/GF/Speech/GrammarToVoiceXML.hs @@ -157,7 +157,9 @@ catForms gr qs cat fs = cat2form :: String -> CatQuestions -> VIdent -> [(VIdent, [VIdent])] -> XML cat2form gr qs cat fs = - form cat $ [var "value" (Just "'?'"), formDebug cat, + form cat $ [var "value" (Just "'?'"), + var "update" Nothing, + formDebug cat, blockCond "value != '?'" [assign cat "value"], field cat [] [promptString (getCatQuestion cat qs), grammar (gr++"#"++cat), @@ -167,7 +169,7 @@ cat2form gr qs cat fs = catDebug] ++ concatMap (uncurry (fun2sub gr cat)) fs ++ [block [return_ [cat]]] - where feedback = [] + where feedback = [if_ ("typeof update != 'undefined' && !update("++string cat++","++ cat ++ ")") [return_ []]] catDebug = debugLog [Data (cat ++ " = "), value ("dump("++cat++")")] retDebug = debugLog [Data "return ", value ("dump("++cat++")")] @@ -178,6 +180,7 @@ fun2sub gr cat fun args = comments [fun ++ " : " ++ cat] ++ ss ss = map (uncurry mkSub) argNames mkSub a t = subdialog s [("src","#"++t),("cond",cat++".name == "++string fun)] [param "value" (cat++"."++a), + param "update" "update", filled [] [assign (cat++"."++a) (s++"."++t)]] where s = fun ++ "_" ++ a