D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
curran
Full window
Github gist
Parser
Built with
blockbuilder.org
<!DOCTYPE html> <head> <meta charset="utf-8"> </head> <body> <script> function isLetter(str) { return str.match(/[a-z]/i); } function parse(str) { // Parse the next token. // We assume each token is a single character. var i = 0, sym; function nextSym () { sym = str[i++]; if (sym && isLetter(sym)) { sym += str[i++] } } function symType () { if (sym === "/" || sym === "+") { return "operator"; } if (sym === "(" || sym === ")") { return "paren"; } return "name"; } // Our grammar: // expression = ["+"] term {("+") term} . // term = factor {("/") factor} . // factor = // name // | "(" expression ")" . function factor (){ if (symType() === "name") { var name = sym; nextSym(); return name; } if (sym === "(") { nextSym(); var result = expression(); if (sym === ")") { nextSym(); return result; } console.error("Expected end paren ')'.") } } function operator (symbol, orientation, fn){ return function () { var result = fn(); if (sym !== symbol) { return result; } var children = [result]; while (sym === symbol) { nextSym(); children = children.concat(fn()); } return { orientation: orientation, children: children }; } } var term = operator("/", "vertical", factor); var expression = operator("+", "horizontal", term); nextSym(); return expression(); } function test (str, expected){ if (JSON.stringify(parse(str)) !== JSON.stringify(expected)) { console.error("Test failed for " + str); console.error(JSON.stringify(parse(str))); } } console.log("Running tests..."); test("A", "A"); test("A/B", { "orientation": "vertical", "children": ["A", "B"] }); test("A+B", { "orientation": "horizontal", "children": ["A", "B"] }); test("A/B/C", { "orientation": "vertical", "children": ["A", "B", "C"] }); test("A+B+C", { "orientation": "horizontal", "children": ["A", "B", "C"] }); test("A/B+C", { "orientation": "horizontal", "children": [ { "orientation": "vertical", "children": ["A", "B"] }, "C" ] }); test("A+B/C", { "orientation": "horizontal", "children": [ "A", { "orientation": "vertical", "children": ["B", "C"] } ] }); test("(A)", "A"); test("(A/B)", { "orientation": "vertical", "children": ["A", "B"] }); test("(A+B)", { "orientation": "horizontal", "children": ["A", "B"] }); test("(A)/B", { "orientation": "vertical", "children": ["A", "B"] }); test("A+(B)", { "orientation": "horizontal", "children": ["A", "B"] }); test("(A)/B", { "orientation": "vertical", "children": ["A", "B"] }); test("(A)+(B)", { "orientation": "horizontal", "children": ["A", "B"] }); test("((A))", "A"); test("((A)+(B))", { "orientation": "horizontal", "children": ["A", "B"] }); test("(A)/(B)/(C)", { "orientation": "vertical", "children": ["A", "B", "C"] }); test("A/(B/C)", { "orientation":"vertical", "children":["A",{"orientation":"vertical","children":["B","C"]}] }); test("(A/B)/C", { "orientation":"vertical", "children":[{"orientation":"vertical","children":["A","B"]},"C"] }); test("A+(B+C)", { "orientation": "horizontal", "children":["A",{"orientation":"horizontal","children":["B","C"]}] }); test("A/(B+C)", { "orientation": "vertical", "children":["A",{"orientation":"horizontal","children":["B","C"]}] }); test("A/(B+C/D+E)", { "orientation":"vertical", "children":[ "A", { "orientation":"horizontal", "children":[ "B", {"orientation":"vertical","children":["C","D"]}, "E" ] } ] }); test("Foo", "Foo"); console.log("Ran all tests!"); //var complexCase = "A/(B+C/D+E)"; </script> </body>