Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

mmmdreg

macrumors 65816
Original poster
Apr 14, 2002
1,393
0
Sydney, Australia
I'm trying to change generate a text-based tree representation of a syntax tree using javascript using recursion. Complications from the condition that a root node is 'undefined' as javascript treats strings as character arrays on some browsers (safari, firefox etc), but not on others (IE).

Given a string "Sue van den Bruck works", the original tree as an array is:
[ "s2", [ "s1", [ "s", ["n3", ["n2", ["pn", ["Sue", "van", "den", "Bruck"]]]], ["v3", ["v2", ["v1", ["iv", ["works"]]]]] ] ] ]..

I want Javascript to turn the array in to a string like:
(s2 (s1 (s (n3 (n2 (pn (Sue van den Bruck) ) ) ) (v3 (v2 (v1 (iv (works ) ) ) ) ) ) ) )

Unfortunately, due to the character problem, it ends up looking like:
(s2 (s1 (s (n3 (n2 (pn (Sue (v (a ) (n ) ) (d (e ) (n ) ) (B (r ) (u ) (c ) (k ) ) ) ) ) ) (v3 (v2 (v1 (iv (works ) ) ) ) ) ) ) )


The recursive function is:
Code:
var treeTxt = ""; //store the syntax tree as it is been constructed
function drawTree(tree)
{
    if(tree[0] != undefined)
	{
		treeTxt +='('+tree[0]+" "; //save the root of the tree
		for(var i=1; i<tree.length; i++) //for each of the branches
		{    
			  drawTree(tree[i]);	//construct the tree for that branch
		}
		treeTxt+=') ';
	}
	else
	{
        treeTxt+=' ' + tree + ' ';	                // store the leaf value (compound words)
	}
}

To give some indication of what is happening, here is a printout of the root node, the first branch and the second branch at every level:
Code:
s2 : s1,s,n3,n2,pn,Sue,van,den,Bruck,v3,v2,v1,iv,works : undefined

s1 : s,n3,n2,pn,Sue,van,den,Bruck,v3,v2,v1,iv,works : undefined

s : n3,n2,pn,Sue,van,den,Bruck : v3,v2,v1,iv,works

n3 : n2,pn,Sue,van,den,Bruck : undefined

n2 : pn,Sue,van,den,Bruck : undefined

pn : Sue,van,den,Bruck : undefined

Sue : van : den

v : a : n

The question is, is there a basic condition or workaround that I can use to avoid this behaviour? The tree originally generated is fine and so this is purely a display problem... which means I don't want to go hacking around and adding special characters to differentiate between tag words and actual words or anything silly like that.

Cheers if you got any advice!

PS, if you want a visualisation of the tree, check out the attachment.

edit: apparently IE8 treats it the same as firefox etc.
 

Attachments

  • syntax_tree.png
    syntax_tree.png
    2.2 KB · Views: 165
My JS is not that strong, but could you use objects instead of an array of strings?

Code:
function Node(name){
    this._name=name
}
Node.prototype._name;
Node.prototype.children;
Node.prototype.getChildren=function() {
    return children;
}
Node.prototype.addChild=function(child){
   if(this.children == undefined)
       this.children = new Array();
   this.children.push(child);
}

I haven't tried the above code so you will likely have to fiddle with it. Also you would have to create the tree from the leaf to the root.
 
Can you post the javascript of how you create the original tree as an array?

The original tree is created externally in Prolog and accessed using Json.

Sorry this is my first time using Javascript (I'm running maintenance on someone else's code).
 
Instead of checking an element of the tree, you should check the type. A simple change of your if statement from
Code:
if(tree[0] != undefined)
to
Code:
if (typeof tree != 'string')
produced the expected output for me on Chrome and Safari.

For reference, here's my isolated test case:
Code:
var gtree = [ "s2", [ "s1", [ "s", ["n3", ["n2", ["pn", ["Sue", "van", "den", "Bruck"]]]], ["v3", ["v2", ["v1", ["iv", ["works"]]]]] ] ] ];

var treeTxt = "";	//store the syntax tree as it is been constructed
function drawTree(tree)
{
	if (typeof tree != 'string') {
		treeTxt +='('+tree[0]+" "; //save the root of the tree
		for (var i = 1; i < tree.length; i++) {	//for each of the branches
			  drawTree(tree[i]);	//construct the tree for that branch
		}
		treeTxt += ') ';
	} else {
		treeTxt += ' ' + tree + ' ';	// store the leaf value (compound words)
	}
}

drawTree(gtree);
document.write(treeTxt);
 
What does Firebug say? That has a debugger.

Though generally you should avoid doing complex stuff in Javascript as its a nasty language you can't easily test.
 
Instead of checking an element of the tree, you should check the type. A simple change of your if statement from
Code:
if(tree[0] != undefined)
to
Code:
if (typeof tree != 'string')
produced the expected output for me on Chrome and Safari.

Cheers Grapist, that worked perfectly =)
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.