Browse Source

PEG.js grammar: Fix line continuation handling in character classes

Before this commit, line continuations in character classes contributed
an empty string to the list of characters and character ranges matched
by a class. While this didn't lead to a buggy behavior with the current
code generator, the AST was wrong and the problem could have caused bugs
later.

This commit fixes the problem.
redux
David Majda 8 years ago
parent
commit
64eb5faf54
  1. 14
      lib/parser.js
  2. 6
      spec/parser.spec.js
  3. 14
      src/parser.pegjs

14
lib/parser.js

@ -182,7 +182,7 @@ module.exports = (function() {
peg$c103 = function(inverted, parts, ignoreCase) {
return {
type: "class",
parts: parts,
parts: filterEmptyStrings(parts),
inverted: inverted !== null,
ignoreCase: ignoreCase !== null,
rawText: text()
@ -4743,6 +4743,18 @@ module.exports = (function() {
"!": "semantic_not"
};
function filterEmptyStrings(array) {
var result = [], i;
for (i = 0; i < array.length; i++) {
if (array[i] !== "") {
result.push(array[i]);
}
}
return result;
}
function extractOptional(optional, index) {
return optional ? optional[index] : null;
}

6
spec/parser.spec.js

@ -485,6 +485,10 @@ describe("PEG.js grammar parser", function() {
expect('start = [a-d]i').toParseAs(
classGrammar([["a", "d"]], false, true, "[a-d]i")
);
expect('start = [\\\n]').toParseAs(
classGrammar([], false, false, "[\\\n]")
);
});
/* Canonical ClassCharacterRange is "a-d". */
@ -510,7 +514,7 @@ describe("PEG.js grammar parser", function() {
classGrammar(["\n"], false, false, "[\\n]")
);
expect('start = [\\\n]').toParseAs(
classGrammar([''], false, false, "[\\\n]")
classGrammar([], false, false, "[\\\n]")
);
expect('start = []]' ).toFailToParse();

14
src/parser.pegjs

@ -41,6 +41,18 @@
"!": "semantic_not"
};
function filterEmptyStrings(array) {
var result = [], i;
for (i = 0; i < array.length; i++) {
if (array[i] !== "") {
result.push(array[i]);
}
}
return result;
}
function extractOptional(optional, index) {
return optional ? optional[index] : null;
}
@ -323,7 +335,7 @@ CharacterClassMatcher "character class"
{
return {
type: "class",
parts: parts,
parts: filterEmptyStrings(parts),
inverted: inverted !== null,
ignoreCase: ignoreCase !== null,
rawText: text()

Loading…
Cancel
Save