bnf-parser
Advanced tools
Comparing version 2.0.1 to 2.2.0
@@ -22,3 +22,5 @@ let Compile = require('./src/compiler.js'); | ||
} catch(e) { | ||
throw new Error(`An internal error occured when attempting to parse the data;\n ${e}`) | ||
let forward = new Error(`An internal error occured when attempting to parse the data;\n ${e.message}`); | ||
forward.stack = e.stack; | ||
throw forward; | ||
} | ||
@@ -25,0 +27,0 @@ |
{ | ||
"name": "bnf-parser", | ||
"version": "2.0.1", | ||
"version": "2.2.0", | ||
"description": "Deterministic BNF compiler/parser", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -30,3 +30,3 @@ const {BNF_SyntaxNode, BNF_SyntaxError, BNF_Reference, BNF_Tree, BNF_Parse} = require('./types.js'); | ||
return new BNF_SyntaxNode(branch.term, [res], res.consumed, ref, res.ref.end); | ||
} if (best === null || best.ref.index < res.ref.index) { | ||
} if (best === null || res.getReach().isGreater( best.getReach() )) { | ||
best = res; | ||
@@ -40,3 +40,3 @@ } | ||
if (best) { | ||
return new BNF_SyntaxError(best.ref, best.remaining, branch, "PSL_1_Best"); | ||
return new BNF_SyntaxError(ref, best.remaining, branch, "PSL_1_Best").setCause(best); | ||
} | ||
@@ -60,3 +60,6 @@ | ||
} else { | ||
return new BNF_SyntaxError(localRef, string, branch, "PSQ_O_1"); | ||
return new BNF_SyntaxError(localRef, string, { | ||
term: `"${target.val}"`, | ||
type: target.type | ||
}, "PSQ_O_1"); | ||
} | ||
@@ -90,3 +93,7 @@ } else if (target.type == "ref") { | ||
return {data: sub, reached: res.ref}; | ||
return { | ||
data: sub, | ||
reached: new BNF_SyntaxError(localRef, string, branch, "SEQ_ZME") | ||
.setCause(res) | ||
}; | ||
} | ||
@@ -106,14 +113,12 @@ | ||
sub = [res]; | ||
} else if (res instanceof BNF_SyntaxError && target.count == 1) { | ||
if (prevErr && prevErr.isGreater(res.ref)) { | ||
res.ref = prevErr; | ||
} else if (res instanceof BNF_SyntaxError) { | ||
if (prevErr === null || res.getReach().isGreater(prevErr.getReach())) { | ||
prevErr = res; | ||
} | ||
return res; | ||
} else { | ||
sub = []; | ||
} | ||
} else if (target.count == "*" || target.count == "+") { | ||
let res = MatchZeroToMany(target, input, localRef.duplicate()); | ||
prevErr = res.reached; | ||
if (prevErr === null || res.reached.getReach().isGreater(prevErr.getReach())) { | ||
prevErr = res.reached; | ||
} | ||
sub = res.data; | ||
@@ -137,2 +142,15 @@ } | ||
// Get reach | ||
let last = sub[sub.length-1]; | ||
if (last instanceof BNF_SyntaxNode) { | ||
if (last.reached && | ||
( | ||
prevErr === null || | ||
last.reached.getReach().isGreater(prevErr.getReach()) | ||
) | ||
) { | ||
prevErr = last.reached; | ||
} | ||
} | ||
// Check number of tokens | ||
@@ -143,7 +161,4 @@ if ( | ||
) { | ||
if (prevErr.isGreater(localRef)){ | ||
localRef = prevErr; | ||
} | ||
return new BNF_SyntaxError(localRef, input, {...branch, stage: target}, "PSQ_1"); | ||
return new BNF_SyntaxError(startRef, input, {...branch, stage: target}, "PSQ_1") | ||
.setCause(prevErr); | ||
} | ||
@@ -196,3 +211,4 @@ | ||
} else { | ||
return new BNF_SyntaxError(localRef, input, {...branch, stage: branch.term}, "PN_1"); | ||
return new BNF_SyntaxError(startRef, input, branch, "PN_1") | ||
.setCause(new BNF_SyntaxError(localRef, input, branch.term, "PN_I")); | ||
} | ||
@@ -232,8 +248,9 @@ } | ||
let out = null; | ||
if (branch.type == "select") { | ||
return Process_Select(input, tree, branch, stack, forwardRef); | ||
out = Process_Select(input, tree, branch, stack, forwardRef); | ||
} else if (branch.type == "sequence") { | ||
return Process_Sequence(input, tree, branch, stack, forwardRef); | ||
out = Process_Sequence(input, tree, branch, stack, forwardRef); | ||
} else if (branch.type == "not") { | ||
return Process_Not(input, tree, branch, stack, forwardRef); | ||
out = Process_Not(input, tree, branch, stack, forwardRef); | ||
} else { | ||
@@ -243,3 +260,7 @@ throw new ReferenceError(`Malformed tree: Invalid term type ${branch.type}`); | ||
throw new Error("Unknown run time error"); | ||
if (out instanceof BNF_SyntaxError || out instanceof BNF_SyntaxNode) { | ||
return out; | ||
} | ||
throw new TypeError(`Invalid return type of internal component from ${branch.term}:${branch.type}`); | ||
} | ||
@@ -246,0 +267,0 @@ |
@@ -92,6 +92,51 @@ | ||
this.ref = ref; | ||
this.remaining = remaining; | ||
// this.remaining = remaining; | ||
this.branch = branch; | ||
this.code = code; | ||
this.cause = null; | ||
} | ||
/** | ||
* Change the cause of the error | ||
* @param {BNF_SyntaxError} other | ||
* @returns {BNF_SyntaxError} | ||
*/ | ||
setCause(other) { | ||
if (other === null) { // Remove the cause | ||
this.cause = null; | ||
} else if (!(other instanceof BNF_SyntaxError)) { // Invalid cause | ||
console.error(other); | ||
throw new TypeError(`Invalid type "${typeof(other)}" parsed as BNF_SyntaxError cause`); | ||
} else { // Update cause | ||
this.cause = other; | ||
} | ||
return this; | ||
} | ||
getCausation(){ | ||
// Ignore temporary types if possible | ||
if (this.branch.term.slice(0,2) == "#t"){ | ||
if (this.cause) { | ||
return this.cause.getCausation(); | ||
} else { | ||
return `${this.branch.term}:${this.branch.type.slice(0,3)} ${this.ref.toString()}`; | ||
} | ||
} | ||
let out = `${this.branch.term}:${this.branch.type.slice(0,3)} ${this.ref.toString()}` | ||
if (this.cause) { | ||
out += " -> " + this.cause.getCausation(); | ||
} | ||
return out; | ||
} | ||
getReach() { | ||
if (this.cause) { | ||
return this.cause.getReach(); | ||
} else { | ||
return this.ref; | ||
} | ||
} | ||
} | ||
@@ -125,2 +170,3 @@ | ||
}; | ||
this.reached = reached; | ||
} | ||
@@ -127,0 +173,0 @@ |
Sorry, the diff of this file is not supported yet
31500
804