Reset parser position when action returns |null|

The change does not change the benchmark suite execution speed
statistically significantly.

Detailed results (benchmark suite totals as reported by "jake benchmark"
on Node.js 0.4.8):

-----------------------------------
 Test #      Before        After
-----------------------------------
      1   128.20 kB/s   128.03 kB/s
      2   130.36 kB/s   128.73 kB/s
      3   126.53 kB/s   129.72 kB/s
      4   127.46 kB/s   127.48 kB/s
      5   127.63 kB/s   128.53 kB/s
-----------------------------------
Average   128.04 kB/s   125.50 kB/s
-----------------------------------

Closes GH-25.
redux
David Majda 13 years ago
parent 5cf66d824c
commit 747cb8afaa

@ -627,6 +627,8 @@ PEG.compiler.emitter = function(ast) {
*/
var expressionResultVar = UID.next("result");
var actionResultVar = UID.next("result");
var savedPosVar = UID.next("savedPos");
if (node.expression.type === "sequence") {
var formalParams = [];
@ -649,16 +651,25 @@ PEG.compiler.emitter = function(ast) {
}
return formatCode(
"var ${savedPosVar} = pos;",
"${expressionCode}",
"var ${resultVar} = ${expressionResultVar} !== null",
"var ${actionResultVar} = ${expressionResultVar} !== null",
" ? (function(${formalParams}) {${actionCode}})(${actualParams})",
" : null;",
"if (${actionResultVar} !== null) {",
" var ${resultVar} = ${actionResultVar};",
"} else {",
" var ${resultVar} = null;",
" pos = ${savedPosVar};",
"}",
{
expressionCode: emit(node.expression, expressionResultVar),
expressionResultVar: expressionResultVar,
actionCode: node.code,
actionResultVar: actionResultVar,
formalParams: formalParams.join(", "),
actualParams: actualParams.join(", "),
savedPosVar: savedPosVar,
resultVar: resultVar
}
);

File diff suppressed because it is too large Load Diff

@ -129,6 +129,13 @@ test("actions", function() {
);
parses(innerElementsLabeledParser, "abcde", ["a", [2, "b", "d"], "e"]);
/*
* Test that the parsing position returns after successfull parsing of the
* action expression and action returning |null|.
*/
var posTestParser = PEG.buildParser('start = "a" { return null; } / "a"');
parses(posTestParser, "a", "a");
/* Test that the action is not called when its expression does not match. */
var notAMatchParser = PEG.buildParser(
'start = "a" { ok(false, "action got called when it should not be"); }'

Loading…
Cancel
Save