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