Added OneOrMore AST node.

This speeds up the benchmark suite execution by 1.08% on V8.

Detailed results (benchmark suite totals):

---------------------------------
 Test #     Before       After
---------------------------------
      1   28.38 kB/s   28.72 kB/s
      2   28.52 kB/s   28.84 kB/s
      3   28.41 kB/s   28.83 kB/s
      4   28.47 kB/s   28.81 kB/s
      5   28.64 kB/s   28.76 kB/s
---------------------------------
Average   28.48 kB/s   28.79 kB/s
---------------------------------

Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.9 Safari/533.2
redux
David Majda 15 years ago
parent 8f59e21c8d
commit c3c1c79665

@ -200,6 +200,8 @@ PEG.Grammar.Choice = function(alternatives) {
PEG.Grammar.ZeroOrMore = function(element) { this._element = element; };
PEG.Grammar.OneOrMore = function(element) { this._element = element; };
PEG.Grammar.NotPredicate = function(expression) {
this._expression = expression;
};
@ -240,6 +242,9 @@ PEG.Grammar.extendNodes("checkReferencedRulesExist", {
ZeroOrMore:
function(grammar) { this._element.checkReferencedRulesExist(grammar); },
OneOrMore:
function(grammar) { this._element.checkReferencedRulesExist(grammar); },
NotPredicate:
function(grammar) { this._expression.checkReferencedRulesExist(grammar); },
@ -288,6 +293,11 @@ PEG.Grammar.extendNodes("checkNoLeftRecursion", {
this._element.checkNoLeftRecursion(grammar, appliedRules);
},
OneOrMore:
function(grammar, appliedRules) {
this._element.checkNoLeftRecursion(grammar, appliedRules);
},
NotPredicate:
function(grammar, appliedRules) {
this._expression.checkNoLeftRecursion(grammar, appliedRules);
@ -858,6 +868,28 @@ PEG.Grammar.ZeroOrMore.prototype.compile = function(resultVar) {
);
};
PEG.Grammar.OneOrMore.prototype.compile = function(resultVar) {
var elementResultVar = PEG.Compiler.generateUniqueIdentifier("result");
return PEG.Compiler.formatCode(
"${elementCode}",
"if (${elementResultVar} !== null) {",
" var ${resultVar} = [];",
" while (${elementResultVar} !== null) {",
" ${resultVar}.push(${elementResultVar});",
" ${elementCode}",
" }",
"} else {",
" var ${resultVar} = null;",
"}",
{
elementCode: this._element.compile(elementResultVar),
elementResultVar: elementResultVar,
resultVar: resultVar
}
);
};
PEG.Grammar.NotPredicate.prototype.compile = function(resultVar) {
var savedPosVar = PEG.Compiler.generateUniqueIdentifier("savedPos");
var savedReportMatchFailuresVar = PEG.Compiler.generateUniqueIdentifier("savedReportMatchFailuresVar");

File diff suppressed because it is too large Load Diff

@ -40,12 +40,7 @@ suffixed
return new PEG.Grammar.Choice([$1, new PEG.Grammar.Literal("")]);
}
/ primary star { return new PEG.Grammar.ZeroOrMore($1); }
/ primary plus {
return new PEG.Grammar.Action(
new PEG.Grammar.Sequence([$1, new PEG.Grammar.ZeroOrMore($1)]),
function(first, rest) { return [first].concat(rest); }
);
}
/ primary plus { return new PEG.Grammar.OneOrMore($1); }
/ primary
primary

@ -192,6 +192,7 @@ test("buildParser reports missing referenced rules", function() {
'start: missing / "a" / "b"',
'start: "a" / "b" / missing',
'start: missing*',
'start: missing+',
'start: !missing',
'start: &missing',
'start: missing { }'
@ -214,6 +215,7 @@ test("buildParser reports left recursion", function() {
'start: start / "a" / "b"',
'start: "a" / "b" / start',
'start: start*',
'start: start+',
'start: !start',
'start: &start',
'start: start { }',

@ -149,13 +149,7 @@ with (PEG.Grammar) {
test("parses suffixed", function() {
grammarParserParses('start: "abcd"?', oneRuleGrammar(choice));
grammarParserParses('start: "abcd"*', oneRuleGrammar(new ZeroOrMore(literalAbcd)));
grammarParserParses(
'start: "abcd"+',
oneRuleGrammar(new Action(
new Sequence([literalAbcd, new ZeroOrMore(literalAbcd)]),
function(first, rest) { return [first].concat(rest); }
))
);
grammarParserParses('start: "abcd"+', oneRuleGrammar(new OneOrMore(literalAbcd)));
grammarParserParses('start: "abcd"', literalGrammar("abcd"));
});

Loading…
Cancel
Save