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.
redux
David Majda 13 years ago
parent eb4badab24
commit cdf23e0a49

@ -211,16 +211,16 @@ describe("compiler pass |computeVarNames|", function() {
})); }));
}); });
it("computes variable names for an any", function() { it("computes variable names for a class", function() {
expect(pass).toChangeAST('start = .', ruleDetails({ expect(pass).toChangeAST('start = [a-z]', ruleDetails({
resultVars: ["result0"], resultVars: ["result0"],
posVars: [], posVars: [],
expression: leafDetails expression: leafDetails
})); }));
}); });
it("computes variable names for a class", function() { it("computes variable names for an any", function() {
expect(pass).toChangeAST('start = [a-z]', ruleDetails({ expect(pass).toChangeAST('start = .', ruleDetails({
resultVars: ["result0"], resultVars: ["result0"],
posVars: [], posVars: [],
expression: leafDetails expression: leafDetails

@ -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() { describe("class matching", function() {
it("matches empty class correctly", function() { it("matches empty class correctly", function() {
var parser = PEG.buildParser('start = []', options); 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("error reporting", function() {
describe("behavior", function() { describe("behavior", function() {
it("reports only the rightmost error", function() { it("reports only the rightmost error", function() {

@ -309,8 +309,8 @@ describe("PEG.js grammar parser", function() {
it("parses primary", function() { it("parses primary", function() {
expect('start = a' ).toParseAs(ruleRefGrammar("a")); expect('start = a' ).toParseAs(ruleRefGrammar("a"));
expect('start = "abcd"' ).toParseAs(literalGrammar("abcd")); expect('start = "abcd"' ).toParseAs(literalGrammar("abcd"));
expect('start = .' ).toParseAs(oneRuleGrammar({ type: "any" }));
expect('start = [a-d]' ).toParseAs(classGrammar([["a", "d"]], "[a-d]")); expect('start = [a-d]' ).toParseAs(classGrammar([["a", "d"]], "[a-d]"));
expect('start = .' ).toParseAs(oneRuleGrammar({ type: "any" }));
expect('start = ("abcd")').toParseAs(literalGrammar("abcd")); expect('start = ("abcd")').toParseAs(literalGrammar("abcd"));
}); });

@ -97,8 +97,8 @@ PEG.compiler.passes.computeParams = function(ast) {
rule_ref: nop, rule_ref: nop,
literal: nop, literal: nop,
any: nop, "class": nop,
"class": nop any: nop
}); });
compute(ast); compute(ast);

@ -119,8 +119,8 @@ PEG.compiler.passes.computeVarNames = function(ast) {
action: computeFromExpression({ result: 0, pos: 1 }), action: computeFromExpression({ result: 0, pos: 1 }),
rule_ref: computeLeaf, rule_ref: computeLeaf,
literal: computeLeaf, literal: computeLeaf,
any: computeLeaf, "class": computeLeaf,
"class": computeLeaf any: computeLeaf
}); });
compute(ast, { result: 0, pos: 0 }); compute(ast, { result: 0, pos: 0 });

@ -711,25 +711,25 @@ PEG.compiler.passes.generateCode = function(ast, options) {
' }', ' }',
'#end' '#end'
], ],
any: [ "class": [
'if (input.length > #{posOffset("pos")}) {', 'if (#{regexp}.test(input.charAt(#{posOffset("pos")}))) {',
' #{node.resultVar} = input.charAt(#{posOffset("pos")});', ' #{node.resultVar} = input.charAt(#{posOffset("pos")});',
' #{posAdvance(1)};', ' #{posAdvance(1)};',
'} else {', '} else {',
' #{node.resultVar} = null;', ' #{node.resultVar} = null;',
' if (reportFailures === 0) {', ' if (reportFailures === 0) {',
' matchFailed("any character");', ' matchFailed(#{string(node.rawText)});',
' }', ' }',
'}' '}'
], ],
"class": [ any: [
'if (#{regexp}.test(input.charAt(#{posOffset("pos")}))) {', 'if (input.length > #{posOffset("pos")}) {',
' #{node.resultVar} = input.charAt(#{posOffset("pos")});', ' #{node.resultVar} = input.charAt(#{posOffset("pos")});',
' #{posAdvance(1)};', ' #{posAdvance(1)};',
'} else {', '} else {',
' #{node.resultVar} = null;', ' #{node.resultVar} = null;',
' if (reportFailures === 0) {', ' if (reportFailures === 0) {',
' matchFailed(#{string(node.rawText)});', ' matchFailed("any character");',
' }', ' }',
'}' '}'
] ]
@ -858,7 +858,6 @@ PEG.compiler.passes.generateCode = function(ast, options) {
action: emitSimple("action"), action: emitSimple("action"),
rule_ref: emitSimple("rule_ref"), rule_ref: emitSimple("rule_ref"),
literal: emitSimple("literal"), literal: emitSimple("literal"),
any: emitSimple("any"),
"class": function(node) { "class": function(node) {
var regexp; var regexp;
@ -883,7 +882,9 @@ PEG.compiler.passes.generateCode = function(ast, options) {
} }
return fill("class", { node: node, regexp: regexp }); return fill("class", { node: node, regexp: regexp });
} },
any: emitSimple("any")
}); });
ast.code = emit(ast); ast.code = emit(ast);

@ -45,8 +45,8 @@ PEG.compiler.passes.removeProxyRules = function(ast) {
}, },
literal: nop, literal: nop,
any: nop, "class": nop,
"class": nop any: nop
}); });
replace(ast, from, to); replace(ast, from, to);

@ -53,8 +53,8 @@ PEG.compiler.passes.reportLeftRecursion = function(ast) {
}, },
literal: nop, literal: nop,
any: nop, "class": nop,
"class": nop any: nop
}); });
check(ast, []); check(ast, []);

@ -34,8 +34,8 @@ PEG.compiler.passes.reportMissingRules = function(ast) {
}, },
literal: nop, literal: nop,
any: nop, "class": nop,
"class": nop any: nop
}); });
check(ast); check(ast);

@ -742,6 +742,8 @@ PEG.parser = (function(){
} }
if (result0 === null) { if (result0 === null) {
result0 = parse_literal(); result0 = parse_literal();
if (result0 === null) {
result0 = parse_class();
if (result0 === null) { if (result0 === null) {
pos0 = pos; pos0 = pos;
result0 = parse_dot(); result0 = parse_dot();
@ -751,8 +753,6 @@ PEG.parser = (function(){
if (result0 === null) { if (result0 === null) {
pos = pos0; pos = pos0;
} }
if (result0 === null) {
result0 = parse_class();
if (result0 === null) { if (result0 === null) {
pos0 = pos; pos0 = pos;
pos1 = pos; pos1 = pos;

@ -139,8 +139,8 @@ primary
}; };
} }
/ literal / literal
/ dot { return { type: "any" }; }
/ class / class
/ dot { return { type: "any" }; }
/ lparen expression:expression rparen { return expression; } / lparen expression:expression rparen { return expression; }
/* "Lexical" elements */ /* "Lexical" elements */

Loading…
Cancel
Save