Yacc and Lex Playground
Uses
Jison
parser generator.
%lex %% [0-9] return 'DIGIT'; <
> return 'EOF'; . return yytext; /lex %start exp %% exp : e EOF { return process($1); } ; e : e '+' r { $$ = { type: 'e', children: [$1, { type: '+' }, $3] }; } | r { $$ = { type: 'e', children: [$1] }; } ; r : r '*' n { $$ = { type: 'r', children: [$1, { type: '*' }, $3] }; } | n { $$ = { type: 'r', children: [$1] }; } ; n : n d { $$ = { type: 'n', children: [$1, $2] }; } | d { $$ = { type: 'n', children: [$1] }; } ; d : DIGIT { $$ = { type: 'd', value: $1 }; } ; %% function indent(ind) { var res = ""; for (var i = 0; i < ind; i++) { res += " "; } return res; } function drawtree(node, ind) { var ENDL = "\n"; var res = ""; if (node.type == 'd') { res += indent(ind) + node.type + " : " + node.value + ENDL; } else if (node.type == '*' || node.type == '+') { res += indent(ind) + node.type + ENDL; } else { res += indent(ind) + node.type + ENDL; for (var i = 0; i < node.children.length; i++) { res += drawtree(node.children[i], ind + 1); } } return res; } function simplify(node) { if (node.type == 'd') { return Number(node.value); } else if (node.type == 'n') { if (node.children.length == 1) { return simplify(node.children[0]); } var lhs = simplify(node.children[0]); var rhs = simplify(node.children[1]); return lhs * 10 + rhs; } else if (node.type == 'e' || node.type == 'r') { if (node.children.length == 1) { return simplify(node.children[0]); } var lhs = simplify(node.children[0]); var rhs = simplify(node.children[2]); return {op: node.children[1].type, lhs: lhs, rhs: rhs}; } } function simplifiedDrawTree(node, ind) { var ENDL = "\n"; var res = ""; if (typeof node == "number") { res += indent(ind) + node + ENDL; } else { res += indent(ind) + node.op + ENDL; res += simplifiedDrawTree(node.lhs, ind + 1); res += simplifiedDrawTree(node.rhs, ind + 1); } return res; } function calculate(node) { if (typeof node == "number") { return node; } else { var lhs = calculate(node.lhs); var rhs = calculate(node.rhs); if (node.op == '+') { return lhs + rhs; } else if (node.op == '*') { return lhs * rhs; } } } function process(node) { var ENDL = "\n"; var newTree = simplify(node); var res = ""; res += "Grammar Tree:" + ENDL; res += ENDL; res += drawtree(node, 0); res += ENDL; res += "Semantic Tree:" + ENDL; res += simplifiedDrawTree(newTree, 0); res += ENDL; res += "Result:" + ENDL; res += calculate(newTree); return res; }
Generate Parser
5+5*2
Parse