From cdf23e0a49ce4b2b230fce752a36e1578b44f3ce Mon Sep 17 00:00:00 2001 From: David Majda Date: Mon, 25 Jun 2012 21:46:47 +0200 Subject: [PATCH] Change ordering of "literal", "class" and "any" code Changes all code that does something with "literal", "class" or "any" AST nodes so that the code deals with these in the follwing order: 1. literal 2. class 3. any Previously the code used this ordering: 1. literal 2. any 3. class The new ordering is more logical because the nodes are handled from the most specific to the most generic. --- .../compiler/passes/compute-var-names.spec.js | 8 ++-- spec/generated-parser.spec.js | 40 +++++++++---------- spec/parser.spec.js | 2 +- src/compiler/passes/compute-params.js | 4 +- src/compiler/passes/compute-var-names.js | 4 +- src/compiler/passes/generate-code.js | 17 ++++---- src/compiler/passes/remove-proxy-rules.js | 4 +- src/compiler/passes/report-left-recursion.js | 4 +- src/compiler/passes/report-missing-rules.js | 4 +- src/parser.js | 18 ++++----- src/parser.pegjs | 2 +- 11 files changed, 54 insertions(+), 53 deletions(-) diff --git a/spec/compiler/passes/compute-var-names.spec.js b/spec/compiler/passes/compute-var-names.spec.js index 036d5b6..bbaf3b7 100644 --- a/spec/compiler/passes/compute-var-names.spec.js +++ b/spec/compiler/passes/compute-var-names.spec.js @@ -211,16 +211,16 @@ describe("compiler pass |computeVarNames|", function() { })); }); - it("computes variable names for an any", function() { - expect(pass).toChangeAST('start = .', ruleDetails({ + it("computes variable names for a class", function() { + expect(pass).toChangeAST('start = [a-z]', ruleDetails({ resultVars: ["result0"], posVars: [], expression: leafDetails })); }); - it("computes variable names for a class", function() { - expect(pass).toChangeAST('start = [a-z]', ruleDetails({ + it("computes variable names for an any", function() { + expect(pass).toChangeAST('start = .', ruleDetails({ resultVars: ["result0"], posVars: [], expression: leafDetails diff --git a/spec/generated-parser.spec.js b/spec/generated-parser.spec.js index 3ac038f..adc9bd9 100644 --- a/spec/generated-parser.spec.js +++ b/spec/generated-parser.spec.js @@ -601,26 +601,6 @@ describe("generated parser", function() { }); }); - describe("any matching", function() { - it("matches correctly", function() { - var parser = PEG.buildParser('start = .', options); - - expect(parser).toParse("a", "a"); - }); - - it("advances position on success", function() { - var parser = PEG.buildParser('start = . .', options); - - expect(parser).toParse("ab", ["a", "b"]); - }); - - it("sets expected string correctly on failure", function() { - var parser = PEG.buildParser('start = .', options); - - expect(parser).toFailToParse("", { expected: ['any character'] }); - }); - }); - describe("class matching", function() { it("matches empty class correctly", function() { var parser = PEG.buildParser('start = []', options); @@ -680,6 +660,26 @@ describe("generated parser", function() { }); }); + describe("any matching", function() { + it("matches correctly", function() { + var parser = PEG.buildParser('start = .', options); + + expect(parser).toParse("a", "a"); + }); + + it("advances position on success", function() { + var parser = PEG.buildParser('start = . .', options); + + expect(parser).toParse("ab", ["a", "b"]); + }); + + it("sets expected string correctly on failure", function() { + var parser = PEG.buildParser('start = .', options); + + expect(parser).toFailToParse("", { expected: ['any character'] }); + }); + }); + describe("error reporting", function() { describe("behavior", function() { it("reports only the rightmost error", function() { diff --git a/spec/parser.spec.js b/spec/parser.spec.js index 701bf47..34e9227 100644 --- a/spec/parser.spec.js +++ b/spec/parser.spec.js @@ -309,8 +309,8 @@ describe("PEG.js grammar parser", function() { it("parses primary", function() { expect('start = a' ).toParseAs(ruleRefGrammar("a")); expect('start = "abcd"' ).toParseAs(literalGrammar("abcd")); - expect('start = .' ).toParseAs(oneRuleGrammar({ type: "any" })); expect('start = [a-d]' ).toParseAs(classGrammar([["a", "d"]], "[a-d]")); + expect('start = .' ).toParseAs(oneRuleGrammar({ type: "any" })); expect('start = ("abcd")').toParseAs(literalGrammar("abcd")); }); diff --git a/src/compiler/passes/compute-params.js b/src/compiler/passes/compute-params.js index bedcc4e..68379e8 100644 --- a/src/compiler/passes/compute-params.js +++ b/src/compiler/passes/compute-params.js @@ -97,8 +97,8 @@ PEG.compiler.passes.computeParams = function(ast) { rule_ref: nop, literal: nop, - any: nop, - "class": nop + "class": nop, + any: nop }); compute(ast); diff --git a/src/compiler/passes/compute-var-names.js b/src/compiler/passes/compute-var-names.js index fd7b9df..7a28fc5 100644 --- a/src/compiler/passes/compute-var-names.js +++ b/src/compiler/passes/compute-var-names.js @@ -119,8 +119,8 @@ PEG.compiler.passes.computeVarNames = function(ast) { action: computeFromExpression({ result: 0, pos: 1 }), rule_ref: computeLeaf, literal: computeLeaf, - any: computeLeaf, - "class": computeLeaf + "class": computeLeaf, + any: computeLeaf }); compute(ast, { result: 0, pos: 0 }); diff --git a/src/compiler/passes/generate-code.js b/src/compiler/passes/generate-code.js index 694d957..67d89be 100644 --- a/src/compiler/passes/generate-code.js +++ b/src/compiler/passes/generate-code.js @@ -711,25 +711,25 @@ PEG.compiler.passes.generateCode = function(ast, options) { ' }', '#end' ], - any: [ - 'if (input.length > #{posOffset("pos")}) {', + "class": [ + 'if (#{regexp}.test(input.charAt(#{posOffset("pos")}))) {', ' #{node.resultVar} = input.charAt(#{posOffset("pos")});', ' #{posAdvance(1)};', '} else {', ' #{node.resultVar} = null;', ' if (reportFailures === 0) {', - ' matchFailed("any character");', + ' matchFailed(#{string(node.rawText)});', ' }', '}' ], - "class": [ - 'if (#{regexp}.test(input.charAt(#{posOffset("pos")}))) {', + any: [ + 'if (input.length > #{posOffset("pos")}) {', ' #{node.resultVar} = input.charAt(#{posOffset("pos")});', ' #{posAdvance(1)};', '} else {', ' #{node.resultVar} = null;', ' if (reportFailures === 0) {', - ' matchFailed(#{string(node.rawText)});', + ' matchFailed("any character");', ' }', '}' ] @@ -858,7 +858,6 @@ PEG.compiler.passes.generateCode = function(ast, options) { action: emitSimple("action"), rule_ref: emitSimple("rule_ref"), literal: emitSimple("literal"), - any: emitSimple("any"), "class": function(node) { var regexp; @@ -883,7 +882,9 @@ PEG.compiler.passes.generateCode = function(ast, options) { } return fill("class", { node: node, regexp: regexp }); - } + }, + + any: emitSimple("any") }); ast.code = emit(ast); diff --git a/src/compiler/passes/remove-proxy-rules.js b/src/compiler/passes/remove-proxy-rules.js index cafdef2..cc82d34 100644 --- a/src/compiler/passes/remove-proxy-rules.js +++ b/src/compiler/passes/remove-proxy-rules.js @@ -45,8 +45,8 @@ PEG.compiler.passes.removeProxyRules = function(ast) { }, literal: nop, - any: nop, - "class": nop + "class": nop, + any: nop }); replace(ast, from, to); diff --git a/src/compiler/passes/report-left-recursion.js b/src/compiler/passes/report-left-recursion.js index ae89e5d..caef1cf 100644 --- a/src/compiler/passes/report-left-recursion.js +++ b/src/compiler/passes/report-left-recursion.js @@ -53,8 +53,8 @@ PEG.compiler.passes.reportLeftRecursion = function(ast) { }, literal: nop, - any: nop, - "class": nop + "class": nop, + any: nop }); check(ast, []); diff --git a/src/compiler/passes/report-missing-rules.js b/src/compiler/passes/report-missing-rules.js index 62b5e26..35add74 100644 --- a/src/compiler/passes/report-missing-rules.js +++ b/src/compiler/passes/report-missing-rules.js @@ -34,8 +34,8 @@ PEG.compiler.passes.reportMissingRules = function(ast) { }, literal: nop, - any: nop, - "class": nop + "class": nop, + any: nop }); check(ast); diff --git a/src/parser.js b/src/parser.js index ab6411f..1c1c9ce 100644 --- a/src/parser.js +++ b/src/parser.js @@ -743,16 +743,16 @@ PEG.parser = (function(){ if (result0 === null) { result0 = parse_literal(); if (result0 === null) { - pos0 = pos; - result0 = parse_dot(); - if (result0 !== null) { - result0 = (function(offset) { return { type: "any" }; })(pos0); - } - if (result0 === null) { - pos = pos0; - } + result0 = parse_class(); if (result0 === null) { - result0 = parse_class(); + pos0 = pos; + result0 = parse_dot(); + if (result0 !== null) { + result0 = (function(offset) { return { type: "any" }; })(pos0); + } + if (result0 === null) { + pos = pos0; + } if (result0 === null) { pos0 = pos; pos1 = pos; diff --git a/src/parser.pegjs b/src/parser.pegjs index 2476278..b9cc837 100644 --- a/src/parser.pegjs +++ b/src/parser.pegjs @@ -139,8 +139,8 @@ primary }; } / literal - / dot { return { type: "any" }; } / class + / dot { return { type: "any" }; } / lparen expression:expression rparen { return expression; } /* "Lexical" elements */