PEG.js grammar: Capitalize rule names

When rule names are capitalized, it's easier to visually distinguish
them from non-capitalized label names. Moreover, I use capitalized rule
names in all my grammars these days.
redux
David Majda 10 years ago
parent fb72c430e6
commit 4725632641

File diff suppressed because it is too large Load Diff

@ -161,8 +161,8 @@ describe("PEG.js grammar parser", function() {
}); });
}); });
/* Canonical grammar is "a = \"abcd\"; b = \"efgh\"; c = \"ijkl\";". */ /* Canonical Grammar is "a = \"abcd\"; b = \"efgh\"; c = \"ijkl\";". */
it("parses grammar", function() { it("parses Grammar", function() {
var ruleA = { type: "rule", name: "a", expression: literalAbcd }, var ruleA = { type: "rule", name: "a", expression: literalAbcd },
ruleB = { type: "rule", name: "b", expression: literalEfgh }, ruleB = { type: "rule", name: "b", expression: literalEfgh },
ruleC = { type: "rule", name: "c", expression: literalIjkl }; ruleC = { type: "rule", name: "c", expression: literalIjkl };
@ -184,8 +184,8 @@ describe("PEG.js grammar parser", function() {
}); });
}); });
/* Canonical initializer is "{ code }". */ /* Canonical Initializer is "{ code }". */
it("parses initializer", function() { it("parses Initializer", function() {
var grammar = oneRuleGrammar(literalAbcd, { var grammar = oneRuleGrammar(literalAbcd, {
type: "initializer", type: "initializer",
code: " code " code: " code "
@ -195,8 +195,8 @@ describe("PEG.js grammar parser", function() {
expect('{ code }; start = "abcd"').toParseAs(grammar); expect('{ code }; start = "abcd"').toParseAs(grammar);
}); });
/* Canonical rule is "a: \"abcd\"". */ /* Canonical Rule is "a: \"abcd\"". */
it("parses rule", function() { it("parses Rule", function() {
expect('start = "abcd" / "efgh" / "ijkl"').toParseAs( expect('start = "abcd" / "efgh" / "ijkl"').toParseAs(
oneRuleGrammar(choiceOfLiterals) oneRuleGrammar(choiceOfLiterals)
); );
@ -212,15 +212,15 @@ describe("PEG.js grammar parser", function() {
); );
}); });
/* Canonical expression is "\"abcd\" / \"efgh\" / \"ijkl\"". */ /* Canonical Expression is "\"abcd\" / \"efgh\" / \"ijkl\"". */
it("parses expression", function() { it("parses Expression", function() {
expect('start = "abcd" / "efgh" / "ijkl"').toParseAs( expect('start = "abcd" / "efgh" / "ijkl"').toParseAs(
oneRuleGrammar(choiceOfLiterals) oneRuleGrammar(choiceOfLiterals)
); );
}); });
/* Canonical choice is "\"abcd\" / \"efgh\" / \"ijkl\"". */ /* Canonical Choice is "\"abcd\" / \"efgh\" / \"ijkl\"". */
it("parses choice", function() { it("parses Choice", function() {
expect('start = "abcd" "efgh" "ijkl"').toParseAs( expect('start = "abcd" "efgh" "ijkl"').toParseAs(
oneRuleGrammar(sequenceOfLiterals) oneRuleGrammar(sequenceOfLiterals)
); );
@ -232,8 +232,8 @@ describe("PEG.js grammar parser", function() {
})); }));
}); });
/* Canonical sequence is "\"abcd\" \"efgh\" \"ijkl\"". */ /* Canonical Sequence is "\"abcd\" \"efgh\" \"ijkl\"". */
it("parses sequence", function() { it("parses Sequence", function() {
expect('start = a:"abcd" { code }').toParseAs( expect('start = a:"abcd" { code }').toParseAs(
oneRuleGrammar({ type: "action", expression: labeledAbcd, code: " code " }) oneRuleGrammar({ type: "action", expression: labeledAbcd, code: " code " })
); );
@ -253,8 +253,8 @@ describe("PEG.js grammar parser", function() {
); );
}); });
/* Canonical labeled is "label:\"abcd\"". */ /* Canonical Labeled is "label:\"abcd\"". */
it("parses labeled", function() { it("parses Labeled", function() {
expect('start = label:!"abcd"').toParseAs(oneRuleGrammar({ expect('start = label:!"abcd"').toParseAs(oneRuleGrammar({
type: "labeled", type: "labeled",
label: "label", label: "label",
@ -263,8 +263,8 @@ describe("PEG.js grammar parser", function() {
expect('start = !"abcd"' ).toParseAs(oneRuleGrammar(simpleNotLiteral)); expect('start = !"abcd"' ).toParseAs(oneRuleGrammar(simpleNotLiteral));
}); });
/* Canonical prefixed is "!\"abcd\"". */ /* Canonical Prefixed is "!\"abcd\"". */
it("parses prefixed", function() { it("parses Prefixed", function() {
expect('start = $"abcd"?' ).toParseAs(oneRuleGrammar({ expect('start = $"abcd"?' ).toParseAs(oneRuleGrammar({
type: "text", type: "text",
expression: optionalLiteral expression: optionalLiteral
@ -288,8 +288,8 @@ describe("PEG.js grammar parser", function() {
expect('start = "abcd"?' ).toParseAs(oneRuleGrammar(optionalLiteral)); expect('start = "abcd"?' ).toParseAs(oneRuleGrammar(optionalLiteral));
}); });
/* Canonical suffixed is "\"abcd\"?". */ /* Canonical Suffixed is "\"abcd\"?". */
it("parses suffixed", function() { it("parses Suffixed", function() {
expect('start = "abcd"?').toParseAs(oneRuleGrammar(optionalLiteral)); expect('start = "abcd"?').toParseAs(oneRuleGrammar(optionalLiteral));
expect('start = "abcd"*').toParseAs(oneRuleGrammar({ expect('start = "abcd"*').toParseAs(oneRuleGrammar({
type: "zero_or_more", type: "zero_or_more",
@ -302,8 +302,8 @@ describe("PEG.js grammar parser", function() {
expect('start = "abcd"' ).toParseAs(literalGrammar("abcd")); expect('start = "abcd"' ).toParseAs(literalGrammar("abcd"));
}); });
/* Canonical primary is "\"abcd\"". */ /* Canonical Primary is "\"abcd\"". */
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 = [a-d]' ).toParseAs(classGrammar([["a", "d"]], "[a-d]")); expect('start = [a-d]' ).toParseAs(classGrammar([["a", "d"]], "[a-d]"));
@ -311,29 +311,29 @@ describe("PEG.js grammar parser", function() {
expect('start = ("abcd")').toParseAs(literalGrammar("abcd")); expect('start = ("abcd")').toParseAs(literalGrammar("abcd"));
}); });
/* Canonical action is "{ code }". */ /* Canonical Action is "{ code }". */
it("parses action", function() { it("parses Action", function() {
expect('start = "abcd" { code }').toParseAs(actionGrammar(" code ")); expect('start = "abcd" { code }').toParseAs(actionGrammar(" code "));
expect('start = "abcd" { code }\n').toParseAs(actionGrammar(" code ")); expect('start = "abcd" { code }\n').toParseAs(actionGrammar(" code "));
}); });
/* Canonical braced is "{ code }". */ /* Canonical Braced is "{ code }". */
it("parses braced", function() { it("parses Braced", function() {
expect('start = "abcd" {}' ).toParseAs(actionGrammar("")); expect('start = "abcd" {}' ).toParseAs(actionGrammar(""));
expect('start = "abcd" {{a}}' ).toParseAs(actionGrammar("{a}")); expect('start = "abcd" {{a}}' ).toParseAs(actionGrammar("{a}"));
expect('start = "abcd" {abcd}' ).toParseAs(actionGrammar("abcd")); expect('start = "abcd" {abcd}' ).toParseAs(actionGrammar("abcd"));
expect('start = "abcd" {{a}{b}{c}}').toParseAs(actionGrammar("{a}{b}{c}")); expect('start = "abcd" {{a}{b}{c}}').toParseAs(actionGrammar("{a}{b}{c}"));
}); });
/* Canonical nonBraceCharacters is "abcd". */ /* Canonical NonBraceCharacters is "abcd". */
it("parses nonBraceCharacters", function() { it("parses NonBraceCharacters", function() {
expect('start = "abcd" {a}' ).toParseAs(actionGrammar("a")); expect('start = "abcd" {a}' ).toParseAs(actionGrammar("a"));
expect('start = "abcd" {abc}').toParseAs(actionGrammar("abc")); expect('start = "abcd" {abc}').toParseAs(actionGrammar("abc"));
}); });
/* Canonical nonBraceCharacter is "a". */ /* Canonical NonBraceCharacter is "a". */
it("parses nonBraceCharacter", function() { it("parses NonBraceCharacter", function() {
expect('start = "abcd" {a}').toParseAs(actionGrammar("a")); expect('start = "abcd" {a}').toParseAs(actionGrammar("a"));
expect('start = "abcd" {{}').toFailToParse(); expect('start = "abcd" {{}').toFailToParse();
@ -342,8 +342,8 @@ describe("PEG.js grammar parser", function() {
/* Trivial character rules are not tested. */ /* Trivial character rules are not tested. */
/* Canonical identifier is "a". */ /* Canonical Identifier is "a". */
it("parses identifier", function() { it("parses Identifier", function() {
expect('start = a' ).toParseAs(ruleRefGrammar("a")); expect('start = a' ).toParseAs(ruleRefGrammar("a"));
expect('start = _' ).toParseAs(ruleRefGrammar("_")); expect('start = _' ).toParseAs(ruleRefGrammar("_"));
expect('start = aa' ).toParseAs(ruleRefGrammar("aa")); expect('start = aa' ).toParseAs(ruleRefGrammar("aa"));
@ -354,8 +354,8 @@ describe("PEG.js grammar parser", function() {
expect('start = a\n').toParseAs(ruleRefGrammar("a")); expect('start = a\n').toParseAs(ruleRefGrammar("a"));
}); });
/* Canonical literal is "\"abcd\"". */ /* Canonical Literal is "\"abcd\"". */
it("parses literal", function() { it("parses Literal", function() {
expect('start = "abcd"' ).toParseAs(literalGrammar("abcd")); expect('start = "abcd"' ).toParseAs(literalGrammar("abcd"));
expect("start = 'abcd'" ).toParseAs(literalGrammar("abcd")); expect("start = 'abcd'" ).toParseAs(literalGrammar("abcd"));
@ -364,8 +364,8 @@ describe("PEG.js grammar parser", function() {
expect('start = "abcd"\n').toParseAs(literalGrammar("abcd")); expect('start = "abcd"\n').toParseAs(literalGrammar("abcd"));
}); });
/* Canonical string is "\"abcd\"". */ /* Canonical String is "\"abcd\"". */
it("parses string", function() { it("parses String", function() {
var grammar = oneRuleGrammar({ var grammar = oneRuleGrammar({
type: "named", type: "named",
name: "abcd", name: "abcd",
@ -378,15 +378,15 @@ describe("PEG.js grammar parser", function() {
expect('start "abcd"\n= "abcd"').toParseAs(grammar); expect('start "abcd"\n= "abcd"').toParseAs(grammar);
}); });
/* Canonical doubleQuotedString is "\"abcd\"". */ /* Canonical DoubleQuotedString is "\"abcd\"". */
it("parses doubleQuotedString", function() { it("parses DoubleQuotedString", function() {
expect('start = ""' ).toParseAs(literalGrammar("")); expect('start = ""' ).toParseAs(literalGrammar(""));
expect('start = "a"' ).toParseAs(literalGrammar("a")); expect('start = "a"' ).toParseAs(literalGrammar("a"));
expect('start = "abc"').toParseAs(literalGrammar("abc")); expect('start = "abc"').toParseAs(literalGrammar("abc"));
}); });
/* Canonical doubleQuotedCharacter is "a". */ /* Canonical DoubleQuotedCharacter is "a". */
it("parses doubleQuotedCharacter", function() { it("parses DoubleQuotedCharacter", function() {
expect('start = "a"' ).toParseAs(literalGrammar("a")); expect('start = "a"' ).toParseAs(literalGrammar("a"));
expect('start = "\\n"' ).toParseAs(literalGrammar("\n")); expect('start = "\\n"' ).toParseAs(literalGrammar("\n"));
expect('start = "\\0"' ).toParseAs(literalGrammar("\x00")); expect('start = "\\0"' ).toParseAs(literalGrammar("\x00"));
@ -395,8 +395,8 @@ describe("PEG.js grammar parser", function() {
expect('start = "\\\n"' ).toParseAs(literalGrammar("")); expect('start = "\\\n"' ).toParseAs(literalGrammar(""));
}); });
/* Canonical simpleDoubleQuotedCharacter is "a". */ /* Canonical SimpleDoubleQuotedCharacter is "a". */
it("parses simpleDoubleQuotedCharacter", function() { it("parses SimpleDoubleQuotedCharacter", function() {
expect('start = "a"').toParseAs(literalGrammar("a")); expect('start = "a"').toParseAs(literalGrammar("a"));
expect('start = """' ).toFailToParse(); expect('start = """' ).toFailToParse();
@ -404,15 +404,15 @@ describe("PEG.js grammar parser", function() {
expect('start = "\n"').toFailToParse(); expect('start = "\n"').toFailToParse();
}); });
/* Canonical singleQuotedString is "'abcd'". */ /* Canonical SingleQuotedString is "'abcd'". */
it("parses singleQuotedString", function() { it("parses SingleQuotedString", function() {
expect("start = ''" ).toParseAs(literalGrammar("")); expect("start = ''" ).toParseAs(literalGrammar(""));
expect("start = 'a'" ).toParseAs(literalGrammar("a")); expect("start = 'a'" ).toParseAs(literalGrammar("a"));
expect("start = 'abc'").toParseAs(literalGrammar("abc")); expect("start = 'abc'").toParseAs(literalGrammar("abc"));
}); });
/* Canonical singleQuotedCharacter is "a". */ /* Canonical SingleQuotedCharacter is "a". */
it("parses singleQuotedCharacter", function() { it("parses SingleQuotedCharacter", function() {
expect("start = 'a'" ).toParseAs(literalGrammar("a")); expect("start = 'a'" ).toParseAs(literalGrammar("a"));
expect("start = '\\n'" ).toParseAs(literalGrammar("\n")); expect("start = '\\n'" ).toParseAs(literalGrammar("\n"));
expect("start = '\\0'" ).toParseAs(literalGrammar("\x00")); expect("start = '\\0'" ).toParseAs(literalGrammar("\x00"));
@ -421,8 +421,8 @@ describe("PEG.js grammar parser", function() {
expect("start = '\\\n'" ).toParseAs(literalGrammar("")); expect("start = '\\\n'" ).toParseAs(literalGrammar(""));
}); });
/* Canonical simpleSingleQuotedCharacter is "a". */ /* Canonical SimpleSingleQuotedCharacter is "a". */
it("parses simpleSingleQuotedCharacter", function() { it("parses SimpleSingleQuotedCharacter", function() {
expect("start = 'a'").toParseAs(literalGrammar("a")); expect("start = 'a'").toParseAs(literalGrammar("a"));
expect("start = '''" ).toFailToParse(); expect("start = '''" ).toFailToParse();
@ -430,8 +430,8 @@ describe("PEG.js grammar parser", function() {
expect("start = '\n'").toFailToParse(); expect("start = '\n'").toFailToParse();
}); });
/* Canonical class is "[a-d]". */ /* Canonical Class is "[a-d]". */
it("parses class", function() { it("parses Class", function() {
expect('start = []' ).toParseAs(classGrammar([], "[]")); expect('start = []' ).toParseAs(classGrammar([], "[]"));
expect('start = [a-d]' ).toParseAs(classGrammar([["a", "d"]], "[a-d]")); expect('start = [a-d]' ).toParseAs(classGrammar([["a", "d"]], "[a-d]"));
expect('start = [a]' ).toParseAs(classGrammar(["a"], "[a]")); expect('start = [a]' ).toParseAs(classGrammar(["a"], "[a]"));
@ -449,8 +449,8 @@ describe("PEG.js grammar parser", function() {
expect('start = [a-d]\n').toParseAs(classGrammar([["a", "d"]], "[a-d]")); expect('start = [a-d]\n').toParseAs(classGrammar([["a", "d"]], "[a-d]"));
}); });
/* Canonical classCharacterRange is "a-d". */ /* Canonical ClassCharacterRange is "a-d". */
it("parses classCharacterRange", function() { it("parses ClassCharacterRange", function() {
expect('start = [a-d]').toParseAs(classGrammar([["a", "d"]], "[a-d]")); expect('start = [a-d]').toParseAs(classGrammar([["a", "d"]], "[a-d]"));
expect('start = [a-a]').toParseAs(classGrammar([["a", "a"]], "[a-a]")); expect('start = [a-a]').toParseAs(classGrammar([["a", "a"]], "[a-a]"));
@ -459,13 +459,13 @@ describe("PEG.js grammar parser", function() {
}); });
}); });
/* Canonical classCharacter is "a". */ /* Canonical ClassCharacter is "a". */
it("parses classCharacter", function() { it("parses ClassCharacter", function() {
expect('start = [a]').toParseAs(classGrammar(["a"], "[a]")); expect('start = [a]').toParseAs(classGrammar(["a"], "[a]"));
}); });
/* Canonical bracketDelimitedCharacter is "a". */ /* Canonical BracketDelimitedCharacter is "a". */
it("parses bracketDelimitedCharacter", function() { it("parses BracketDelimitedCharacter", function() {
expect('start = [a]' ).toParseAs(classGrammar(["a"], "[a]")); expect('start = [a]' ).toParseAs(classGrammar(["a"], "[a]"));
expect('start = [\\n]' ).toParseAs(classGrammar(["\n"], "[\\n]")); expect('start = [\\n]' ).toParseAs(classGrammar(["\n"], "[\\n]"));
expect('start = [\\0]' ).toParseAs(classGrammar(["\x00"], "[\\0]")); expect('start = [\\0]' ).toParseAs(classGrammar(["\x00"], "[\\0]"));
@ -474,8 +474,8 @@ describe("PEG.js grammar parser", function() {
expect('start = [\\\n]' ).toParseAs(classGrammar([""], "[\\\n]")); expect('start = [\\\n]' ).toParseAs(classGrammar([""], "[\\\n]"));
}); });
/* Canonical simpleBracketDelimiedCharacter is "a". */ /* Canonical SimpleBracketDelimiedCharacter is "a". */
it("parses simpleBracketDelimitedCharacter", function() { it("parses SimpleBracketDelimitedCharacter", function() {
expect('start = [a]').toParseAs(classGrammar(["a"], "[a]")); expect('start = [a]').toParseAs(classGrammar(["a"], "[a]"));
expect('start = []]' ).toFailToParse(); expect('start = []]' ).toFailToParse();
@ -483,8 +483,8 @@ describe("PEG.js grammar parser", function() {
expect('start = [\n]').toFailToParse(); expect('start = [\n]').toFailToParse();
}); });
/* Canonical simpleEscapeSequence is "\\n". */ /* Canonical SimpleEscapeSequence is "\\n". */
it("parses simpleEscapeSequence", function() { it("parses SimpleEscapeSequence", function() {
expect('start = "\\b"').toParseAs(literalGrammar("\b")); expect('start = "\\b"').toParseAs(literalGrammar("\b"));
expect('start = "\\f"').toParseAs(literalGrammar("\f")); expect('start = "\\f"').toParseAs(literalGrammar("\f"));
expect('start = "\\n"').toParseAs(literalGrammar("\n")); expect('start = "\\n"').toParseAs(literalGrammar("\n"));
@ -498,26 +498,26 @@ describe("PEG.js grammar parser", function() {
expect('start = "\\u"').toFailToParse(); expect('start = "\\u"').toFailToParse();
}); });
/* Canonical zeroEscapeSequence is "\\0". */ /* Canonical ZeroEscapeSequence is "\\0". */
it("parses zeroEscapeSequence", function() { it("parses ZeroEscapeSequence", function() {
expect('start = "\\0"').toParseAs(literalGrammar("\x00")); expect('start = "\\0"').toParseAs(literalGrammar("\x00"));
expect('start = "\\00"').toFailToParse(); expect('start = "\\00"').toFailToParse();
expect('start = "\\09"').toFailToParse(); expect('start = "\\09"').toFailToParse();
}); });
/* Canonical hexEscapeSequence is "\\xFF". */ /* Canonical HexEscapeSequence is "\\xFF". */
it("parses hexEscapeSequence", function() { it("parses HexEscapeSequence", function() {
expect('start = "\\xFF"').toParseAs(literalGrammar("\xFF")); expect('start = "\\xFF"').toParseAs(literalGrammar("\xFF"));
}); });
/* Canonical unicodeEscapeSequence is "\\uFFFF". */ /* Canonical UnicodeEscapeSequence is "\\uFFFF". */
it("parses unicodeEscapeSequence", function() { it("parses UnicodeEscapeSequence", function() {
expect('start = "\\uFFFF"').toParseAs(literalGrammar("\uFFFF")); expect('start = "\\uFFFF"').toParseAs(literalGrammar("\uFFFF"));
}); });
/* Canonical eolEscapeSequence is "\\\n". */ /* Canonical EOLEscapeSequence is "\\\n". */
it("parses eolEscapeSequence", function() { it("parses EOLEscapeSequence", function() {
expect('start = "\\\n"' ).toParseAs(literalGrammar("")); expect('start = "\\\n"' ).toParseAs(literalGrammar(""));
}); });
@ -532,21 +532,21 @@ describe("PEG.js grammar parser", function() {
expect('start = "abcd"' ).toParseAs(trivialGrammar); expect('start = "abcd"' ).toParseAs(trivialGrammar);
}); });
// Canonical comment is "/* comment */". // Canonical Comment is "/* comment */".
it("parses comment", function() { it("parses Comment", function() {
expect('start =// comment\n"abcd"' ).toParseAs(trivialGrammar); expect('start =// comment\n"abcd"' ).toParseAs(trivialGrammar);
expect('start =/* comment */"abcd"').toParseAs(trivialGrammar); expect('start =/* comment */"abcd"').toParseAs(trivialGrammar);
}); });
/* Canonical singleLineComment is "// comment". */ /* Canonical SingleLineComment is "// comment". */
it("parses singleLineComment", function() { it("parses SingleLineComment", function() {
expect('start =//\n"abcd"' ).toParseAs(trivialGrammar); expect('start =//\n"abcd"' ).toParseAs(trivialGrammar);
expect('start =//a\n"abcd"' ).toParseAs(trivialGrammar); expect('start =//a\n"abcd"' ).toParseAs(trivialGrammar);
expect('start =//aaa\n"abcd"').toParseAs(trivialGrammar); expect('start =//aaa\n"abcd"').toParseAs(trivialGrammar);
}); });
// Canonical multiLineComment is "/* comment */". // Canonical MultiLineComment is "/* comment */".
it("parses multiLineComment", function() { it("parses MultiLineComment", function() {
expect('start =/**/"abcd"' ).toParseAs(trivialGrammar); expect('start =/**/"abcd"' ).toParseAs(trivialGrammar);
expect('start =/*a*/"abcd"' ).toParseAs(trivialGrammar); expect('start =/*a*/"abcd"' ).toParseAs(trivialGrammar);
expect('start =/*aaa*/"abcd"').toParseAs(trivialGrammar); expect('start =/*aaa*/"abcd"').toParseAs(trivialGrammar);
@ -555,8 +555,8 @@ describe("PEG.js grammar parser", function() {
expect('start =/**/*/"abcd"').toFailToParse(); expect('start =/**/*/"abcd"').toFailToParse();
}); });
/* Canonical eol is "\n". */ /* Canonical EOL is "\n". */
it("parses eol", function() { it("parses EOL", function() {
expect('start =\n"abcd"' ).toParseAs(trivialGrammar); expect('start =\n"abcd"' ).toParseAs(trivialGrammar);
expect('start =\r\n"abcd"' ).toParseAs(trivialGrammar); expect('start =\r\n"abcd"' ).toParseAs(trivialGrammar);
expect('start =\r"abcd"' ).toParseAs(trivialGrammar); expect('start =\r"abcd"' ).toParseAs(trivialGrammar);
@ -564,16 +564,16 @@ describe("PEG.js grammar parser", function() {
expect('start =\u2029"abcd"').toParseAs(trivialGrammar); expect('start =\u2029"abcd"').toParseAs(trivialGrammar);
}); });
/* Canonical eolChar is "\n". */ /* Canonical EOLChar is "\n". */
it("parses eolChar", function() { it("parses EOLChar", function() {
expect('start =\n"abcd"' ).toParseAs(trivialGrammar); expect('start =\n"abcd"' ).toParseAs(trivialGrammar);
expect('start =\r"abcd"' ).toParseAs(trivialGrammar); expect('start =\r"abcd"' ).toParseAs(trivialGrammar);
expect('start =\u2028"abcd"').toParseAs(trivialGrammar); expect('start =\u2028"abcd"').toParseAs(trivialGrammar);
expect('start =\u2029"abcd"').toParseAs(trivialGrammar); expect('start =\u2029"abcd"').toParseAs(trivialGrammar);
}); });
/* Canonical whitespace is " ". */ /* Canonical Whitespace is " ". */
it("parses whitespace", function() { it("parses Whitespace", function() {
expect('start =\t"abcd"' ).toParseAs(trivialGrammar); expect('start =\t"abcd"' ).toParseAs(trivialGrammar);
expect('start =\x0B"abcd"' ).toParseAs(trivialGrammar); // no "\v" in IE expect('start =\x0B"abcd"' ).toParseAs(trivialGrammar); // no "\v" in IE
expect('start =\f"abcd"' ).toParseAs(trivialGrammar); expect('start =\f"abcd"' ).toParseAs(trivialGrammar);

@ -2,8 +2,8 @@
var utils = require("./utils"); var utils = require("./utils");
} }
grammar Grammar
= __ initializer:initializer? rules:rule+ { = __ initializer:Initializer? rules:Rule+ {
return { return {
type: "grammar", type: "grammar",
initializer: initializer, initializer: initializer,
@ -11,16 +11,16 @@ grammar
}; };
} }
initializer Initializer
= code:action semicolon? { = code:Action Semicolon? {
return { return {
type: "initializer", type: "initializer",
code: code code: code
}; };
} }
rule Rule
= name:identifier displayName:string? equals expression:expression semicolon? { = name:Identifier displayName:String? Equals expression:Expression Semicolon? {
return { return {
type: "rule", type: "rule",
name: name, name: name,
@ -34,11 +34,11 @@ rule
}; };
} }
expression Expression
= choice = Choice
choice Choice
= head:sequence tail:(slash sequence)* { = head:Sequence tail:(Slash Sequence)* {
if (tail.length > 0) { if (tail.length > 0) {
var alternatives = [head].concat(utils.map( var alternatives = [head].concat(utils.map(
tail, tail,
@ -53,8 +53,8 @@ choice
} }
} }
sequence Sequence
= elements:labeled+ code:action { = elements:Labeled+ code:Action {
var expression = elements.length !== 1 var expression = elements.length !== 1
? { ? {
type: "sequence", type: "sequence",
@ -67,7 +67,7 @@ sequence
code: code code: code
}; };
} }
/ elements:labeled+ { / elements:Labeled+ {
return elements.length !== 1 return elements.length !== 1
? { ? {
type: "sequence", type: "sequence",
@ -76,109 +76,109 @@ sequence
: elements[0]; : elements[0];
} }
labeled Labeled
= label:identifier colon expression:prefixed { = label:Identifier Colon expression:Prefixed {
return { return {
type: "labeled", type: "labeled",
label: label, label: label,
expression: expression expression: expression
}; };
} }
/ prefixed / Prefixed
prefixed Prefixed
= dollar expression:suffixed { = Dollar expression:Suffixed {
return { return {
type: "text", type: "text",
expression: expression expression: expression
}; };
} }
/ and code:action { / And code:Action {
return { return {
type: "semantic_and", type: "semantic_and",
code: code code: code
}; };
} }
/ and expression:suffixed { / And expression:Suffixed {
return { return {
type: "simple_and", type: "simple_and",
expression: expression expression: expression
}; };
} }
/ not code:action { / Not code:Action {
return { return {
type: "semantic_not", type: "semantic_not",
code: code code: code
}; };
} }
/ not expression:suffixed { / Not expression:Suffixed {
return { return {
type: "simple_not", type: "simple_not",
expression: expression expression: expression
}; };
} }
/ suffixed / Suffixed
suffixed Suffixed
= expression:primary question { = expression:Primary Question {
return { return {
type: "optional", type: "optional",
expression: expression expression: expression
}; };
} }
/ expression:primary star { / expression:Primary Star {
return { return {
type: "zero_or_more", type: "zero_or_more",
expression: expression expression: expression
}; };
} }
/ expression:primary plus { / expression:Primary Plus {
return { return {
type: "one_or_more", type: "one_or_more",
expression: expression expression: expression
}; };
} }
/ primary / Primary
primary Primary
= name:identifier !(string? equals) { = name:Identifier !(String? Equals) {
return { return {
type: "rule_ref", type: "rule_ref",
name: name name: name
}; };
} }
/ literal / Literal
/ class / Class
/ dot { return { type: "any" }; } / Dot { return { type: "any" }; }
/ lparen expression:expression rparen { return expression; } / Lparen expression:Expression Rparen { return expression; }
/* "Lexical" elements */ /* "Lexical" elements */
action "action" Action "action"
= braced:braced __ { return braced.substr(1, braced.length - 2); } = braced:Braced __ { return braced.substr(1, braced.length - 2); }
braced Braced
= $("{" (braced / nonBraceCharacters)* "}") = $("{" (Braced / NonBraceCharacters)* "}")
nonBraceCharacters NonBraceCharacters
= nonBraceCharacter+ = NonBraceCharacter+
nonBraceCharacter NonBraceCharacter
= [^{}] = [^{}]
equals = "=" __ { return "="; } Equals = "=" __ { return "="; }
colon = ":" __ { return ":"; } Colon = ":" __ { return ":"; }
semicolon = ";" __ { return ";"; } Semicolon = ";" __ { return ";"; }
slash = "/" __ { return "/"; } Slash = "/" __ { return "/"; }
and = "&" __ { return "&"; } And = "&" __ { return "&"; }
not = "!" __ { return "!"; } Not = "!" __ { return "!"; }
dollar = "$" __ { return "$"; } Dollar = "$" __ { return "$"; }
question = "?" __ { return "?"; } Question = "?" __ { return "?"; }
star = "*" __ { return "*"; } Star = "*" __ { return "*"; }
plus = "+" __ { return "+"; } Plus = "+" __ { return "+"; }
lparen = "(" __ { return "("; } Lparen = "(" __ { return "("; }
rparen = ")" __ { return ")"; } Rparen = ")" __ { return ")"; }
dot = "." __ { return "."; } Dot = "." __ { return "."; }
/* /*
* Modeled after ECMA-262, 5th ed., 7.6, but much simplified: * Modeled after ECMA-262, 5th ed., 7.6, but much simplified:
@ -198,15 +198,15 @@ dot = "." __ { return "."; }
* Contrary to ECMA 262, the "$" character is not valid because it serves other * Contrary to ECMA 262, the "$" character is not valid because it serves other
* purpose in the grammar. * purpose in the grammar.
*/ */
identifier "identifier" Identifier "identifier"
= chars:$((letter / "_") (letter / digit / "_")*) __ { return chars; } = chars:$((Letter / "_") (Letter / Digit / "_")*) __ { return chars; }
/* /*
* Modeled after ECMA-262, 5th ed., 7.8.4. (syntax & semantics, rules only * Modeled after ECMA-262, 5th ed., 7.8.4. (syntax & semantics, rules only
* vaguely). * vaguely).
*/ */
literal "literal" Literal "literal"
= value:(doubleQuotedString / singleQuotedString) flags:"i"? __ { = value:(DoubleQuotedString / SingleQuotedString) flags:"i"? __ {
return { return {
type: "literal", type: "literal",
value: value, value: value,
@ -214,40 +214,40 @@ literal "literal"
}; };
} }
string "string" String "string"
= string:(doubleQuotedString / singleQuotedString) __ { return string; } = string:(DoubleQuotedString / SingleQuotedString) __ { return string; }
doubleQuotedString DoubleQuotedString
= '"' chars:doubleQuotedCharacter* '"' { return chars.join(""); } = '"' chars:DoubleQuotedCharacter* '"' { return chars.join(""); }
doubleQuotedCharacter DoubleQuotedCharacter
= simpleDoubleQuotedCharacter = SimpleDoubleQuotedCharacter
/ simpleEscapeSequence / SimpleEscapeSequence
/ zeroEscapeSequence / ZeroEscapeSequence
/ hexEscapeSequence / HexEscapeSequence
/ unicodeEscapeSequence / UnicodeEscapeSequence
/ eolEscapeSequence / EOLEscapeSequence
simpleDoubleQuotedCharacter SimpleDoubleQuotedCharacter
= !('"' / "\\" / eolChar) char_:. { return char_; } = !('"' / "\\" / EOLChar) char_:. { return char_; }
singleQuotedString SingleQuotedString
= "'" chars:singleQuotedCharacter* "'" { return chars.join(""); } = "'" chars:SingleQuotedCharacter* "'" { return chars.join(""); }
singleQuotedCharacter SingleQuotedCharacter
= simpleSingleQuotedCharacter = SimpleSingleQuotedCharacter
/ simpleEscapeSequence / SimpleEscapeSequence
/ zeroEscapeSequence / ZeroEscapeSequence
/ hexEscapeSequence / HexEscapeSequence
/ unicodeEscapeSequence / UnicodeEscapeSequence
/ eolEscapeSequence / EOLEscapeSequence
simpleSingleQuotedCharacter SimpleSingleQuotedCharacter
= !("'" / "\\" / eolChar) char_:. { return char_; } = !("'" / "\\" / EOLChar) char_:. { return char_; }
class "character class" Class "character class"
= class_:( = class_:(
"[" inverted:"^"? parts:(classCharacterRange / classCharacter)* "]" flags:"i"? { "[" inverted:"^"? parts:(ClassCharacterRange / ClassCharacter)* "]" flags:"i"? {
return { return {
type: "class", type: "class",
parts: parts, parts: parts,
@ -260,8 +260,8 @@ class "character class"
__ __
{ return class_; } { return class_; }
classCharacterRange ClassCharacterRange
= begin:classCharacter "-" end:classCharacter { = begin:ClassCharacter "-" end:ClassCharacter {
if (begin.charCodeAt(0) > end.charCodeAt(0)) { if (begin.charCodeAt(0) > end.charCodeAt(0)) {
error("Invalid character range: " + text() + "."); error("Invalid character range: " + text() + ".");
} }
@ -269,22 +269,22 @@ classCharacterRange
return [begin, end]; return [begin, end];
} }
classCharacter ClassCharacter
= bracketDelimitedCharacter = BracketDelimitedCharacter
bracketDelimitedCharacter BracketDelimitedCharacter
= simpleBracketDelimitedCharacter = SimpleBracketDelimitedCharacter
/ simpleEscapeSequence / SimpleEscapeSequence
/ zeroEscapeSequence / ZeroEscapeSequence
/ hexEscapeSequence / HexEscapeSequence
/ unicodeEscapeSequence / UnicodeEscapeSequence
/ eolEscapeSequence / EOLEscapeSequence
simpleBracketDelimitedCharacter SimpleBracketDelimitedCharacter
= !("]" / "\\" / eolChar) char_:. { return char_; } = !("]" / "\\" / EOLChar) char_:. { return char_; }
simpleEscapeSequence SimpleEscapeSequence
= "\\" !(digit / "x" / "u" / eolChar) char_:. { = "\\" !(Digit / "x" / "u" / EOLChar) char_:. {
return char_ return char_
.replace("b", "\b") .replace("b", "\b")
.replace("f", "\f") .replace("f", "\f")
@ -294,62 +294,62 @@ simpleEscapeSequence
.replace("v", "\x0B"); // IE does not recognize "\v". .replace("v", "\x0B"); // IE does not recognize "\v".
} }
zeroEscapeSequence ZeroEscapeSequence
= "\\0" !digit { return "\x00"; } = "\\0" !Digit { return "\x00"; }
hexEscapeSequence HexEscapeSequence
= "\\x" digits:$(hexDigit hexDigit) { = "\\x" digits:$(HexDigit HexDigit) {
return String.fromCharCode(parseInt(digits, 16)); return String.fromCharCode(parseInt(digits, 16));
} }
unicodeEscapeSequence UnicodeEscapeSequence
= "\\u" digits:$(hexDigit hexDigit hexDigit hexDigit) { = "\\u" digits:$(HexDigit HexDigit HexDigit HexDigit) {
return String.fromCharCode(parseInt(digits, 16)); return String.fromCharCode(parseInt(digits, 16));
} }
eolEscapeSequence EOLEscapeSequence
= "\\" eol:eol { return ""; } = "\\" eol:EOL { return ""; }
digit Digit
= [0-9] = [0-9]
hexDigit HexDigit
= [0-9a-fA-F] = [0-9a-fA-F]
letter Letter
= lowerCaseLetter = LowerCaseLetter
/ upperCaseLetter / UpperCaseLetter
lowerCaseLetter LowerCaseLetter
= [a-z] = [a-z]
upperCaseLetter UpperCaseLetter
= [A-Z] = [A-Z]
__ = (whitespace / eol / comment)* __ = (Whitespace / EOL / Comment)*
/* Modeled after ECMA-262, 5th ed., 7.4. */ /* Modeled after ECMA-262, 5th ed., 7.4. */
comment "comment" Comment "comment"
= singleLineComment = SingleLineComment
/ multiLineComment / MultiLineComment
singleLineComment SingleLineComment
= "//" (!eolChar .)* = "//" (!EOLChar .)*
multiLineComment MultiLineComment
= "/*" (!"*/" .)* "*/" = "/*" (!"*/" .)* "*/"
/* Modeled after ECMA-262, 5th ed., 7.3. */ /* Modeled after ECMA-262, 5th ed., 7.3. */
eol "end of line" EOL "end of line"
= "\n" = "\n"
/ "\r\n" / "\r\n"
/ "\r" / "\r"
/ "\u2028" / "\u2028"
/ "\u2029" / "\u2029"
eolChar EOLChar
= [\n\r\u2028\u2029] = [\n\r\u2028\u2029]
/* Modeled after ECMA-262, 5th ed., 7.2. */ /* Modeled after ECMA-262, 5th ed., 7.2. */
whitespace "whitespace" Whitespace "whitespace"
= [ \t\v\f\u00A0\uFEFF\u1680\u180E\u2000-\u200A\u202F\u205F\u3000] = [ \t\v\f\u00A0\uFEFF\u1680\u180E\u2000-\u200A\u202F\u205F\u3000]

Loading…
Cancel
Save