Browse Source

PEG.js grammar: More JavaScript-like initializer/rule separation

Initializer and rules are now separated in a similar way as JavaScript
statements -- either by a semicolon or a line terminator, possibly with
whitespace and comments mixed in.

One consequence is that the grammars like this are now illegal:

  foo = "a" bar = "b"

A semicolon needs to be inserted between the rules:

  foo = "a";bar = "b"

I consider this a good change as the now-illegal syntax was somewhat
confusing.
redux
David Majda 8 years ago
committed by David Majda
parent
commit
27c2d26203
  1. 1568
      lib/parser.js
  2. 36
      spec/parser.spec.js
  3. 20
      src/parser.pegjs

1568
lib/parser.js
File diff suppressed because it is too large
View File

36
spec/parser.spec.js

@ -181,7 +181,7 @@ describe("PEG.js grammar parser", function() {
initializer: null,
rules: [ruleA]
});
expect('{ code } a = "abcd"').toParseAs({
expect('{ code }; a = "abcd"').toParseAs({
type: "grammar",
initializer: { type: "initializer", code: " code " },
rules: [ruleA]
@ -200,8 +200,7 @@ describe("PEG.js grammar parser", function() {
code: " code "
});
expect('{ code } start = "abcd"' ).toParseAs(grammar);
expect('{ code }\n; start = "abcd"').toParseAs(grammar);
expect('{ code }; start = "abcd"' ).toParseAs(grammar);
});
/* Canonical Rule is "a: \"abcd\"". */
@ -382,6 +381,16 @@ describe("PEG.js grammar parser", function() {
expect('start =/**/*/"abcd"').toFailToParse();
});
// Canonical MultiLineCommentNoLineTerminator is "/* comment */".
it("parses MultiLineCommentNoLineTerminator", function() {
expect('start = "abcd"/**/\r\n' ).toParseAs(trivialGrammar);
expect('start = "abcd"/*a*/\r\n' ).toParseAs(trivialGrammar);
expect('start = "abcd"/*aaa*/\r\n').toParseAs(trivialGrammar);
expect('{ code }/**/*/\r\nstart = "abcd"').toFailToParse();
expect('{ code }/*\n*/\r\nstart = "abcd"').toFailToParse();
});
/* Canonical SingleLineComment is "// comment". */
it("parses SingleLineComment", function() {
expect('start =//\n"abcd"' ).toParseAs(trivialGrammar);
@ -593,4 +602,25 @@ describe("PEG.js grammar parser", function() {
expect('start =/* comment */"abcd"').toParseAs(trivialGrammar);
expect('start = "abcd"' ).toParseAs(trivialGrammar);
});
/* Canonical _ is " ". */
it("parses _", function() {
expect('start = "abcd"\r\n' ).toParseAs(trivialGrammar);
expect('start = "abcd" \r\n' ).toParseAs(trivialGrammar);
expect('start = "abcd"/* comment */\r\n').toParseAs(trivialGrammar);
expect('start = "abcd" \r\n' ).toParseAs(trivialGrammar);
});
/* Canonical EOS is ";". */
it("parses EOS", function() {
expect('start = "abcd"\n;' ).toParseAs(trivialGrammar);
expect('start = "abcd" \r\n' ).toParseAs(trivialGrammar);
expect('start = "abcd" // comment\r\n').toParseAs(trivialGrammar);
expect('start = "abcd"\n' ).toParseAs(trivialGrammar);
});
/* Canonical EOF is the end of input. */
it("parses EOS", function() {
expect('start = "abcd"\n').toParseAs(trivialGrammar);
});
});

20
src/parser.pegjs

@ -41,7 +41,7 @@ Grammar
}
Initializer
= code:CodeBlock (__ ";")? {
= code:CodeBlock EOS {
return {
type: "initializer",
code: code
@ -52,7 +52,7 @@ Rule
= name:IdentifierName __
displayName:(StringLiteral __)?
"=" __
expression:Expression (__ ";")? {
expression:Expression EOS {
return {
type: "rule",
name: name,
@ -200,6 +200,9 @@ Comment "comment"
MultiLineComment
= "/*" (!"*/" SourceCharacter)* "*/"
MultiLineCommentNoLineTerminator
= "/*" (!("*/" / LineTerminator) SourceCharacter)* "*/"
SingleLineComment
= "//" (!LineTerminator SourceCharacter)*
@ -504,3 +507,16 @@ WithToken = "with" !IdentifierPart
__
= (WhiteSpace / LineTerminatorSequence / Comment)*
_
= (WhiteSpace / MultiLineCommentNoLineTerminator)*
/* Automatic Semicolon Insertion */
EOS
= __ ";"
/ _ SingleLineComment? LineTerminatorSequence
/ __ EOF
EOF
= !.
Loading…
Cancel
Save