summaryrefslogtreecommitdiff
path: root/src/www/syntax-editor
diff options
context:
space:
mode:
authorjohn.j.camilleri <john.j.camilleri@chalmers.se>2012-11-16 14:35:37 +0000
committerjohn.j.camilleri <john.j.camilleri@chalmers.se>2012-11-16 14:35:37 +0000
commit3e5dac8ed4c4e3d081b815c4ac3c3047c8ca926d (patch)
treeae660c93f5ca1e12fcd33e7fb9446e83c7fce492 /src/www/syntax-editor
parent954d7a7ff52f623fa8aa4b3734e6b8413d24c287 (diff)
Syntax editor: work on importing AST as string (eg for generate random)
But it's still not complete. Need an efficient way of getting the cat info to accompany funs.
Diffstat (limited to 'src/www/syntax-editor')
-rw-r--r--src/www/syntax-editor/README.md2
-rw-r--r--src/www/syntax-editor/js/ast.js130
-rw-r--r--src/www/syntax-editor/js/editor.js55
-rw-r--r--src/www/syntax-editor/js/editor_menu.js15
4 files changed, 159 insertions, 43 deletions
diff --git a/src/www/syntax-editor/README.md b/src/www/syntax-editor/README.md
index e47d67518..647792d48 100644
--- a/src/www/syntax-editor/README.md
+++ b/src/www/syntax-editor/README.md
@@ -13,6 +13,8 @@ Tested with latest Chrome and Firefox.
## TODO
+- Clicking on tokens to select tree node
+- Use local caching
- Enter string/float/int literals
- UI issue with DisambPhrasebookEng
- more prominence to Disamb-linearizations
diff --git a/src/www/syntax-editor/js/ast.js b/src/www/syntax-editor/js/ast.js
index 0bcb75a16..651f949cd 100644
--- a/src/www/syntax-editor/js/ast.js
+++ b/src/www/syntax-editor/js/ast.js
@@ -1,25 +1,40 @@
/* --- Tree representation -------------------------------------------------- */
-function Tree(value) {
+function Node(value, children) {
+ this.value = value;
+ this.children = [];
+ if (children != undefined)
+ for (c in children)
+ this.children.push( new Node(children[c],[]) );
+ this.hasChildren = function(){
+ return this.children.length > 0;
+ }
- // Create node as JS object
- var createNode = function(value, children) {
- var node = {
- value: value,
- children: [],
- hasChildren: function(){ return this.children.length > 0; }
- };
- if (children != undefined)
- for (c in children)
- node.children.push( createNode(children[c],[]) );
- return node;
+ // generic HOF for traversing tree
+ this.traverse = function(f) {
+ function visit(node) {
+ f(node);
+ for (i in node.children) {
+ visit(node.children[i]);
+ }
+ }
+ visit(this);
}
+}
- this.root = createNode(value, []);
+function Tree(value) {
+ this.root = new Node(value, []);
// add value as child of id
this.add = function(id, value, children) {
var x = this.find(id);
- x.children.push( createNode(value, children) );
+ x.children.push( new Node(value, children) );
+ }
+
+ // set tree at given id to
+ this.setSubtree = function(id, node) {
+ var x = this.find(id);
+ x.value = node.value;
+ x.children = node.children;
}
// id should be a list of child indices [0,1,0]
@@ -40,6 +55,20 @@ function Tree(value) {
return undefined;
return node;
}
+
+ // generic HOF for traversing tree
+ this.traverse = function(f) {
+ function visit(id, node) {
+ f(node);
+ for (i in node.children) {
+ var newid = new NodeID(id);
+ newid.add(parseInt(i));
+ visit(newid, node.children[i]);
+ }
+ }
+ visit(new NodeID(), this.root);
+ }
+
}
/* --- ID for a node in a tree ---------------------------------------------- */
@@ -77,12 +106,12 @@ function NodeID(x) {
/* --- Abstract Syntax Tree (with state)------------------------------------- */
function AST(fun, cat) {
- function Node(fun, cat) {
+ function ASTNode(fun, cat) {
this.fun = fun;
this.cat = cat;
}
- this.tree = new Tree(new Node(fun, cat));
+ this.tree = new Tree(new ASTNode(fun, cat));
this.current = new NodeID(); // current id in tree
this.getFun = function() {
@@ -98,8 +127,14 @@ function AST(fun, cat) {
this.tree.find(this.current).value.cat = c;
}
+ // Add a single fun at current node
this.add = function(fun, cat) {
- this.tree.add(this.current, new Node(fun,cat));
+ this.tree.add(this.current, new ASTNode(fun,cat));
+ }
+
+ // Set entire subtree at current node
+ this.setSubtree = function(node) {
+ this.tree.setSubtree(this.current, node);
}
// Clear children of current node
@@ -107,19 +142,6 @@ function AST(fun, cat) {
this.tree.find(this.current).children = [];
}
- // generic HOF for traversing tree
- this.traverse = function(f) {
- function visit(id, node) {
- f(node);
- for (i in node.children) {
- var newid = new NodeID(id);
- newid.add(parseInt(i));
- visit(newid, node.children[i]);
- }
- }
- visit(new NodeID(), this.tree.root);
- }
-
// Move current ID to next hole
this.toNextHole = function() {
var id = new NodeID(this.current);
@@ -149,6 +171,11 @@ function AST(fun, cat) {
this.current.add(i);
}
+ //
+ this.traverse = function(f) {
+ this.tree.traverse(f);
+ }
+
// Return tree as string
this.toString = function() {
var s = "";
@@ -157,13 +184,52 @@ function AST(fun, cat) {
if (node.children.length == 0)
return;
for (i in node.children) {
- s += "(";
+ s += " (";
visit(node.children[i]);
- s += ")";
+ s += ")";
}
}
visit(this.tree.root);
return s;
}
+
+ // Parse AST string into node tree
+ this.parseTree = function(str) {
+
+ function trim(str) {
+ return str.trim().replace(/^\(\s*(.*)\s*\)$/, "$1");
+ }
+
+ function visit(node, str) {
+ var parts = [];
+ var ix_last = 0;
+ var par_cnt = 0;
+ for (i in str) {
+ if (str[i] == " ") {
+ if (par_cnt == 0) {
+ parts.push(trim(str.substring(ix_last, i)));
+ ix_last = i;
+ }
+ }
+ else if (str[i] == "(")
+ par_cnt++;
+ else if (str[i] == ")")
+ par_cnt--;
+ }
+ parts.push(trim(str.substring(ix_last)));
+
+ var fun = parts.shift();
+ var cat = null; // will be filled later
+
+ node.value = new ASTNode(fun, cat);
+ for (i in parts) {
+ node.children.push(new Node());
+ visit(node.children[i], parts[i]);
+ }
+ }
+ var tree = new Node();
+ visit(tree, str);
+ return tree;
+ }
}
diff --git a/src/www/syntax-editor/js/editor.js b/src/www/syntax-editor/js/editor.js
index 608770edb..b0663b816 100644
--- a/src/www/syntax-editor/js/editor.js
+++ b/src/www/syntax-editor/js/editor.js
@@ -101,24 +101,22 @@ Editor.prototype.get_refinements=function(cat) {
};
var err = function(data){
clear(t.ui.refinements);
- alert("No refinements");
+ alert("Error");
};
t.server.browse(args, cont, err);
}
Editor.prototype.select_refinement=function(fun) {
with (this) {
- clear(ui.refinements);
+ ui.refinements.innerHTML = "...";
ast.removeChildren();
ast.setFun(fun);
-// redraw_tree();
-
var args = {
id: fun,
format: "json"
};
var err = function(data){
- alert("no refinements");
+ alert("Error");
};
server.browse(args, bind(complete_refinement,this), err);
}
@@ -148,7 +146,6 @@ Editor.prototype.complete_refinement=function(data) {
// Select next hole & get its refinements
ast.toNextHole();
update_current_node();
- get_refinements();
}
}
@@ -166,7 +163,9 @@ Editor.prototype.redraw_tree=function() {
var elem = node; // function from support.js
function visit(container, id, node) {
var container2 = empty_class("div", "node");
- var label = ((node.value.fun) ? node.value.fun : "?") + " : " + node.value.cat;
+ var label =
+ ((node.value.fun) ? node.value.fun : "?") + " : " +
+ ((node.value.cat) ? node.value.cat : "?");
var current = id.equals(t.ast.current);
var element = elem("a", {class:(current?"current":"")}, [text(label)]);
element.onclick = function() {
@@ -217,3 +216,45 @@ Editor.prototype.update_linearisation=function(){
}
}
+//
+Editor.prototype.delete_refinement = function() {
+ var t = this;
+ t.ast.removeChildren();
+ t.ast.setFun(null);
+ t.redraw_tree();
+// t.get_refinements();
+}
+
+// Generate random subtree from current node
+Editor.prototype.generate_random = function() {
+ var t = this;
+ t.ui.refinements.innerHTML = "...";
+ t.ast.removeChildren();
+ var args = {
+ cat: t.ast.getCat(),
+ limit: 1
+ };
+ var cont = function(data){
+ // Build tree of just fun, then populate with cats
+ var tree = t.ast.parseTree(data[0].tree);
+ tree.traverse(function(node){
+ var info = t.lookup_fun(node.value.fun);
+ node.value.cat = info.cat;
+ });
+ t.ast.setSubtree(tree);
+ t.redraw_tree();
+ };
+ var err = function(data){
+ alert("Error");
+ };
+ server.get_random(args, cont, err);
+}
+
+// Look up information for a function, hopefully from cache
+Editor.prototype.lookup_fun = function(fun) {
+ // TODO
+ return {
+ cat: null
+ }
+}
+
diff --git a/src/www/syntax-editor/js/editor_menu.js b/src/www/syntax-editor/js/editor_menu.js
index ce0894ee0..c5e2e9912 100644
--- a/src/www/syntax-editor/js/editor_menu.js
+++ b/src/www/syntax-editor/js/editor_menu.js
@@ -26,11 +26,19 @@ function EditorMenu(editor,opts) {
id: "to_menu",
multiple: "multiple",
class: "hidden"
- } )
+ }),
+ clear_button: button("Clear", function(){
+ t.editor.delete_refinement();
+ }),
+ random_button: button("Random", function(){
+ t.editor.generate_random();
+ }),
};
with(this.ui) {
appendChildren(this.container, [text(" Startcat: "),startcat_menu]);
appendChildren(this.container, [text(" To: "), to_toggle, to_menu]);
+// appendChildren(this.container, [clear_button, random_button]);
+ appendChildren(this.container, [clear_button]);
startcat_menu.onchange=bind(this.change_startcat,this);
to_menu.onchange=bind(this.change_language,this);
}
@@ -157,9 +165,8 @@ EditorMenu.prototype.update_language_menu=function(menu,grammar) {
menu.appendChild(option(lp,ln));
}
}
-
- insertFirst(menu,option("All","All"));
- menu.value="All";
+ // insertFirst(menu,option("All","All"));
+ // menu.value="All";
}