Adv item search: organize productions more sensibly in expr parser

This commit is contained in:
phantamanta44 2021-03-13 16:44:35 -06:00
parent 160a319919
commit 1ed397dd70

View file

@ -147,17 +147,16 @@ const ExprParser = (function() {
function takeExprList0(tokens) { function takeExprList0(tokens) {
const children = []; const children = [];
switch (tokens.peek.type) { switch (tokens.peek.type) {
case ')':
return { type: 'nonterm', name: 'exprList\'', prod: 1, children };
case ',': case ',':
children.push(tokens.consume(',')); children.push(tokens.consume(','));
children.push(takeExpr(tokens)); children.push(takeExpr(tokens));
children.push(takeExprList0(tokens)); children.push(takeExprList0(tokens));
return { type: 'nonterm', name: 'exprList\'', prod: 0, children }; return { type: 'nonterm', name: 'exprList\'', prod: 0, children };
case ')':
case 'eof': case 'eof':
return { type: 'nonterm', name: 'exprList\'', prod: 1, children }; return { type: 'nonterm', name: 'exprList\'', prod: 1, children };
default: default:
throw new Error('Could not parse an expression list!'); throw new Error('Could not parse a expression list!');
} }
} }
@ -217,15 +216,14 @@ const ExprParser = (function() {
function takeDisj0(tokens) { function takeDisj0(tokens) {
const children = []; const children = [];
switch (tokens.peek.type) { switch (tokens.peek.type) {
case '&':
case ')':
case ',':
return { type: 'nonterm', name: 'disj\'', prod: 1, children };
case '|': case '|':
children.push(tokens.consume('|')); children.push(tokens.consume('|'));
children.push(takeCmpEq(tokens)); children.push(takeCmpEq(tokens));
children.push(takeDisj0(tokens)); children.push(takeDisj0(tokens));
return { type: 'nonterm', name: 'disj\'', prod: 0, children }; return { type: 'nonterm', name: 'disj\'', prod: 0, children };
case '&':
case ')':
case ',':
case 'eof': case 'eof':
return { type: 'nonterm', name: 'disj\'', prod: 1, children }; return { type: 'nonterm', name: 'disj\'', prod: 1, children };
default: default:
@ -254,25 +252,24 @@ const ExprParser = (function() {
function takeCmpEq0(tokens) { function takeCmpEq0(tokens) {
const children = []; const children = [];
switch (tokens.peek.type) { switch (tokens.peek.type) {
case '!=':
children.push(tokens.consume('!='));
children.push(takeCmpRel(tokens));
children.push(takeCmpEq0(tokens));
return { type: 'nonterm', name: 'cmpEq\'', prod: 1, children };
case '&':
case ')':
case ',':
return { type: 'nonterm', name: 'cmpEq\'', prod: 3, children };
case '=': case '=':
children.push(tokens.consume('=')); children.push(tokens.consume('='));
children.push(takeCmpRel(tokens)); children.push(takeCmpRel(tokens));
children.push(takeCmpEq0(tokens)); children.push(takeCmpEq0(tokens));
return { type: 'nonterm', name: 'cmpEq\'', prod: 0, children }; return { type: 'nonterm', name: 'cmpEq\'', prod: 0, children };
case '!=':
children.push(tokens.consume('!='));
children.push(takeCmpRel(tokens));
children.push(takeCmpEq0(tokens));
return { type: 'nonterm', name: 'cmpEq\'', prod: 1, children };
case '?=': case '?=':
children.push(tokens.consume('?=')); children.push(tokens.consume('?='));
children.push(takeCmpRel(tokens)); children.push(takeCmpRel(tokens));
children.push(takeCmpEq0(tokens)); children.push(takeCmpEq0(tokens));
return { type: 'nonterm', name: 'cmpEq\'', prod: 2, children }; return { type: 'nonterm', name: 'cmpEq\'', prod: 2, children };
case '&':
case ')':
case ',':
case '|': case '|':
case 'eof': case 'eof':
return { type: 'nonterm', name: 'cmpEq\'', prod: 3, children }; return { type: 'nonterm', name: 'cmpEq\'', prod: 3, children };
@ -302,23 +299,16 @@ const ExprParser = (function() {
function takeCmpRel0(tokens) { function takeCmpRel0(tokens) {
const children = []; const children = [];
switch (tokens.peek.type) { switch (tokens.peek.type) {
case '!=':
case '&':
case ')':
case ',':
return { type: 'nonterm', name: 'cmpRel\'', prod: 4, children };
case '<':
children.push(tokens.consume('<'));
children.push(takeSum(tokens));
children.push(takeCmpRel0(tokens));
return { type: 'nonterm', name: 'cmpRel\'', prod: 1, children };
case '<=': case '<=':
children.push(tokens.consume('<=')); children.push(tokens.consume('<='));
children.push(takeSum(tokens)); children.push(takeSum(tokens));
children.push(takeCmpRel0(tokens)); children.push(takeCmpRel0(tokens));
return { type: 'nonterm', name: 'cmpRel\'', prod: 0, children }; return { type: 'nonterm', name: 'cmpRel\'', prod: 0, children };
case '=': case '<':
return { type: 'nonterm', name: 'cmpRel\'', prod: 4, children }; children.push(tokens.consume('<'));
children.push(takeSum(tokens));
children.push(takeCmpRel0(tokens));
return { type: 'nonterm', name: 'cmpRel\'', prod: 1, children };
case '>': case '>':
children.push(tokens.consume('>')); children.push(tokens.consume('>'));
children.push(takeSum(tokens)); children.push(takeSum(tokens));
@ -329,6 +319,11 @@ const ExprParser = (function() {
children.push(takeSum(tokens)); children.push(takeSum(tokens));
children.push(takeCmpRel0(tokens)); children.push(takeCmpRel0(tokens));
return { type: 'nonterm', name: 'cmpRel\'', prod: 3, children }; return { type: 'nonterm', name: 'cmpRel\'', prod: 3, children };
case '!=':
case '&':
case ')':
case ',':
case '=':
case '?=': case '?=':
case '|': case '|':
case 'eof': case 'eof':
@ -359,22 +354,20 @@ const ExprParser = (function() {
function takeSum0(tokens) { function takeSum0(tokens) {
const children = []; const children = [];
switch (tokens.peek.type) { switch (tokens.peek.type) {
case '!=':
case '&':
case ')':
return { type: 'nonterm', name: 'sum\'', prod: 2, children };
case '+': case '+':
children.push(tokens.consume('+')); children.push(tokens.consume('+'));
children.push(takeProd(tokens)); children.push(takeProd(tokens));
children.push(takeSum0(tokens)); children.push(takeSum0(tokens));
return { type: 'nonterm', name: 'sum\'', prod: 0, children }; return { type: 'nonterm', name: 'sum\'', prod: 0, children };
case ',':
return { type: 'nonterm', name: 'sum\'', prod: 2, children };
case '-': case '-':
children.push(tokens.consume('-')); children.push(tokens.consume('-'));
children.push(takeProd(tokens)); children.push(takeProd(tokens));
children.push(takeSum0(tokens)); children.push(takeSum0(tokens));
return { type: 'nonterm', name: 'sum\'', prod: 1, children }; return { type: 'nonterm', name: 'sum\'', prod: 1, children };
case '!=':
case '&':
case ')':
case ',':
case '<': case '<':
case '<=': case '<=':
case '=': case '=':
@ -410,24 +403,22 @@ const ExprParser = (function() {
function takeProd0(tokens) { function takeProd0(tokens) {
const children = []; const children = [];
switch (tokens.peek.type) { switch (tokens.peek.type) {
case '!=':
case '&':
case ')':
return { type: 'nonterm', name: 'prod\'', prod: 2, children };
case '*': case '*':
children.push(tokens.consume('*')); children.push(tokens.consume('*'));
children.push(takeExp(tokens)); children.push(takeExp(tokens));
children.push(takeProd0(tokens)); children.push(takeProd0(tokens));
return { type: 'nonterm', name: 'prod\'', prod: 0, children }; return { type: 'nonterm', name: 'prod\'', prod: 0, children };
case '+':
case ',':
case '-':
return { type: 'nonterm', name: 'prod\'', prod: 2, children };
case '/': case '/':
children.push(tokens.consume('/')); children.push(tokens.consume('/'));
children.push(takeExp(tokens)); children.push(takeExp(tokens));
children.push(takeProd0(tokens)); children.push(takeProd0(tokens));
return { type: 'nonterm', name: 'prod\'', prod: 1, children }; return { type: 'nonterm', name: 'prod\'', prod: 1, children };
case '!=':
case '&':
case ')':
case '+':
case ',':
case '-':
case '<': case '<':
case '<=': case '<=':
case '=': case '=':
@ -463,6 +454,11 @@ const ExprParser = (function() {
function takeExp0(tokens) { function takeExp0(tokens) {
const children = []; const children = [];
switch (tokens.peek.type) { switch (tokens.peek.type) {
case '^':
children.push(tokens.consume('^'));
children.push(takeUnary(tokens));
children.push(takeExp0(tokens));
return { type: 'nonterm', name: 'exp\'', prod: 0, children };
case '!=': case '!=':
case '&': case '&':
case ')': case ')':
@ -477,12 +473,6 @@ const ExprParser = (function() {
case '>': case '>':
case '>=': case '>=':
case '?=': case '?=':
return { type: 'nonterm', name: 'exp\'', prod: 1, children };
case '^':
children.push(tokens.consume('^'));
children.push(takeUnary(tokens));
children.push(takeExp0(tokens));
return { type: 'nonterm', name: 'exp\'', prod: 0, children };
case '|': case '|':
case 'eof': case 'eof':
return { type: 'nonterm', name: 'exp\'', prod: 1, children }; return { type: 'nonterm', name: 'exp\'', prod: 1, children };
@ -494,17 +484,15 @@ const ExprParser = (function() {
function takeUnary(tokens) { function takeUnary(tokens) {
const children = []; const children = [];
switch (tokens.peek.type) { switch (tokens.peek.type) {
case '-':
children.push(tokens.consume('-'));
children.push(takeUnary(tokens));
return { type: 'nonterm', name: 'unary', prod: 0, children };
case '!': case '!':
children.push(tokens.consume('!')); children.push(tokens.consume('!'));
children.push(takeUnary(tokens)); children.push(takeUnary(tokens));
return { type: 'nonterm', name: 'unary', prod: 1, children }; return { type: 'nonterm', name: 'unary', prod: 1, children };
case '(': case '(':
children.push(takePrim(tokens));
return { type: 'nonterm', name: 'unary', prod: 2, children };
case '-':
children.push(tokens.consume('-'));
children.push(takeUnary(tokens));
return { type: 'nonterm', name: 'unary', prod: 0, children };
case 'bLit': case 'bLit':
case 'ident': case 'ident':
case 'nLit': case 'nLit':
@ -519,24 +507,24 @@ const ExprParser = (function() {
function takePrim(tokens) { function takePrim(tokens) {
const children = []; const children = [];
switch (tokens.peek.type) { switch (tokens.peek.type) {
case 'nLit':
children.push(tokens.consume('nLit'));
return { type: 'nonterm', name: 'prim', prod: 0, children };
case 'bLit':
children.push(tokens.consume('bLit'));
return { type: 'nonterm', name: 'prim', prod: 1, children };
case 'sLit':
children.push(tokens.consume('sLit'));
return { type: 'nonterm', name: 'prim', prod: 2, children };
case 'ident':
children.push(tokens.consume('ident'));
children.push(takeIdentTail(tokens));
return { type: 'nonterm', name: 'prim', prod: 3, children };
case '(': case '(':
children.push(tokens.consume('(')); children.push(tokens.consume('('));
children.push(takeExpr(tokens)); children.push(takeExpr(tokens));
children.push(tokens.consume(')')); children.push(tokens.consume(')'));
return { type: 'nonterm', name: 'prim', prod: 4, children }; return { type: 'nonterm', name: 'prim', prod: 4, children };
case 'bLit':
children.push(tokens.consume('bLit'));
return { type: 'nonterm', name: 'prim', prod: 1, children };
case 'ident':
children.push(tokens.consume('ident'));
children.push(takeIdentTail(tokens));
return { type: 'nonterm', name: 'prim', prod: 3, children };
case 'nLit':
children.push(tokens.consume('nLit'));
return { type: 'nonterm', name: 'prim', prod: 0, children };
case 'sLit':
children.push(tokens.consume('sLit'));
return { type: 'nonterm', name: 'prim', prod: 2, children };
default: default:
throw new Error('Could not parse a primitive value!'); throw new Error('Could not parse a primitive value!');
} }
@ -545,14 +533,13 @@ const ExprParser = (function() {
function takeIdentTail(tokens) { function takeIdentTail(tokens) {
const children = []; const children = [];
switch (tokens.peek.type) { switch (tokens.peek.type) {
case '!=':
case '&':
return { type: 'nonterm', name: 'identTail', prod: 1, children };
case '(': case '(':
children.push(tokens.consume('(')); children.push(tokens.consume('('));
children.push(takeArgs(tokens)); children.push(takeArgs(tokens));
children.push(tokens.consume(')')); children.push(tokens.consume(')'));
return { type: 'nonterm', name: 'identTail', prod: 0, children }; return { type: 'nonterm', name: 'identTail', prod: 0, children };
case '!=':
case '&':
case ')': case ')':
case '*': case '*':
case '+': case '+':
@ -570,7 +557,7 @@ const ExprParser = (function() {
case 'eof': case 'eof':
return { type: 'nonterm', name: 'identTail', prod: 1, children }; return { type: 'nonterm', name: 'identTail', prod: 1, children };
default: default:
throw new Error('Could not parse an identifier or function call!'); throw new Error('Could not parse an identifier expression!');
} }
} }
@ -579,10 +566,6 @@ const ExprParser = (function() {
switch (tokens.peek.type) { switch (tokens.peek.type) {
case '!': case '!':
case '(': case '(':
children.push(takeExprList(tokens));
return { type: 'nonterm', name: 'args', prod: 0, children };
case ')':
return { type: 'nonterm', name: 'args', prod: 1, children };
case '-': case '-':
case 'bLit': case 'bLit':
case 'ident': case 'ident':
@ -590,6 +573,7 @@ const ExprParser = (function() {
case 'sLit': case 'sLit':
children.push(takeExprList(tokens)); children.push(takeExprList(tokens));
return { type: 'nonterm', name: 'args', prod: 0, children }; return { type: 'nonterm', name: 'args', prod: 0, children };
case ')':
case 'eof': case 'eof':
return { type: 'nonterm', name: 'args', prod: 1, children }; return { type: 'nonterm', name: 'args', prod: 1, children };
default: default:
@ -635,9 +619,11 @@ const ExprParser = (function() {
} }
return { ...ast, children: mapFixUp(ast.children) }; return { ...ast, children: mapFixUp(ast.children) };
} }
function mapFixUp(nodes) { function mapFixUp(nodes) {
return nodes.map(chAst => fixUp(chAst)); return nodes.map(chAst => fixUp(chAst));
} }
function fixUpRightRecurse(ast, maxProd) { function fixUpRightRecurse(ast, maxProd) {
let nomAst = { type: 'nonterm', name: ast.name, prod: maxProd, children: [fixUp(ast.children[0])] }; let nomAst = { type: 'nonterm', name: ast.name, prod: maxProd, children: [fixUp(ast.children[0])] };
let tree = ast.children[1]; let tree = ast.children[1];
@ -656,6 +642,7 @@ const ExprParser = (function() {
function trans(ast) { function trans(ast) {
return translate(ast, builtInProps, builtInFuncs); return translate(ast, builtInProps, builtInFuncs);
} }
if (ast.type === 'term') { if (ast.type === 'term') {
switch (ast.token.type) { switch (ast.token.type) {
case 'nLit': case 'nLit':