Use literal raw text in error messages

Fixes #127.
redux
David Majda 9 years ago
parent 36eb7b81b5
commit 69a0f769fc

@ -536,9 +536,7 @@ function generateBytecode(ast) {
'{', '{',
'type: "literal",', 'type: "literal",',
'value: "' + js.stringEscape(node.value) + '",', 'value: "' + js.stringEscape(node.value) + '",',
'description: "' 'description: "' + js.stringEscape(node.rawText) + '"',
+ js.stringEscape('"' + js.stringEscape(node.value) + '"')
+ '"',
'}' '}'
].join(' ')); ].join(' '));

@ -149,13 +149,13 @@ module.exports = (function() {
peg$c36 = "\t", peg$c36 = "\t",
peg$c37 = { type: "literal", value: "\t", description: "\"\\t\"" }, peg$c37 = { type: "literal", value: "\t", description: "\"\\t\"" },
peg$c38 = "\x0B", peg$c38 = "\x0B",
peg$c39 = { type: "literal", value: "\x0B", description: "\"\\x0B\"" }, peg$c39 = { type: "literal", value: "\x0B", description: "\"\\v\"" },
peg$c40 = "\f", peg$c40 = "\f",
peg$c41 = { type: "literal", value: "\f", description: "\"\\f\"" }, peg$c41 = { type: "literal", value: "\f", description: "\"\\f\"" },
peg$c42 = " ", peg$c42 = " ",
peg$c43 = { type: "literal", value: " ", description: "\" \"" }, peg$c43 = { type: "literal", value: " ", description: "\" \"" },
peg$c44 = "\xA0", peg$c44 = "\xA0",
peg$c45 = { type: "literal", value: "\xA0", description: "\"\\xA0\"" }, peg$c45 = { type: "literal", value: "\xA0", description: "\"\\u00A0\"" },
peg$c46 = "\uFEFF", peg$c46 = "\uFEFF",
peg$c47 = { type: "literal", value: "\uFEFF", description: "\"\\uFEFF\"" }, peg$c47 = { type: "literal", value: "\uFEFF", description: "\"\\uFEFF\"" },
peg$c48 = /^[\n\r\u2028\u2029]/, peg$c48 = /^[\n\r\u2028\u2029]/,
@ -198,12 +198,13 @@ module.exports = (function() {
type: "literal", type: "literal",
value: value, value: value,
ignoreCase: ignoreCase !== null, ignoreCase: ignoreCase !== null,
rawText: text(),
location: location() location: location()
}; };
}, },
peg$c84 = { type: "other", description: "string" }, peg$c84 = { type: "other", description: "string" },
peg$c85 = "\"", peg$c85 = "\"",
peg$c86 = { type: "literal", value: "\"", description: "\"\\\"\"" }, peg$c86 = { type: "literal", value: "\"", description: "'\"'" },
peg$c87 = function(chars) { return chars.join(""); }, peg$c87 = function(chars) { return chars.join(""); },
peg$c88 = "'", peg$c88 = "'",
peg$c89 = { type: "literal", value: "'", description: "\"'\"" }, peg$c89 = { type: "literal", value: "'", description: "\"'\"" },

@ -108,7 +108,7 @@ describe("plugin API", function() {
' {', ' {',
' type: "rule",', ' type: "rule",',
' name: "start",', ' name: "start",',
' expression: { type: "literal", value: text(), ignoreCase: false }', ' expression: { type: "literal", value: text(), ignoreCase: false, rawText: text() }',
' }', ' }',
' ]', ' ]',
' };', ' };',

@ -572,7 +572,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() { it("defines correct constants", function() {
expect(pass).toChangeAST(grammar, constsDetails([ expect(pass).toChangeAST(grammar, constsDetails([
'"a"', '"a"',
'{ type: "literal", value: "A", description: "\\"A\\"" }' '{ type: "literal", value: "A", description: "\\"A\\"i" }'
])); ]));
}); });
}); });

@ -4,10 +4,10 @@
"use strict"; "use strict";
describe("PEG.js grammar parser", function() { describe("PEG.js grammar parser", function() {
var literalAbcd = { type: "literal", value: "abcd", ignoreCase: false }, var literalAbcd = { type: "literal", value: "abcd", ignoreCase: false, rawText: '"abcd"' },
literalEfgh = { type: "literal", value: "efgh", ignoreCase: false }, literalEfgh = { type: "literal", value: "efgh", ignoreCase: false, rawText: '"efgh"' },
literalIjkl = { type: "literal", value: "ijkl", ignoreCase: false }, literalIjkl = { type: "literal", value: "ijkl", ignoreCase: false, rawText: '"ijkl"' },
literalMnop = { type: "literal", value: "mnop", ignoreCase: false }, literalMnop = { type: "literal", value: "mnop", ignoreCase: false, rawText: '"mnop"' },
semanticAnd = { type: "semantic_and", code: " code " }, semanticAnd = { type: "semantic_and", code: " code " },
semanticNot = { type: "semantic_not", code: " code " }, semanticNot = { type: "semantic_not", code: " code " },
optional = { type: "optional", expression: literalAbcd }, optional = { type: "optional", expression: literalAbcd },
@ -72,10 +72,13 @@ describe("PEG.js grammar parser", function() {
); );
} }
function literalGrammar(value, ignoreCase) { function literalGrammar(value, ignoreCase, rawText) {
return oneRuleGrammar( return oneRuleGrammar({
{ type: "literal", value: value, ignoreCase: ignoreCase } type: "literal",
); value: value,
ignoreCase: ignoreCase,
rawText: rawText
});
} }
function classGrammar(parts, inverted, ignoreCase, rawText) { function classGrammar(parts, inverted, ignoreCase, rawText) {
@ -96,7 +99,7 @@ describe("PEG.js grammar parser", function() {
return oneRuleGrammar({ type: "rule_ref", name: name }); return oneRuleGrammar({ type: "rule_ref", name: name });
} }
var trivialGrammar = literalGrammar("abcd", false), var trivialGrammar = literalGrammar("abcd", false, '"abcd"'),
twoRuleGrammar = { twoRuleGrammar = {
type: "grammar", type: "grammar",
initializer: null, initializer: null,
@ -488,26 +491,26 @@ describe("PEG.js grammar parser", function() {
/* Canonical LiteralMatcher is "\"abcd\"". */ /* Canonical LiteralMatcher is "\"abcd\"". */
it("parses LiteralMatcher", function() { it("parses LiteralMatcher", function() {
expect('start = "abcd"' ).toParseAs(literalGrammar("abcd", false)); expect('start = "abcd"' ).toParseAs(literalGrammar("abcd", false, '"abcd"'));
expect('start = "abcd"i').toParseAs(literalGrammar("abcd", true)); expect('start = "abcd"i').toParseAs(literalGrammar("abcd", true, '"abcd"i'));
}); });
/* Canonical StringLiteral is "\"abcd\"". */ /* Canonical StringLiteral is "\"abcd\"". */
it("parses StringLiteral", function() { it("parses StringLiteral", function() {
expect('start = ""' ).toParseAs(literalGrammar("", false)); expect('start = ""' ).toParseAs(literalGrammar("", false, '""'));
expect('start = "a"' ).toParseAs(literalGrammar("a", false)); expect('start = "a"' ).toParseAs(literalGrammar("a", false, '"a"'));
expect('start = "abc"').toParseAs(literalGrammar("abc", false)); expect('start = "abc"').toParseAs(literalGrammar("abc", false, '"abc"'));
expect("start = ''" ).toParseAs(literalGrammar("", false)); expect("start = ''" ).toParseAs(literalGrammar("", false, "''"));
expect("start = 'a'" ).toParseAs(literalGrammar("a", false)); expect("start = 'a'" ).toParseAs(literalGrammar("a", false, "'a'"));
expect("start = 'abc'").toParseAs(literalGrammar("abc", false)); expect("start = 'abc'").toParseAs(literalGrammar("abc", false, "'abc'"));
}); });
/* Canonical DoubleStringCharacter is "a". */ /* Canonical DoubleStringCharacter is "a". */
it("parses DoubleStringCharacter", function() { it("parses DoubleStringCharacter", function() {
expect('start = "a"' ).toParseAs(literalGrammar("a", false)); expect('start = "a"' ).toParseAs(literalGrammar("a", false, '"a"'));
expect('start = "\\n"' ).toParseAs(literalGrammar("\n", false)); expect('start = "\\n"' ).toParseAs(literalGrammar("\n", false, '"\\n"'));
expect('start = "\\\n"').toParseAs(literalGrammar("", false)); expect('start = "\\\n"').toParseAs(literalGrammar("", false, '"\\\n"'));
expect('start = """' ).toFailToParse(); expect('start = """' ).toFailToParse();
expect('start = "\\"').toFailToParse(); expect('start = "\\"').toFailToParse();
@ -516,9 +519,9 @@ describe("PEG.js grammar parser", function() {
/* Canonical SingleStringCharacter is "a". */ /* Canonical SingleStringCharacter is "a". */
it("parses SingleStringCharacter", function() { it("parses SingleStringCharacter", function() {
expect("start = 'a'" ).toParseAs(literalGrammar("a", false)); expect("start = 'a'" ).toParseAs(literalGrammar("a", false, "'a'"));
expect("start = '\\n'" ).toParseAs(literalGrammar("\n", false)); expect("start = '\\n'" ).toParseAs(literalGrammar("\n", false, "'\\n'"));
expect("start = '\\\n'").toParseAs(literalGrammar("", false)); expect("start = '\\\n'").toParseAs(literalGrammar("", false, "'\\\n'"));
expect("start = '''" ).toFailToParse(); expect("start = '''" ).toFailToParse();
expect("start = '\\'").toFailToParse(); expect("start = '\\'").toFailToParse();
@ -589,41 +592,41 @@ describe("PEG.js grammar parser", function() {
/* Canonical LineContinuation is "\\\n". */ /* Canonical LineContinuation is "\\\n". */
it("parses LineContinuation", function() { it("parses LineContinuation", function() {
expect('start = "\\\r\n"').toParseAs(literalGrammar("", false)); expect('start = "\\\r\n"').toParseAs(literalGrammar("", false, '"\\\r\n"'));
}); });
/* Canonical EscapeSequence is "n". */ /* Canonical EscapeSequence is "n". */
it("parses EscapeSequence", function() { it("parses EscapeSequence", function() {
expect('start = "\\n"' ).toParseAs(literalGrammar("\n", false)); expect('start = "\\n"' ).toParseAs(literalGrammar("\n", false, '"\\n"'));
expect('start = "\\0"' ).toParseAs(literalGrammar("\x00", false)); expect('start = "\\0"' ).toParseAs(literalGrammar("\x00", false, '"\\0"'));
expect('start = "\\xFF"' ).toParseAs(literalGrammar("\xFF", false)); expect('start = "\\xFF"' ).toParseAs(literalGrammar("\xFF", false, '"\\xFF"'));
expect('start = "\\uFFFF"').toParseAs(literalGrammar("\uFFFF", false)); expect('start = "\\uFFFF"').toParseAs(literalGrammar("\uFFFF", false, '"\\uFFFF"'));
expect('start = "\\09"').toFailToParse(); expect('start = "\\09"').toFailToParse();
}); });
/* Canonical CharacterEscapeSequence is "n". */ /* Canonical CharacterEscapeSequence is "n". */
it("parses CharacterEscapeSequence", function() { it("parses CharacterEscapeSequence", function() {
expect('start = "\\n"').toParseAs(literalGrammar("\n", false)); expect('start = "\\n"').toParseAs(literalGrammar("\n", false, '"\\n"'));
expect('start = "\\a"').toParseAs(literalGrammar("a", false)); expect('start = "\\a"').toParseAs(literalGrammar("a", false, '"\\a"'));
}); });
/* Canonical SingleEscapeCharacter is "n". */ /* Canonical SingleEscapeCharacter is "n". */
it("parses SingleEscapeCharacter", function() { it("parses SingleEscapeCharacter", function() {
expect('start = "\\\'"').toParseAs(literalGrammar("'", false)); expect('start = "\\\'"').toParseAs(literalGrammar("'", false, '"\\\'"'));
expect('start = "\\""' ).toParseAs(literalGrammar('"', false)); expect('start = "\\""' ).toParseAs(literalGrammar('"', false, '"\\""'));
expect('start = "\\\\"').toParseAs(literalGrammar("\\", false)); expect('start = "\\\\"').toParseAs(literalGrammar("\\", false, '"\\\\"'));
expect('start = "\\b"' ).toParseAs(literalGrammar("\b", false)); expect('start = "\\b"' ).toParseAs(literalGrammar("\b", false, '"\\b"'));
expect('start = "\\f"' ).toParseAs(literalGrammar("\f", false)); expect('start = "\\f"' ).toParseAs(literalGrammar("\f", false, '"\\f"'));
expect('start = "\\n"' ).toParseAs(literalGrammar("\n", false)); expect('start = "\\n"' ).toParseAs(literalGrammar("\n", false, '"\\n"'));
expect('start = "\\r"' ).toParseAs(literalGrammar("\r", false)); expect('start = "\\r"' ).toParseAs(literalGrammar("\r", false, '"\\r"'));
expect('start = "\\t"' ).toParseAs(literalGrammar("\t", false)); expect('start = "\\t"' ).toParseAs(literalGrammar("\t", false, '"\\t"'));
expect('start = "\\v"' ).toParseAs(literalGrammar("\x0B", false)); // no "\v" in IE expect('start = "\\v"' ).toParseAs(literalGrammar("\x0B", false, '"\\v"')); // no "\v" in IE
}); });
/* Canonical NonEscapeCharacter is "a". */ /* Canonical NonEscapeCharacter is "a". */
it("parses NonEscapeCharacter", function() { it("parses NonEscapeCharacter", function() {
expect('start = "\\a"').toParseAs(literalGrammar("a", false)); expect('start = "\\a"').toParseAs(literalGrammar("a", false, '"\\a"'));
/* /*
* The negative predicate is impossible to test with PEG.js grammar * The negative predicate is impossible to test with PEG.js grammar
@ -638,12 +641,12 @@ describe("PEG.js grammar parser", function() {
/* Canonical HexEscapeSequence is "xFF". */ /* Canonical HexEscapeSequence is "xFF". */
it("parses HexEscapeSequence", function() { it("parses HexEscapeSequence", function() {
expect('start = "\\xFF"').toParseAs(literalGrammar("\xFF", false)); expect('start = "\\xFF"').toParseAs(literalGrammar("\xFF", false, '"\\xFF"'));
}); });
/* Canonical UnicodeEscapeSequence is "uFFFF". */ /* Canonical UnicodeEscapeSequence is "uFFFF". */
it("parses UnicodeEscapeSequence", function() { it("parses UnicodeEscapeSequence", function() {
expect('start = "\\uFFFF"').toParseAs(literalGrammar("\uFFFF", false)); expect('start = "\\uFFFF"').toParseAs(literalGrammar("\uFFFF", false, '"\\uFFFF"'));
}); });
/* Digit rules are not tested. */ /* Digit rules are not tested. */

@ -345,6 +345,7 @@ LiteralMatcher "literal"
type: "literal", type: "literal",
value: value, value: value,
ignoreCase: ignoreCase !== null, ignoreCase: ignoreCase !== null,
rawText: text(),
location: location() location: location()
}; };
} }

Loading…
Cancel
Save