diff --git a/examples/arithmetics.pegjs b/examples/arithmetics.pegjs index 80c2afd..be7fffc 100644 --- a/examples/arithmetics.pegjs +++ b/examples/arithmetics.pegjs @@ -3,15 +3,20 @@ * "2*(3+4)". The parser generated from this grammar then computes their value. */ -start = additive +start + = additive -additive = multiplicative "+" additive { return $1 + $3; } - / multiplicative +additive + = multiplicative "+" additive { return $1 + $3; } + / multiplicative -multiplicative = primary "*" multiplicative { return $1 * $3; } - / primary +multiplicative + = primary "*" multiplicative { return $1 * $3; } + / primary -primary = integer - / "(" additive ")" { return $2; } +primary + = integer + / "(" additive ")" { return $2; } -integer "integer" = [0-9]+ { return parseInt($1.join(""), 10); } +integer "integer" + = [0-9]+ { return parseInt($1.join(""), 10); } diff --git a/examples/css.pegjs b/examples/css.pegjs index 3767b4c..18fe7b8 100644 --- a/examples/css.pegjs +++ b/examples/css.pegjs @@ -14,73 +14,79 @@ /* ===== Syntactical Elements ===== */ -start = stylesheet comment* { return $1; } - -stylesheet = - (CHARSET_SYM STRING ";")? (S / CDO / CDC)* - (import (CDO S* / CDC S*)*)* - ((ruleset / media / page) (CDO S* / CDC S*)*)* - { - var imports = []; - for (var i = 0; i < $3.length; i++) { - imports.push($3[i][0]); +start + = stylesheet comment* { return $1; } + +stylesheet + = (CHARSET_SYM STRING ";")? (S / CDO / CDC)* + (import (CDO S* / CDC S*)*)* + ((ruleset / media / page) (CDO S* / CDC S*)*)* { + var imports = []; + for (var i = 0; i < $3.length; i++) { + imports.push($3[i][0]); + } + + var rules = []; + for (i = 0; i < $4.length; i++) { + rules.push($4[i][0]); + } + + return { + type: "stylesheet", + charset: $1 !== "" ? $1[1] : null, + imports: imports, + rules: rules + }; } - var rules = []; - for (i = 0; i < $4.length; i++) { - rules.push($4[i][0]); +import + = IMPORT_SYM S* (STRING / URI) S* media_list? ";" S* { + return { + type: "import_rule", + href: $3, + media: $5 !== "" ? $5 : [] + }; } - return { - type: "stylesheet", - charset: $1 !== "" ? $1[1] : null, - imports: imports, - rules: rules - }; - } - -import = IMPORT_SYM S* (STRING / URI) S* media_list? ";" S* { - return { - type: "import_rule", - href: $3, - media: $5 !== "" ? $5 : [] - }; -} - -media = MEDIA_SYM S* media_list "{" S* ruleset* "}" S* { - return { - type: "media_rule", - media: $3, - rules: $6 - }; -} - -media_list = medium ("," S* medium)* { - var result = [$1]; - for (var i = 0; i < $2.length; i++) { - result.push($2[i][2]); - } - return result; -} - -medium = IDENT S* { return $1; } - -page = PAGE_SYM S* pseudo_page? "{" S* declaration? (";" S* declaration?)* "}" S* { - var declarations = $6 !== "" ? [$6] : []; - for (var i = 0; i < $7.length; i++) { - if ($7[i][2] !== "") { - declarations.push($7[i][2]); +media + = MEDIA_SYM S* media_list "{" S* ruleset* "}" S* { + return { + type: "media_rule", + media: $3, + rules: $6 + }; } - } - return { - type: "page_rule", - qualifier: $3 !== "" ? $3 : null, - declarations: declarations - }; -} +media_list + = medium ("," S* medium)* { + var result = [$1]; + for (var i = 0; i < $2.length; i++) { + result.push($2[i][2]); + } + return result; + } -pseudo_page = ":" IDENT S* { return $2; } +medium + = IDENT S* { return $1; } + +page + = PAGE_SYM S* pseudo_page? "{" S* declaration? (";" S* declaration?)* "}" S* { + var declarations = $6 !== "" ? [$6] : []; + for (var i = 0; i < $7.length; i++) { + if ($7[i][2] !== "") { + declarations.push($7[i][2]); + } + } + + return { + type: "page_rule", + qualifier: $3 !== "" ? $3 : null, + declarations: declarations + }; + } + +pseudo_page + = ":" IDENT S* { return $2; } operator = "/" S* { return $1; } @@ -90,29 +96,34 @@ combinator = "+" S* { return $1; } / ">" S* { return $1; } -unary_operator = "+" / "-" +unary_operator + = "+" + / "-" -property = IDENT S* { return $1; } +property + = IDENT S* { return $1; } -ruleset = selector ("," S* selector)* "{" S* declaration? (";" S* declaration?)* "}" S* { - var selectors = [$1]; - for (var i = 0; i < $2.length; i++) { - selectors.push($2[i][2]); - } +ruleset + = selector ("," S* selector)* + "{" S* declaration? (";" S* declaration?)* "}" S* { + var selectors = [$1]; + for (var i = 0; i < $2.length; i++) { + selectors.push($2[i][2]); + } - var declarations = $5 !== "" ? [$5] : []; - for (i = 0; i < $6.length; i++) { - if ($6[i][2] !== "") { - declarations.push($6[i][2]); - } - } + var declarations = $5 !== "" ? [$5] : []; + for (i = 0; i < $6.length; i++) { + if ($6[i][2] !== "") { + declarations.push($6[i][2]); + } + } - return { - type: "ruleset", - selectors: selectors, - declarations: declarations - }; -} + return { + type: "ruleset", + selectors: selectors, + declarations: declarations + }; + } selector = simple_selector S* combinator selector { @@ -160,66 +171,71 @@ simple_selector }; } -class = "." IDENT { return { type: "class_selector", "class": $2 }; } - -element_name = IDENT / '*' - -attrib = "[" S* IDENT S* (('=' / INCLUDES / DASHMATCH) S* (IDENT / STRING) S*)? "]" { - return { - type: "attribute_selector", - attribute: $3, - operator: $5 !== "" ? $5[0] : null, - value: $5 !== "" ? $5[2] : null - }; -} - -pseudo = - ":" - ( - FUNCTION S* (IDENT S*)? ")" { - return { - type: "function", - name: $1, - params: $3 !== "" ? [$3[0]] : [] +class + = "." IDENT { return { type: "class_selector", "class": $2 }; } + +element_name + = IDENT / '*' + +attrib + = "[" S* IDENT S* (('=' / INCLUDES / DASHMATCH) S* (IDENT / STRING) S*)? "]" { + return { + type: "attribute_selector", + attribute: $3, + operator: $5 !== "" ? $5[0] : null, + value: $5 !== "" ? $5[2] : null + }; + } + +pseudo + = ":" + ( + FUNCTION S* (IDENT S*)? ")" { + return { + type: "function", + name: $1, + params: $3 !== "" ? [$3[0]] : [] + }; + } + / IDENT + ) { + /* + * The returned object has somewhat vague property names and values because + * the rule matches both pseudo-classes and pseudo-elements (they look the + * same at the syntactic level). + */ + return { + type: "pseudo_selector", + value: $2 + }; + } + +declaration + = property ":" S* expr prio? { + return { + type: "declaration", + property: $1, + expression: $4, + important: $5 !== "" ? true : false + }; + } + +prio + = IMPORTANT_SYM S* + +expr + = term (operator? term)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "expression", + operator: $2[i][0], + left: result, + right: $2[i][1] }; } - / IDENT - ) - { - /* - * The returned object has somewhat vague property names and values because - * the rule matches both pseudo-classes and pseudo-elements (they look the - * same at the syntactic level). - */ - return { - type: "pseudo_selector", - value: $2 - }; - } - -declaration = property ":" S* expr prio? { - return { - type: "declaration", - property: $1, - expression: $4, - important: $5 !== "" ? true : false - }; -} - -prio = IMPORTANT_SYM S* - -expr = term (operator? term)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "expression", - operator: $2[i][0], - left: result, - right: $2[i][1] - }; - } - return result; -} + return result; + } term = unary_operator? @@ -239,69 +255,127 @@ term / STRING S* { return { type: "string", value: $1 }; } / IDENT S* { return { type: "ident", value: $1 }; } -function = FUNCTION S* expr ")" S* { - return { - type: "function", - name: $1, - params: $3 - }; -} +function + = FUNCTION S* expr ")" S* { + return { + type: "function", + name: $1, + params: $3 + }; + } -hexcolor = HASH S* { return { type: "hexcolor", value: $1}; } +hexcolor + = HASH S* { return { type: "hexcolor", value: $1}; } /* ===== Lexical Elements ===== */ /* Macros */ -h = [0-9a-fA-F] -nonascii = [\x80-\xFF] -unicode = "\\" h h? h? h? h? h? ("\r\n" / [ \t\r\n\f])? { - return String.fromCharCode(parseInt("0x" + $2 + $3 + $4 + $5 + $6 + $7)); - } -escape = unicode / "\\" [^\r\n\f0-9a-fA-F] { return $2; } -nmstart = [_a-zA-Z] / nonascii / escape -nmchar = [_a-zA-Z0-9-] / nonascii / escape -integer = [0-9]+ { return parseInt($1.join("")); } -float = [0-9]* "." [0-9]+ { return parseFloat($1.join("") + $2 + $3.join("")); } -string1 = '"' ([^\n\r\f\\"] / "\\" nl { return $2 } / escape)* '"' { return $2.join(""); } -string2 = "'" ([^\n\r\f\\'] / "\\" nl { return $2 } / escape)* "'" { return $2.join(""); } - -comment = "/*" [^*]* "*"+ ([^/*] [^*]* "*"+)* "/" -ident = "-"? nmstart nmchar* { return $1 + $2 + $3.join(""); } -name = nmchar+ { return $1.join(""); } -num = float / integer -string = string1 / string2 -url = ([!#$%&*-~] / nonascii / escape)* { return $1.join(""); } -s = [ \t\r\n\f]+ -w = s? -nl = "\n" / "\r\n" / "\r" / "\f" +h + = [0-9a-fA-F] + +nonascii + = [\x80-\xFF] + +unicode + = "\\" h h? h? h? h? h? ("\r\n" / [ \t\r\n\f])? { + return String.fromCharCode(parseInt("0x" + $2 + $3 + $4 + $5 + $6 + $7)); + } + +escape + = unicode + / "\\" [^\r\n\f0-9a-fA-F] { return $2; } + +nmstart + = [_a-zA-Z] + / nonascii + / escape + +nmchar + = [_a-zA-Z0-9-] + / nonascii + / escape + +integer + = [0-9]+ { return parseInt($1.join("")); } + +float + = [0-9]* "." [0-9]+ { return parseFloat($1.join("") + $2 + $3.join("")); } + +string1 + = '"' ([^\n\r\f\\"] / "\\" nl { return $2 } / escape)* '"' { + return $2.join(""); + } + +string2 + = "'" ([^\n\r\f\\'] / "\\" nl { return $2 } / escape)* "'" { + return $2.join(""); + } + +comment + = "/*" [^*]* "*"+ ([^/*] [^*]* "*"+)* "/" + +ident + = "-"? nmstart nmchar* { return $1 + $2 + $3.join(""); } + +name + = nmchar+ { return $1.join(""); } + +num + = float + / integer + +string + = string1 + / string2 + +url + = ([!#$%&*-~] / nonascii / escape)* { return $1.join(""); } + +s + = [ \t\r\n\f]+ + +w + = s? + +nl + = "\n" + / "\r\n" + / "\r" + / "\f" A = [aA] / "\\" "0"? "0"? "0"? "0"? "41" ("\r\n" / [ \t\r\n\f])? { return "A"; } / "\\" "0"? "0"? "0"? "0"? "61" ("\r\n" / [ \t\r\n\f])? { return "a"; } + C = [cC] / "\\" "0"? "0"? "0"? "0"? "43" ("\r\n" / [ \t\r\n\f])? { return "C"; } / "\\" "0"? "0"? "0"? "0"? "63" ("\r\n" / [ \t\r\n\f])? { return "c"; } + D = [dD] / "\\" "0"? "0"? "0"? "0"? "44" ("\r\n" / [ \t\r\n\f])? { return "D"; } / "\\" "0"? "0"? "0"? "0"? "64" ("\r\n" / [ \t\r\n\f])? { return "d"; } + E = [eE] / "\\" "0"? "0"? "0"? "0"? "45" ("\r\n" / [ \t\r\n\f])? { return "E"; } / "\\" "0"? "0"? "0"? "0"? "65" ("\r\n" / [ \t\r\n\f])? { return "e"; } + G = [gG] / "\\" "0"? "0"? "0"? "0"? "47" ("\r\n" / [ \t\r\n\f])? { return "G"; } / "\\" "0"? "0"? "0"? "0"? "67" ("\r\n" / [ \t\r\n\f])? { return "g"; } / "\\" [gG] { return $2; } + H = [hH] / "\\" "0"? "0"? "0"? "0"? "48" ("\r\n" / [ \t\r\n\f])? { return "H"; } / "\\" "0"? "0"? "0"? "0"? "68" ("\r\n" / [ \t\r\n\f])? { return "h"; } / "\\" [hH] { return $2; } + I = [iI] / "\\" "0"? "0"? "0"? "0"? "49" ("\r\n" / [ \t\r\n\f])? { return "I"; } @@ -313,56 +387,67 @@ K / "\\" "0"? "0"? "0"? "0"? "4" [bB] ("\r\n" / [ \t\r\n\f])? { return "K"; } / "\\" "0"? "0"? "0"? "0"? "6" [bB] ("\r\n" / [ \t\r\n\f])? { return "k"; } / "\\" [kK] { return $2; } + L = [lL] / "\\" "0"? "0"? "0"? "0"? "4" [cC] ("\r\n" / [ \t\r\n\f])? { return "L"; } / "\\" "0"? "0"? "0"? "0"? "6" [cC] ("\r\n" / [ \t\r\n\f])? { return "l"; } / "\\" [lL] { return $2; } + M = [mM] / "\\" "0"? "0"? "0"? "0"? "4" [dD] ("\r\n" / [ \t\r\n\f])? { return "M"; } / "\\" "0"? "0"? "0"? "0"? "6" [dD] ("\r\n" / [ \t\r\n\f])? { return "m"; } / "\\" [mM] { return $2; } + N = [nN] / "\\" "0"? "0"? "0"? "0"? "4" [eE] ("\r\n" / [ \t\r\n\f])? { return "N"; } / "\\" "0"? "0"? "0"? "0"? "6" [eE] ("\r\n" / [ \t\r\n\f])? { return "n"; } / "\\" [nN] { return $2; } + O = [oO] / "\\" "0"? "0"? "0"? "0"? "4" [fF] ("\r\n" / [ \t\r\n\f])? { return "O"; } / "\\" "0"? "0"? "0"? "0"? "6" [fF] ("\r\n" / [ \t\r\n\f])? { return "o"; } / "\\" [oO] { return $2; } + P = [pP] / "\\" "0"? "0"? "0"? "0"? "50" ("\r\n" / [ \t\r\n\f])? { return "P"; } / "\\" "0"? "0"? "0"? "0"? "70" ("\r\n" / [ \t\r\n\f])? { return "p"; } / "\\" [pP] { return $2; } + R = [rR] / "\\" "0"? "0"? "0"? "0"? "52" ("\r\n" / [ \t\r\n\f])? { return "R"; } / "\\" "0"? "0"? "0"? "0"? "72" ("\r\n" / [ \t\r\n\f])? { return "r"; } / "\\" [rR] { return $2; } + S_ = [sS] / "\\" "0"? "0"? "0"? "0"? "53" ("\r\n" / [ \t\r\n\f])? { return "S"; } / "\\" "0"? "0"? "0"? "0"? "73" ("\r\n" / [ \t\r\n\f])? { return "s"; } / "\\" [sS] { return $2; } + T = [tT] / "\\" "0"? "0"? "0"? "0"? "54" ("\r\n" / [ \t\r\n\f])? { return "T"; } / "\\" "0"? "0"? "0"? "0"? "74" ("\r\n" / [ \t\r\n\f])? { return "t"; } / "\\" [tT] { return $2; } + U = [uU] / "\\" "0"? "0"? "0"? "0"? "55" ("\r\n" / [ \t\r\n\f])? { return "U"; } / "\\" "0"? "0"? "0"? "0"? "75" ("\r\n" / [ \t\r\n\f])? { return "u"; } / "\\" [uU] { return $2; } + X = [xX] / "\\" "0"? "0"? "0"? "0"? "58" ("\r\n" / [ \t\r\n\f])? { return "X"; } / "\\" "0"? "0"? "0"? "0"? "78" ("\r\n" / [ \t\r\n\f])? { return "x"; } / "\\" [xX] { return $2; } + Z = [zZ] / "\\" "0"? "0"? "0"? "0"? "5" [aA] ("\r\n" / [ \t\r\n\f])? { return "Z"; } @@ -371,36 +456,77 @@ Z /* Tokens */ -S "whitespace" = comment* s +S "whitespace" + = comment* s + +CDO "" + = comment* "-->" + +INCLUDES "~=" + = comment* "~=" + +DASHMATCH "|=" + = comment* "|=" -CDO "" = comment* "-->" -INCLUDES "~=" = comment* "~=" -DASHMATCH "|=" = comment* "|=" +STRING "string" + = comment* string { return $2; } -STRING "string" = comment* string { return $2; } +IDENT "identifier" + = comment* ident { return $2; } -IDENT "identifier" = comment* ident { return $2; } +HASH "hash" + = comment* "#" name { return $2 + $3; } -HASH "hash" = comment* "#" name { return $2 + $3; } +IMPORT_SYM "@import" + = comment* "@" I M P O R T + +PAGE_SYM "@page" + = comment* "@" P A G E + +MEDIA_SYM "@media" + = comment* "@" M E D I A + +CHARSET_SYM "@charset" + = comment* "@charset " -IMPORT_SYM "@import" = comment* "@" I M P O R T -PAGE_SYM "@page" = comment* "@" P A G E -MEDIA_SYM "@media" = comment* "@" M E D I A -CHARSET_SYM "@charset" = comment* "@charset " /* Note: We replace "w" with "s" here to avoid infinite recursion. */ -IMPORTANT_SYM "!important" = comment* "!" (s / comment)* I M P O R T A N T { return "!important"; } +IMPORTANT_SYM "!important" + = comment* "!" (s / comment)* I M P O R T A N T { return "!important"; } + +EMS "length" + = comment* num E M { return $2 + $3 + $4; } + +EXS "length" + = comment* num E X { return $2 + $3 + $4; } + +LENGTH "length" + = comment* num (P X / C M / M M / I N / P T / P C) { + return $2 + $3.join(""); + } + +ANGLE "angle" + = comment* num (D E G / R A D / G R A D) { return $2 + $3.join(""); } + +TIME "time" + = comment* num (M S_ { return $1 + $2; } / S_) { return $2 + $3; } + +FREQ "frequency" + = comment* num (H Z / K H Z) { return $2 + $3.join(""); } + +DIMENSION "dimension" + = comment* num ident { return $2 + $3; } + +PERCENTAGE "percentage" + = comment* num "%" { return $2 + $3; } -EMS "length" = comment* num E M { return $2 + $3 + $4; } -EXS "length" = comment* num E X { return $2 + $3 + $4; } -LENGTH "length" = comment* num (P X / C M / M M / I N / P T / P C) { return $2 + $3.join(""); } -ANGLE "angle" = comment* num (D E G / R A D / G R A D) { return $2 + $3.join(""); } -TIME "time" = comment* num (M S_ { return $1 + $2; } / S_) { return $2 + $3; } -FREQ "frequency" = comment* num (H Z / K H Z) { return $2 + $3.join(""); } -DIMENSION "dimension" = comment* num ident { return $2 + $3; } -PERCENTAGE "percentage" = comment* num "%" { return $2 + $3; } -NUMBER "number" = comment* num { return $2; } +NUMBER "number" + = comment* num { return $2; } -URI "uri" = comment* U R L "(" w (string / url) w ")" { return $7; } +URI "uri" + = comment* U R L "(" w (string / url) w ")" { return $7; } -FUNCTION "function" = comment* ident "(" { return $2; } +FUNCTION "function" + = comment* ident "(" { return $2; } diff --git a/examples/javascript.pegjs b/examples/javascript.pegjs index 5704d11..838e9ff 100644 --- a/examples/javascript.pegjs +++ b/examples/javascript.pegjs @@ -45,15 +45,20 @@ * grammar correctly. */ -start = __ Program __ { return $2; } +start + = __ Program __ { return $2; } /* ===== A.1 Lexical Grammar ===== */ -SourceCharacter = . +SourceCharacter + = . -WhiteSpace "whitespace" = [\t\v\f \u00A0\uFEFF] / Zs +WhiteSpace "whitespace" + = [\t\v\f \u00A0\uFEFF] + / Zs -LineTerminator = [\n\r\u2028\u2029] +LineTerminator + = [\n\r\u2028\u2029] LineTerminatorSequence "end of line" = "\n" @@ -66,17 +71,20 @@ Comment "comment" = MultiLineComment / SingleLineComment -MultiLineComment = "/*" (!"*/" SourceCharacter)* "*/" +MultiLineComment + = "/*" (!"*/" SourceCharacter)* "*/" -MultiLineCommentNoLineTerminator = "/*" (!("*/" / LineTerminator) SourceCharacter)* "*/" +MultiLineCommentNoLineTerminator + = "/*" (!("*/" / LineTerminator) SourceCharacter)* "*/" -SingleLineComment = "//" (!LineTerminator SourceCharacter)* +SingleLineComment + = "//" (!LineTerminator SourceCharacter)* -Identifier "identifier" = !ReservedWord IdentifierName { return $2; } +Identifier "identifier" + = !ReservedWord IdentifierName { return $2; } -IdentifierName "identifier" = IdentifierStart IdentifierPart* { - return $1 + $2.join(""); -} +IdentifierName "identifier" + = IdentifierStart IdentifierPart* { return $1 + $2.join(""); } IdentifierStart = UnicodeLetter @@ -92,58 +100,72 @@ IdentifierPart / "\u200C" { return "\u200C"; } // zero-width non-joiner / "\u200D" { return "\u200D"; } // zero-width joiner -UnicodeLetter = Lu / Ll / Lt / Lm / Lo / Nl - -UnicodeCombiningMark = Mn / Mc - -UnicodeDigit = Nd - -UnicodeConnectorPunctuation = Pc - -ReservedWord = Keyword / FutureReservedWord / NullLiteral / BooleanLiteral - -Keyword = - ( - "break" - / "case" - / "catch" - / "continue" - / "debugger" - / "default" - / "delete" - / "do" - / "else" - / "finally" - / "for" - / "function" - / "if" - / "instanceof" - / "in" - / "new" - / "return" - / "switch" - / "this" - / "throw" - / "try" - / "typeof" - / "var" - / "void" - / "while" - / "with" - ) - !IdentifierPart - -FutureReservedWord = - ( - "class" - / "const" - / "enum" - / "export" - / "extends" - / "import" - / "super" - ) - !IdentifierPart +UnicodeLetter + = Lu + / Ll + / Lt + / Lm + / Lo + / Nl + +UnicodeCombiningMark + = Mn + / Mc + +UnicodeDigit + = Nd + +UnicodeConnectorPunctuation + = Pc + +ReservedWord + = Keyword + / FutureReservedWord + / NullLiteral + / BooleanLiteral + +Keyword + = ( + "break" + / "case" + / "catch" + / "continue" + / "debugger" + / "default" + / "delete" + / "do" + / "else" + / "finally" + / "for" + / "function" + / "if" + / "instanceof" + / "in" + / "new" + / "return" + / "switch" + / "this" + / "throw" + / "try" + / "typeof" + / "var" + / "void" + / "while" + / "with" + ) + !IdentifierPart + +FutureReservedWord + = ( + "class" + / "const" + / "enum" + / "export" + / "extends" + / "import" + / "super" + ) + !IdentifierPart /* * This rule contains an error in the specification: |RegularExpressionLiteral| @@ -156,15 +178,15 @@ Literal / StringLiteral { return { type: "StringLiteral", value: $1 }; } / RegularExpressionLiteral -NullLiteral = NullToken { return { type: "NullLiteral" }; } +NullLiteral + = NullToken { return { type: "NullLiteral" }; } BooleanLiteral = TrueToken { return { type: "BooleanLiteral", value: true }; } / FalseToken { return { type: "BooleanLiteral", value: false }; } -NumericLiteral "number" = (HexIntegerLiteral / DecimalLiteral) !IdentifierStart { - return $1; -} +NumericLiteral "number" + = (HexIntegerLiteral / DecimalLiteral) !IdentifierStart { return $1; } DecimalLiteral = DecimalIntegerLiteral "." DecimalDigits? ExponentPart? { @@ -177,31 +199,43 @@ DecimalLiteral return parseFloat($1 + $2); } -DecimalIntegerLiteral = "0" / NonZeroDigit DecimalDigits? { return $1 + $2; } +DecimalIntegerLiteral + = "0" / NonZeroDigit DecimalDigits? { return $1 + $2; } -DecimalDigits = DecimalDigit+ { return $1.join(""); } +DecimalDigits + = DecimalDigit+ { return $1.join(""); } -DecimalDigit = [0-9] +DecimalDigit + = [0-9] -NonZeroDigit = [1-9] +NonZeroDigit + = [1-9] -ExponentPart = ExponentIndicator SignedInteger { return $1 + $2; } +ExponentPart + = ExponentIndicator SignedInteger { return $1 + $2; } -ExponentIndicator = [eE] +ExponentIndicator + = [eE] -SignedInteger = [-+]? DecimalDigits { return $1 + $2; } +SignedInteger + = [-+]? DecimalDigits { return $1 + $2; } -HexIntegerLiteral = "0" [xX] HexDigit+ { return parseInt($1 + $2 + $3.join("")); } +HexIntegerLiteral + = "0" [xX] HexDigit+ { return parseInt($1 + $2 + $3.join("")); } -HexDigit = [0-9a-fA-F] +HexDigit + = [0-9a-fA-F] -StringLiteral "string" = ('"' DoubleStringCharacters? '"' / "'" SingleStringCharacters? "'") { - return $1[1]; -} +StringLiteral "string" + = ('"' DoubleStringCharacters? '"' / "'" SingleStringCharacters? "'") { + return $1[1]; + } -DoubleStringCharacters = DoubleStringCharacter+ { return $1.join(""); } +DoubleStringCharacters + = DoubleStringCharacter+ { return $1.join(""); } -SingleStringCharacters = SingleStringCharacter+ { return $1.join(""); } +SingleStringCharacters + = SingleStringCharacter+ { return $1.join(""); } DoubleStringCharacter = !('"' / "\\" / LineTerminator) SourceCharacter { return $2; } @@ -213,7 +247,8 @@ SingleStringCharacter / "\\" EscapeSequence { return $2; } / LineContinuation -LineContinuation = "\\" LineTerminatorSequence { return $2; } +LineContinuation + = "\\" LineTerminatorSequence { return $2; } EscapeSequence = CharacterEscapeSequence @@ -221,45 +256,54 @@ EscapeSequence / HexEscapeSequence / UnicodeEscapeSequence -CharacterEscapeSequence = SingleEscapeCharacter / NonEscapeCharacter - -SingleEscapeCharacter = ['"\\bfnrtv] { - return $1 - .replace("b", "\b") - .replace("f", "\f") - .replace("n", "\n") - .replace("r", "\r") - .replace("t", "\t") - .replace("v", "\x0B") // IE does not recognize "\v". -} +CharacterEscapeSequence + = SingleEscapeCharacter + / NonEscapeCharacter + +SingleEscapeCharacter + = ['"\\bfnrtv] { + return $1 + .replace("b", "\b") + .replace("f", "\f") + .replace("n", "\n") + .replace("r", "\r") + .replace("t", "\t") + .replace("v", "\x0B") // IE does not recognize "\v". + } -NonEscapeCharacter = (!EscapeCharacter / LineTerminator) SourceCharacter { - return $2; -} +NonEscapeCharacter + = (!EscapeCharacter / LineTerminator) SourceCharacter { return $2; } -EscapeCharacter = SingleEscapeCharacter / DecimalDigit / "x" / "u" +EscapeCharacter + = SingleEscapeCharacter + / DecimalDigit + / "x" + / "u" -HexEscapeSequence = "x" HexDigit HexDigit { - return String.fromCharCode(parseInt("0x" + $2 + $3)); -} +HexEscapeSequence + = "x" HexDigit HexDigit { + return String.fromCharCode(parseInt("0x" + $2 + $3)); + } -UnicodeEscapeSequence = "u" HexDigit HexDigit HexDigit HexDigit { - return String.fromCharCode(parseInt("0x" + $2 + $3 + $4 + $5)); -} +UnicodeEscapeSequence + = "u" HexDigit HexDigit HexDigit HexDigit { + return String.fromCharCode(parseInt("0x" + $2 + $3 + $4 + $5)); + } -RegularExpressionLiteral "regular expression" = "/" RegularExpressionBody "/" RegularExpressionFlags { - return { - type: "RegularExpressionLiteral", - body: $2, - flags: $4 - }; -} +RegularExpressionLiteral "regular expression" + = "/" RegularExpressionBody "/" RegularExpressionFlags { + return { + type: "RegularExpressionLiteral", + body: $2, + flags: $4 + }; + } -RegularExpressionBody = RegularExpressionFirstChar RegularExpressionChars { - return $1 + $2; -} +RegularExpressionBody + = RegularExpressionFirstChar RegularExpressionChars { return $1 + $2; } -RegularExpressionChars = RegularExpressionChar* { return $1.join(""); } +RegularExpressionChars + = RegularExpressionChar* { return $1.join(""); } RegularExpressionFirstChar = ![*\\/[] RegularExpressionNonTerminator { return $2; } @@ -275,23 +319,24 @@ RegularExpressionChar * This rule contains an error in the specification: "NonTerminator" instead of * "RegularExpressionNonTerminator". */ -RegularExpressionBackslashSequence = "\\" RegularExpressionNonTerminator { - return $1 + $2; -} +RegularExpressionBackslashSequence + = "\\" RegularExpressionNonTerminator { return $1 + $2; } -RegularExpressionNonTerminator = !LineTerminator SourceCharacter { return $2; } +RegularExpressionNonTerminator + = !LineTerminator SourceCharacter { return $2; } -RegularExpressionClass = "[" RegularExpressionClassChars "]" { - return $1 + $2 + $3; -} +RegularExpressionClass + = "[" RegularExpressionClassChars "]" { return $1 + $2 + $3; } -RegularExpressionClassChars = RegularExpressionClassChar* { return $1.join(""); } +RegularExpressionClassChars + = RegularExpressionClassChar* { return $1.join(""); } RegularExpressionClassChar = ![\]\\] RegularExpressionNonTerminator { return $2; } / RegularExpressionBackslashSequence -RegularExpressionFlags = IdentifierPart* { return $1.join(""); } +RegularExpressionFlags + = IdentifierPart* { return $1.join(""); } /* Tokens */ @@ -389,13 +434,16 @@ EOSNoLineTerminator / _ &"}" / _ EOF -EOF = !. +EOF + = !. /* Whitespace */ -_ = (WhiteSpace / MultiLineCommentNoLineTerminator / SingleLineComment)* +_ + = (WhiteSpace / MultiLineCommentNoLineTerminator / SingleLineComment)* -__ = (WhiteSpace / LineTerminatorSequence / Comment)* +__ + = (WhiteSpace / LineTerminatorSequence / Comment)* /* ===== A.2 Number Conversions ===== */ @@ -407,44 +455,50 @@ __ = (WhiteSpace / LineTerminatorSequence / Comment)* /* ===== A.3 Expressions ===== */ PrimaryExpression - = ThisToken { return { type: "This" }; } - / Identifier { return { type: "Variable", name: $1 }; } + = ThisToken { return { type: "This" }; } + / Identifier { return { type: "Variable", name: $1 }; } / Literal / ArrayLiteral / ObjectLiteral / "(" __ Expression __ ")" { return $3; } -ArrayLiteral = "[" __ ElementList? __ (Elision __)? "]" { - return { - type: "ArrayLiteral", - elements: $3 !== "" ? $3 : [] - }; -} - -ElementList = (Elision __)? AssignmentExpression (__ "," __ Elision? __ AssignmentExpression)* { - var result = [$2]; - for (var i = 0; i < $3.length; i++) { - result.push($3[i][5]); - } - return result; -} - -Elision = "," (__ ",")* - -ObjectLiteral = "{" __ (PropertyNameAndValueList __ ("," __)?)? "}" { - return { - type: "ObjectLiteral", - properties: $3 !== "" ? $3[0] : [] - }; -} - -PropertyNameAndValueList = PropertyAssignment (__ "," __ PropertyAssignment)* { - var result = [$1]; - for (var i = 0; i < $2.length; i++) { - result.push($2[i][3]); - } - return result; -} +ArrayLiteral + = "[" __ ElementList? __ (Elision __)? "]" { + return { + type: "ArrayLiteral", + elements: $3 !== "" ? $3 : [] + }; + } + +ElementList + = (Elision __)? AssignmentExpression + (__ "," __ Elision? __ AssignmentExpression)* { + var result = [$2]; + for (var i = 0; i < $3.length; i++) { + result.push($3[i][5]); + } + return result; + } + +Elision + = "," (__ ",")* + +ObjectLiteral + = "{" __ (PropertyNameAndValueList __ ("," __)?)? "}" { + return { + type: "ObjectLiteral", + properties: $3 !== "" ? $3[0] : [] + }; + } + +PropertyNameAndValueList + = PropertyAssignment (__ "," __ PropertyAssignment)* { + var result = [$1]; + for (var i = 0; i < $2.length; i++) { + result.push($2[i][3]); + } + return result; + } PropertyAssignment = PropertyName __ ":" __ AssignmentExpression { @@ -461,7 +515,9 @@ PropertyAssignment body: $11 }; } - / SetToken __ PropertyName __ "(" __ PropertySetParameterList __ ")" __ "{" __ FunctionBody __ "}" { + / SetToken __ PropertyName __ + "(" __ PropertySetParameterList __ ")" __ + "{" __ FunctionBody __ "}" { return { type: "SetterDefinition", name: $3, @@ -475,35 +531,35 @@ PropertyName / StringLiteral / NumericLiteral -PropertySetParameterList = Identifier - -MemberExpression = - ( - PrimaryExpression - / FunctionExpression - / NewToken __ MemberExpression __ Arguments { - return { - type: "NewOperator", - constructor: $3, - arguments: $5 +PropertySetParameterList + = Identifier + +MemberExpression + = ( + PrimaryExpression + / FunctionExpression + / NewToken __ MemberExpression __ Arguments { + return { + type: "NewOperator", + constructor: $3, + arguments: $5 + }; + } + ) + ( + __ "[" __ Expression __ "]" { return $4; } + / __ "." __ IdentifierName { return $4; } + )* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "PropertyAccess", + base: result, + name: $2[i] }; } - ) - ( - __ "[" __ Expression __ "]" { return $4; } - / __ "." __ IdentifierName { return $4; } - )* - { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "PropertyAccess", - base: result, - name: $2[i] - }; + return result; } - return result; - } NewExpression = MemberExpression @@ -515,72 +571,75 @@ NewExpression }; } -CallExpression = - ( - MemberExpression __ Arguments { - return { - type: "FunctionCall", - name: $1, - arguments: $3 - }; - } - ) - ( - __ Arguments { - return { - type: "FunctionCallArguments", - arguments: $2 - }; - } - / __ "[" __ Expression __ "]" { +CallExpression + = ( + MemberExpression __ Arguments { return { - type: "PropertyAccessProperty", - name: $4 + type: "FunctionCall", + name: $1, + arguments: $3 }; } - / __ "." __ IdentifierName { - return { - type: "PropertyAccessProperty", - name: $4 - }; - } - )* - { - var result = $1; - for (var i = 0; i < $2.length; i++) { - switch ($2[i].type) { - case "FunctionCallArguments": - result = { - type: "FuctionCall", - name: result, - arguments: $2[i].arguments + ) + ( + __ Arguments { + return { + type: "FunctionCallArguments", + arguments: $2 }; - break; - case "PropertyAccessProperty": - result = { - type: "PropertyAccess", - base: result, - name: $2[i].name + } + / __ "[" __ Expression __ "]" { + return { + type: "PropertyAccessProperty", + name: $4 }; - break; - default: - throw new Error("Invalid expression type: " + $2[i].type); + } + / __ "." __ IdentifierName { + return { + type: "PropertyAccessProperty", + name: $4 + }; + } + )* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + switch ($2[i].type) { + case "FunctionCallArguments": + result = { + type: "FuctionCall", + name: result, + arguments: $2[i].arguments + }; + break; + case "PropertyAccessProperty": + result = { + type: "PropertyAccess", + base: result, + name: $2[i].name + }; + break; + default: + throw new Error("Invalid expression type: " + $2[i].type); + } } + return result; } - return result; - } -Arguments = "(" __ ArgumentList? __ ")" { return $3 !== "" ? $3 : []; } +Arguments + = "(" __ ArgumentList? __ ")" { return $3 !== "" ? $3 : []; } -ArgumentList = AssignmentExpression (__ "," __ AssignmentExpression)* { - var result = [$1]; - for (var i = 0; i < $2.length; i++) { - result.push($2[i][3]); +ArgumentList + = AssignmentExpression (__ "," __ AssignmentExpression)* { + var result = [$1]; + for (var i = 0; i < $2.length; i++) { + result.push($2[i][3]); + } + return result; } - return result; -} -LeftHandSideExpression = CallExpression / NewExpression +LeftHandSideExpression + = CallExpression + / NewExpression PostfixExpression = LeftHandSideExpression _ PostfixOperator { @@ -592,7 +651,9 @@ PostfixExpression } / LeftHandSideExpression -PostfixOperator = "++" / "--" +PostfixOperator + = "++" + / "--" UnaryExpression = PostfixExpression @@ -615,253 +676,296 @@ UnaryOperator / "~" / "!" -MultiplicativeExpression = UnaryExpression (__ MultiplicativeOperator __ UnaryExpression)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -MultiplicativeOperator = ("*" / "/" / "%") !"=" { return $1; } - -AdditiveExpression = MultiplicativeExpression (__ AdditiveOperator __ MultiplicativeExpression)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} +MultiplicativeExpression + = UnaryExpression (__ MultiplicativeOperator __ UnaryExpression)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +MultiplicativeOperator + = ("*" / "/" / "%") !"=" { return $1; } + +AdditiveExpression + = MultiplicativeExpression (__ AdditiveOperator __ MultiplicativeExpression)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } AdditiveOperator = "+" !("+" / "=") { return $1; } / "-" !("-" / "=") { return $1; } -ShiftExpression = AdditiveExpression (__ ShiftOperator __ AdditiveExpression)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -ShiftOperator = "<<" / ">>>" / ">>" - -RelationalExpression = ShiftExpression (__ RelationalOperator __ ShiftExpression)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -RelationalOperator = "<=" / ">=" / "<" / ">" / InstanceofToken / InToken - -RelationalExpressionNoIn = ShiftExpression (__ RelationalOperatorNoIn __ ShiftExpression)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -RelationalOperatorNoIn = "<=" / ">=" / "<" / ">" / InstanceofToken - -EqualityExpression = RelationalExpression (__ EqualityOperator __ RelationalExpression)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -EqualityExpressionNoIn = RelationalExpressionNoIn (__ EqualityOperator __ RelationalExpressionNoIn)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -EqualityOperator = "===" / "!==" / "==" / "!=" - -BitwiseANDExpression = EqualityExpression (__ BitwiseANDOperator __ EqualityExpression)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -BitwiseANDExpressionNoIn = EqualityExpressionNoIn (__ BitwiseANDOperator __ EqualityExpressionNoIn)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -BitwiseANDOperator = "&" !("&" / "=") { return $1; } - -BitwiseXORExpression = BitwiseANDExpression (__ BitwiseXOROperator __ BitwiseANDExpression)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -BitwiseXORExpressionNoIn = BitwiseANDExpressionNoIn (__ BitwiseXOROperator __ BitwiseANDExpressionNoIn)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -BitwiseXOROperator = "^" !("^" / "=") { return $1; } - -BitwiseORExpression = BitwiseXORExpression (__ BitwiseOROperator __ BitwiseXORExpression)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -BitwiseORExpressionNoIn = BitwiseXORExpressionNoIn (__ BitwiseOROperator __ BitwiseXORExpressionNoIn)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -BitwiseOROperator = "|" !("|" / "=") { return $1; } - -LogicalANDExpression = BitwiseORExpression (__ LogicalANDOperator __ BitwiseORExpression)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -LogicalANDExpressionNoIn = BitwiseORExpressionNoIn (__ LogicalANDOperator __ BitwiseORExpressionNoIn)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -LogicalANDOperator = "&&" !"=" { return $1; } - -LogicalORExpression = LogicalANDExpression (__ LogicalOROperator __ LogicalANDExpression)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -LogicalORExpressionNoIn = LogicalANDExpressionNoIn (__ LogicalOROperator __ LogicalANDExpressionNoIn)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} +ShiftExpression + = AdditiveExpression (__ ShiftOperator __ AdditiveExpression)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +ShiftOperator + = "<<" + / ">>>" + / ">>" + +RelationalExpression + = ShiftExpression (__ RelationalOperator __ ShiftExpression)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +RelationalOperator + = "<=" + / ">=" + / "<" + / ">" + / InstanceofToken + / InToken + +RelationalExpressionNoIn + = ShiftExpression (__ RelationalOperatorNoIn __ ShiftExpression)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +RelationalOperatorNoIn + = "<=" + / ">=" + / "<" + / ">" + / InstanceofToken + +EqualityExpression + = RelationalExpression (__ EqualityOperator __ RelationalExpression)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +EqualityExpressionNoIn + = RelationalExpressionNoIn (__ EqualityOperator __ RelationalExpressionNoIn)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +EqualityOperator + = "===" + / "!==" + / "==" + / "!=" + +BitwiseANDExpression + = EqualityExpression (__ BitwiseANDOperator __ EqualityExpression)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +BitwiseANDExpressionNoIn + = EqualityExpressionNoIn (__ BitwiseANDOperator __ EqualityExpressionNoIn)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +BitwiseANDOperator + = "&" !("&" / "=") { return $1; } + +BitwiseXORExpression + = BitwiseANDExpression (__ BitwiseXOROperator __ BitwiseANDExpression)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +BitwiseXORExpressionNoIn + = BitwiseANDExpressionNoIn (__ BitwiseXOROperator __ BitwiseANDExpressionNoIn)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +BitwiseXOROperator + = "^" !("^" / "=") { return $1; } + +BitwiseORExpression + = BitwiseXORExpression (__ BitwiseOROperator __ BitwiseXORExpression)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +BitwiseORExpressionNoIn + = BitwiseXORExpressionNoIn (__ BitwiseOROperator __ BitwiseXORExpressionNoIn)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +BitwiseOROperator + = "|" !("|" / "=") { return $1; } + +LogicalANDExpression + = BitwiseORExpression (__ LogicalANDOperator __ BitwiseORExpression)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +LogicalANDExpressionNoIn + = BitwiseORExpressionNoIn (__ LogicalANDOperator __ BitwiseORExpressionNoIn)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +LogicalANDOperator + = "&&" !"=" { return $1; } + +LogicalORExpression + = LogicalANDExpression (__ LogicalOROperator __ LogicalANDExpression)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +LogicalORExpressionNoIn + = LogicalANDExpressionNoIn (__ LogicalOROperator __ LogicalANDExpressionNoIn)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } -LogicalOROperator = "||" !"=" { return $1; } +LogicalOROperator + = "||" !"=" { return $1; } ConditionalExpression - = LogicalORExpression __ "?" __ AssignmentExpression __ ":" __ AssignmentExpression { + = LogicalORExpression __ + "?" __ AssignmentExpression __ + ":" __ AssignmentExpression { return { type: "ConditionalExpression", condition: $1, @@ -872,7 +976,9 @@ ConditionalExpression / LogicalORExpression ConditionalExpressionNoIn - = LogicalORExpressionNoIn __ "?" __ AssignmentExpressionNoIn __ ":" __ AssignmentExpressionNoIn { + = LogicalORExpressionNoIn __ + "?" __ AssignmentExpressionNoIn __ + ":" __ AssignmentExpressionNoIn { return { type: "ConditionalExpression", condition: $1, @@ -918,31 +1024,33 @@ AssignmentOperator / "^=" / "|=" -Expression = AssignmentExpression (__ "," __ AssignmentExpression)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} - -ExpressionNoIn = AssignmentExpressionNoIn (__ "," __ AssignmentExpressionNoIn)* { - var result = $1; - for (var i = 0; i < $2.length; i++) { - result = { - type: "BinaryExpression", - operator: $2[i][1], - left: result, - right: $2[i][3] - }; - } - return result; -} +Expression + = AssignmentExpression (__ "," __ AssignmentExpression)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } + +ExpressionNoIn + = AssignmentExpressionNoIn (__ "," __ AssignmentExpressionNoIn)* { + var result = $1; + for (var i = 0; i < $2.length; i++) { + result = { + type: "BinaryExpression", + operator: $2[i][1], + left: result, + right: $2[i][3] + }; + } + return result; + } /* ===== A.4 Statements ===== */ @@ -970,76 +1078,88 @@ Statement / FunctionDeclaration / FunctionExpression -Block = "{" __ (StatementList __)? "}" { - return { - type: "Block", - statements: $3 !== "" ? $3[0] : [] - }; -} - -StatementList = Statement (__ Statement)* { - var result = [$1]; - for (var i = 0; i < $2.length; i++) { - result.push($2[i][1]); - } - return result; -} - -VariableStatement = VarToken __ VariableDeclarationList EOS { - return { - type: "VariableStatement", - declarations: $3 - }; -} - -VariableDeclarationList = VariableDeclaration (__ "," __ VariableDeclaration)* { - var result = [$1]; - for (var i = 0; i < $2.length; i++) { - result.push($2[i][3]); - } - return result; -} +Block + = "{" __ (StatementList __)? "}" { + return { + type: "Block", + statements: $3 !== "" ? $3[0] : [] + }; + } -VariableDeclarationListNoIn = VariableDeclarationNoIn (__ "," __ VariableDeclarationNoIn)* { - var result = [$1]; - for (var i = 0; i < $2.length; i++) { - result.push($2[i][3]); - } - return result; -} - -VariableDeclaration = Identifier __ Initialiser? { - return { - type: "VariableDeclaration", - name: $1, - value: $3 !== "" ? $3 : null - }; -} - -VariableDeclarationNoIn = Identifier __ InitialiserNoIn? { - return { - type: "VariableDeclaration", - name: $1, - value: $3 !== "" ? $3 : null - }; -} - -Initialiser = "=" (!"=") __ AssignmentExpression { return $4; } - -InitialiserNoIn = "=" (!"=") __ AssignmentExpressionNoIn { return $4; } - -EmptyStatement = ";" { return { type: "EmptyStatement" }; } - -ExpressionStatement = !("{" / FunctionToken) Expression EOS { return $2; } - -IfStatement = IfToken __ "(" __ Expression __ ")" __ Statement (__ ElseToken __ Statement)? { - return { - type: "IfStatement", - condition: $5, - ifStatement: $9, - elseStatement: $10 !== "" ? $10[3] : null - }; -} +StatementList + = Statement (__ Statement)* { + var result = [$1]; + for (var i = 0; i < $2.length; i++) { + result.push($2[i][1]); + } + return result; + } + +VariableStatement + = VarToken __ VariableDeclarationList EOS { + return { + type: "VariableStatement", + declarations: $3 + }; + } + +VariableDeclarationList + = VariableDeclaration (__ "," __ VariableDeclaration)* { + var result = [$1]; + for (var i = 0; i < $2.length; i++) { + result.push($2[i][3]); + } + return result; + } + +VariableDeclarationListNoIn + = VariableDeclarationNoIn (__ "," __ VariableDeclarationNoIn)* { + var result = [$1]; + for (var i = 0; i < $2.length; i++) { + result.push($2[i][3]); + } + return result; + } + +VariableDeclaration + = Identifier __ Initialiser? { + return { + type: "VariableDeclaration", + name: $1, + value: $3 !== "" ? $3 : null + }; + } + +VariableDeclarationNoIn + = Identifier __ InitialiserNoIn? { + return { + type: "VariableDeclaration", + name: $1, + value: $3 !== "" ? $3 : null + }; + } + +Initialiser + = "=" (!"=") __ AssignmentExpression { return $4; } + +InitialiserNoIn + = "=" (!"=") __ AssignmentExpressionNoIn { return $4; } + +EmptyStatement + = ";" { return { type: "EmptyStatement" }; } + +ExpressionStatement + = !("{" / FunctionToken) Expression EOS { return $2; } + +IfStatement + = IfToken __ "(" __ Expression __ ")" __ Statement (__ ElseToken __ Statement)? { + return { + type: "IfStatement", + condition: $5, + ifStatement: $9, + elseStatement: $10 !== "" ? $10[3] : null + }; + } IterationStatement = DoWhileStatement @@ -1047,175 +1167,182 @@ IterationStatement / ForStatement / ForInStatement -DoWhileStatement = DoToken __ Statement __ WhileToken __ "(" __ Expression __ ")" EOS { - return { - type: "DoWhileStatement", - condition: $9, - statement: $3 - }; -} - -WhileStatement = WhileToken __ "(" __ Expression __ ")" __ Statement { - return { - type: "WhileStatement", - condition: $5, - statement: $9 - }; -} - -ForStatement = - ForToken __ - "(" __ - ( - VarToken __ VariableDeclarationListNoIn { - return { - type: "VariableStatement", - declarations: $3 - }; - } - / ExpressionNoIn? - ) __ - ";" __ - Expression? __ - ";" __ - Expression? __ - ")" __ - Statement - { - return { - type: "ForStatement", - initializer: $5 !== "" ? $5 : null, - test: $9 !== "" ? $9 : null, - counter: $13 !== "" ? $13 : null, - statement: $17 - }; - } +DoWhileStatement + = DoToken __ Statement __ WhileToken __ "(" __ Expression __ ")" EOS { + return { + type: "DoWhileStatement", + condition: $9, + statement: $3 + }; + } -ForInStatement = - ForToken __ - "(" __ - ( - VarToken __ VariableDeclarationNoIn { return $3; } - / LeftHandSideExpression - ) __ - InToken __ - Expression __ - ")" __ - Statement - { - return { - type: "ForInStatement", - iterator: $5, - collection: $9, - statement: $13 - }; - } +WhileStatement + = WhileToken __ "(" __ Expression __ ")" __ Statement { + return { + type: "WhileStatement", + condition: $5, + statement: $9 + }; + } -ContinueStatement = - ContinueToken _ - ( - Identifier EOS { return $1; } - / EOSNoLineTerminator { return ""; } - ) - { - return { - type: "ContinueStatement", - label: $3 !== "" ? $3 : null - }; - } +ForStatement + = ForToken __ + "(" __ + ( + VarToken __ VariableDeclarationListNoIn { + return { + type: "VariableStatement", + declarations: $3 + }; + } + / ExpressionNoIn? + ) __ + ";" __ + Expression? __ + ";" __ + Expression? __ + ")" __ + Statement + { + return { + type: "ForStatement", + initializer: $5 !== "" ? $5 : null, + test: $9 !== "" ? $9 : null, + counter: $13 !== "" ? $13 : null, + statement: $17 + }; + } -BreakStatement = - BreakToken _ - ( - Identifier EOS { return $1; } - / EOSNoLineTerminator { return ""; } - ) - { - return { - type: "BreakStatement", - label: $3 !== "" ? $3 : null - }; - } +ForInStatement + = ForToken __ + "(" __ + ( + VarToken __ VariableDeclarationNoIn { return $3; } + / LeftHandSideExpression + ) __ + InToken __ + Expression __ + ")" __ + Statement + { + return { + type: "ForInStatement", + iterator: $5, + collection: $9, + statement: $13 + }; + } -ReturnStatement = - ReturnToken _ - ( - Expression EOS { return $1; } - / EOSNoLineTerminator { return ""; } - ) - { - return { - type: "ReturnStatement", - value: $3 !== "" ? $3 : null - }; - } +ContinueStatement + = ContinueToken _ + ( + Identifier EOS { return $1; } + / EOSNoLineTerminator { return ""; } + ) { + return { + type: "ContinueStatement", + label: $3 !== "" ? $3 : null + }; + } -WithStatement = WithToken __ "(" __ Expression __ ")" __ Statement { - return { - type: "WithStatement", - environment: $5, - statement: $9 - }; -} - -SwitchStatement = SwitchToken __ "(" __ Expression __ ")" __ CaseBlock { - return { - type: "SwitchStatement", - expression: $5, - clauses: $9 - }; -} - -CaseBlock = "{" __ CaseClauses? (__ DefaultClause __ CaseClauses?)? __ "}" { - var clausesBefore = $3 !== "" ? $3 : []; - if ($4 !== "") { - var defaultClause = $4[1]; - var clausesAfter = $4[3] !== "" ? $4[3] : []; - } else { - var defaultClause = null; - var clausesAfter = []; - } +BreakStatement + = BreakToken _ + ( + Identifier EOS { return $1; } + / EOSNoLineTerminator { return ""; } + ) { + return { + type: "BreakStatement", + label: $3 !== "" ? $3 : null + }; + } - return (defaultClause ? clausesBefore.concat(defaultClause) : clausesBefore).concat(clausesAfter); -} +ReturnStatement + = ReturnToken _ + ( + Expression EOS { return $1; } + / EOSNoLineTerminator { return ""; } + ) { + return { + type: "ReturnStatement", + value: $3 !== "" ? $3 : null + }; + } -CaseClauses = CaseClause (__ CaseClause)* { - var result = [$1]; - for (var i = 0; i < $2.length; i++) { - result.push($2[i][1]); - } - return result; -} - -CaseClause = CaseToken __ Expression __ ":" (__ StatementList)? { - return { - type: "CaseClause", - selector: $3, - statements: $6 !== "" ? $6[1] : [] - }; -} - -DefaultClause = DefaultToken __ ":" (__ StatementList)? { - return { - type: "DefaultClause", - statements: $4 !== "" ? $4[1] : [] - }; -} - -LabelledStatement = Identifier __ ":" __ Statement { - return { - type: "LabelledStatement", - label: $1, - statement: $5 - }; -} - -ThrowStatement = ThrowToken _ Expression EOSNoLineTerminator { - return { - type: "ThrowStatement", - exception: $3 - }; -} +WithStatement + = WithToken __ "(" __ Expression __ ")" __ Statement { + return { + type: "WithStatement", + environment: $5, + statement: $9 + }; + } + +SwitchStatement + = SwitchToken __ "(" __ Expression __ ")" __ CaseBlock { + return { + type: "SwitchStatement", + expression: $5, + clauses: $9 + }; + } + +CaseBlock + = "{" __ CaseClauses? (__ DefaultClause __ CaseClauses?)? __ "}" { + var clausesBefore = $3 !== "" ? $3 : []; + if ($4 !== "") { + var defaultClause = $4[1]; + var clausesAfter = $4[3] !== "" ? $4[3] : []; + } else { + var defaultClause = null; + var clausesAfter = []; + } + + return (defaultClause ? clausesBefore.concat(defaultClause) : clausesBefore).concat(clausesAfter); + } + +CaseClauses + = CaseClause (__ CaseClause)* { + var result = [$1]; + for (var i = 0; i < $2.length; i++) { + result.push($2[i][1]); + } + return result; + } + +CaseClause + = CaseToken __ Expression __ ":" (__ StatementList)? { + return { + type: "CaseClause", + selector: $3, + statements: $6 !== "" ? $6[1] : [] + }; + } + +DefaultClause + = DefaultToken __ ":" (__ StatementList)? { + return { + type: "DefaultClause", + statements: $4 !== "" ? $4[1] : [] + }; + } + +LabelledStatement + = Identifier __ ":" __ Statement { + return { + type: "LabelledStatement", + label: $1, + statement: $5 + }; + } + +ThrowStatement + = ThrowToken _ Expression EOSNoLineTerminator { + return { + type: "ThrowStatement", + exception: $3 + }; + } TryStatement = TryToken __ Block __ Catch __ Finally { @@ -1243,78 +1370,88 @@ TryStatement }; } -Catch = CatchToken __ "(" __ Identifier __ ")" __ Block { - return { - type: "Catch", - identifier: $5, - block: $9 - }; -} +Catch + = CatchToken __ "(" __ Identifier __ ")" __ Block { + return { + type: "Catch", + identifier: $5, + block: $9 + }; + } -Finally = FinallyToken __ Block { - return { - type: "Finally", - block: $3 - }; -} +Finally + = FinallyToken __ Block { + return { + type: "Finally", + block: $3 + }; + } -DebuggerStatement = DebuggerToken EOS { - return { - type: "DebuggerStatement", - }; -} +DebuggerStatement + = DebuggerToken EOS { return { type: "DebuggerStatement" }; } /* ===== A.5 Functions and Programs ===== */ -FunctionDeclaration = FunctionToken __ Identifier __ "(" __ FormalParameterList? __ ")" __ "{" __ FunctionBody __ "}" { - return { - type: "Function", - name: $3, - params: $7 !== "" ? $7 : [], - elements: $13 - }; -} - -FunctionExpression = FunctionToken __ Identifier? __ "(" __ FormalParameterList? __ ")" __ "{" __ FunctionBody __ "}" { - return { - type: "Function", - name: $3 !== "" ? $3 : null, - params: $7 !== "" ? $7 : [], - elements: $13 - }; -} - -FormalParameterList = Identifier (__ "," __ Identifier)* { - var result = [$1]; - for (var i = 0; i < $2.length; i++) { - result.push($2[i][3]); - } - return result; -} - -FunctionBody = SourceElements? { return $1 !== "" ? $1 : []; } - -Program = SourceElements? { - return { - type: "Program", - elements: $1 !== "" ? $1 : [] - }; -} - -SourceElements = SourceElement (__ SourceElement)* { - var result = [$1]; - for (var i = 0; i < $2.length; i++) { - result.push($2[i][1]); - } - return result; -} +FunctionDeclaration + = FunctionToken __ Identifier __ + "(" __ FormalParameterList? __ ")" __ + "{" __ FunctionBody __ "}" { + return { + type: "Function", + name: $3, + params: $7 !== "" ? $7 : [], + elements: $13 + }; + } + +FunctionExpression + = FunctionToken __ Identifier? __ + "(" __ FormalParameterList? __ ")" __ + "{" __ FunctionBody __ "}" { + return { + type: "Function", + name: $3 !== "" ? $3 : null, + params: $7 !== "" ? $7 : [], + elements: $13 + }; + } + +FormalParameterList + = Identifier (__ "," __ Identifier)* { + var result = [$1]; + for (var i = 0; i < $2.length; i++) { + result.push($2[i][3]); + } + return result; + } + +FunctionBody + = SourceElements? { return $1 !== "" ? $1 : []; } + +Program + = SourceElements? { + return { + type: "Program", + elements: $1 !== "" ? $1 : [] + }; + } + +SourceElements + = SourceElement (__ SourceElement)* { + var result = [$1]; + for (var i = 0; i < $2.length; i++) { + result.push($2[i][1]); + } + return result; + } /* * The specification also allows |FunctionDeclaration| here. We do it * implicitly, because we consider |FunctionDeclaration| and * |FunctionExpression| as statements. See the coment at the |Statement| rule. */ -SourceElement = Statement +SourceElement + = Statement /* ===== A.6 Universal Resource Identifier Character Classes ===== */ diff --git a/examples/json.pegjs b/examples/json.pegjs index 5681fe3..6bfa538 100644 --- a/examples/json.pegjs +++ b/examples/json.pegjs @@ -2,34 +2,38 @@ /* ===== Syntactical Elements ===== */ -start = _ object { return $2; } +start + = _ object { return $2; } object = "{" _ "}" _ { return {}; } / "{" _ members "}" _ { return $3; } -members = pair ("," _ pair)* { - var result = {}; - result[$1[0]] = $1[1]; - for (var i = 0; i < $2.length; i++) { - result[$2[i][2][0]] = $2[i][2][1]; - } - return result; -} +members + = pair ("," _ pair)* { + var result = {}; + result[$1[0]] = $1[1]; + for (var i = 0; i < $2.length; i++) { + result[$2[i][2][0]] = $2[i][2][1]; + } + return result; + } -pair = string ":" _ value { return [$1, $4]; } +pair + = string ":" _ value { return [$1, $4]; } array = "[" _ "]" _ { return []; } / "[" _ elements "]" _ { return $3; } -elements = value ("," _ value)* { - var result = [$1]; - for (var i = 0; i < $2.length; i++) { - result.push($2[i][2]); - } - return result; -} +elements + = value ("," _ value)* { + var result = [$1]; + for (var i = 0; i < $2.length; i++) { + result.push($2[i][2]); + } + return result; + } value = string @@ -47,7 +51,8 @@ string "string" = '"' '"' _ { return ""; } / '"' chars '"' _ { return $2; } -chars = char+ { return $1.join(""); } +chars + = char+ { return $1.join(""); } char // In the original JSON grammar: "any-Unicode-character-except-"-or-\-or-control-character" @@ -76,13 +81,17 @@ int / "-" digit19 digits { return $1 + $2 + $3; } / "-" digit { return $1 + $2; } -frac = "." digits { return $1 + $2; } +frac + = "." digits { return $1 + $2; } -exp = e digits { return $1 + $2; } +exp + = e digits { return $1 + $2; } -digits = digit+ { return $1.join(""); } +digits + = digit+ { return $1.join(""); } -e = [eE] [+-]? { return $1 + $2; } +e + = [eE] [+-]? { return $1 + $2; } /* * The following rules are not present in the original JSON gramar, but they are @@ -91,16 +100,21 @@ e = [eE] [+-]? { return $1 + $2; } * FIXME: Define them according to ECMA-262, 5th ed. */ -digit = [0-9] +digit + = [0-9] -digit19 = [1-9] +digit19 + = [1-9] -hexDigit = [0-9a-fA-F] +hexDigit + = [0-9a-fA-F] /* ===== Whitespace ===== */ -_ "whitespace" = whitespace* +_ "whitespace" + = whitespace* // Whitespace is undefined in the original JSON grammar, so I assume a simple // conventional definition consistent with ECMA-262, 5th ed. -whitespace = [ \t\n\r] +whitespace + = [ \t\n\r] diff --git a/lib/metagrammar.js b/lib/metagrammar.js index 75d5d0b..6ab8a5c 100644 --- a/lib/metagrammar.js +++ b/lib/metagrammar.js @@ -86,10 +86,10 @@ PEG.grammarParser = (function(){ } var result0 = result1 !== null ? (function($1, $2) { - var result = {}; - PEG.ArrayUtils.each($2, function(rule) { result[rule.name] = rule; }); - return result; - }).apply(null, result1) + var result = {}; + PEG.ArrayUtils.each($2, function(rule) { result[rule.name] = rule; }); + return result; + }).apply(null, result1) : null; @@ -158,13 +158,13 @@ PEG.grammarParser = (function(){ } var result5 = result6 !== null ? (function($1, $2, $3, $4) { - return { - type: "rule", - name: $1, - displayName: $2 !== "" ? $2 : null, - expression: $4 - }; - }).apply(null, result6) + return { + type: "rule", + name: $1, + displayName: $2 !== "" ? $2 : null, + expression: $4 + }; + }).apply(null, result6) : null; @@ -234,19 +234,19 @@ PEG.grammarParser = (function(){ } var result13 = result14 !== null ? (function($1, $2) { - if ($2.length > 0) { - var alternatives = [$1].concat(PEG.ArrayUtils.map( - $2, - function(element) { return element[1]; } - )); - return { - type: "choice", - alternatives: alternatives - } - } else { - return $1; - } - }).apply(null, result14) + if ($2.length > 0) { + var alternatives = [$1].concat(PEG.ArrayUtils.map( + $2, + function(element) { return element[1]; } + )); + return { + type: "choice", + alternatives: alternatives + } + } else { + return $1; + } + }).apply(null, result14) : null; @@ -1421,8 +1421,8 @@ PEG.grammarParser = (function(){ } var result129 = result130 !== null ? (function($1, $2, $3) { - return $1 + $2.join(""); - }).apply(null, result130) + return $1 + $2.join(""); + }).apply(null, result130) : null; context.reportMatchFailures = savedReportMatchFailures; if (context.reportMatchFailures && result129 === null) { @@ -1991,20 +1991,22 @@ PEG.grammarParser = (function(){ } var result190 = result191 !== null ? (function($1, $2, $3, $4, $5) { - parts = PEG.ArrayUtils.map($3, function(part) { return part.data; }); - rawText = "[" - + $2 - + PEG.ArrayUtils.map($3, function(part) { return part.rawText; }).join("") - + "]"; + parts = PEG.ArrayUtils.map($3, function(part) { return part.data; }); + rawText = "[" + + $2 + + PEG.ArrayUtils.map($3, function(part) { + return part.rawText; + }).join("") + + "]"; - return { - type: "class", - inverted: $2 === "^", - parts: parts, - // FIXME: Get the raw text from the input directly. - rawText: rawText - }; - }).apply(null, result191) + return { + type: "class", + inverted: $2 === "^", + parts: parts, + // FIXME: Get the raw text from the input directly. + rawText: rawText + }; + }).apply(null, result191) : null; context.reportMatchFailures = savedReportMatchFailures; if (context.reportMatchFailures && result190 === null) { @@ -2059,18 +2061,18 @@ PEG.grammarParser = (function(){ } var result201 = result202 !== null ? (function($1, $2, $3) { - if ($1.data.charCodeAt(0) > $3.data.charCodeAt(0)) { - throw new this.SyntaxError( - "Invalid character range: " + $1.rawText + "-" + $3.rawText + "." - ); - } + if ($1.data.charCodeAt(0) > $3.data.charCodeAt(0)) { + throw new this.SyntaxError( + "Invalid character range: " + $1.rawText + "-" + $3.rawText + "." + ); + } - return { - data: [$1.data, $3.data], - // FIXME: Get the raw text from the input directly. - rawText: $1.rawText + "-" + $3.rawText - } - }).apply(null, result202) + return { + data: [$1.data, $3.data], + // FIXME: Get the raw text from the input directly. + rawText: $1.rawText + "-" + $3.rawText + } + }).apply(null, result202) : null; @@ -2096,12 +2098,12 @@ PEG.grammarParser = (function(){ var result207 = this._parse_bracketDelimitedCharacter(context); var result206 = result207 !== null ? (function($1) { - return { - data: $1, - // FIXME: Get the raw text from the input directly. - rawText: PEG.RegExpUtils.quoteForClass($1) - }; - })(result207) + return { + data: $1, + // FIXME: Get the raw text from the input directly. + rawText: PEG.RegExpUtils.quoteForClass($1) + }; + })(result207) : null; @@ -2347,14 +2349,14 @@ PEG.grammarParser = (function(){ } var result223 = result224 !== null ? (function($1, $2, $3) { - return $3 - .replace("b", "\b") - .replace("f", "\f") - .replace("n", "\n") - .replace("r", "\r") - .replace("t", "\t") - .replace("v", "\x0B") // IE does not recognize "\v". - }).apply(null, result224) + return $3 + .replace("b", "\b") + .replace("f", "\f") + .replace("n", "\n") + .replace("r", "\r") + .replace("t", "\t") + .replace("v", "\x0B") // IE does not recognize "\v". + }).apply(null, result224) : null; @@ -2463,8 +2465,8 @@ PEG.grammarParser = (function(){ } var result238 = result239 !== null ? (function($1, $2, $3) { - return String.fromCharCode(parseInt("0x" + $2 + $3)); - }).apply(null, result239) + return String.fromCharCode(parseInt("0x" + $2 + $3)); + }).apply(null, result239) : null; @@ -2529,8 +2531,8 @@ PEG.grammarParser = (function(){ } var result243 = result244 !== null ? (function($1, $2, $3, $4, $5) { - return String.fromCharCode(parseInt("0x" + $2 + $3 + $4 + $5)); - }).apply(null, result244) + return String.fromCharCode(parseInt("0x" + $2 + $3 + $4 + $5)); + }).apply(null, result244) : null; diff --git a/lib/metagrammar.pegjs b/lib/metagrammar.pegjs index be7372a..e1ebbd4 100644 --- a/lib/metagrammar.pegjs +++ b/lib/metagrammar.pegjs @@ -1,34 +1,38 @@ -grammar = __ rule+ { - var result = {}; - PEG.ArrayUtils.each($2, function(rule) { result[rule.name] = rule; }); - return result; -} - -rule = identifier (literal / "") equals expression { - return { - type: "rule", - name: $1, - displayName: $2 !== "" ? $2 : null, - expression: $4 - }; -} - -expression = choice - -choice = sequence (slash sequence)* { - if ($2.length > 0) { - var alternatives = [$1].concat(PEG.ArrayUtils.map( - $2, - function(element) { return element[1]; } - )); - return { - type: "choice", - alternatives: alternatives +grammar + = __ rule+ { + var result = {}; + PEG.ArrayUtils.each($2, function(rule) { result[rule.name] = rule; }); + return result; + } + +rule + = identifier (literal / "") equals expression { + return { + type: "rule", + name: $1, + displayName: $2 !== "" ? $2 : null, + expression: $4 + }; + } + +expression + = choice + +choice + = sequence (slash sequence)* { + if ($2.length > 0) { + var alternatives = [$1].concat(PEG.ArrayUtils.map( + $2, + function(element) { return element[1]; } + )); + return { + type: "choice", + alternatives: alternatives + } + } else { + return $1; + } } - } else { - return $1; - } -} sequence = prefixed* action { @@ -73,13 +77,17 @@ primary /* "Lexical" elements */ -action "action" = braced __ { return $1.substr(1, $1.length - 2); } +action "action" + = braced __ { return $1.substr(1, $1.length - 2); } -braced = "{" (braced / nonBraceCharacter)* "}" { return $1 + $2.join("") + $3; } +braced + = "{" (braced / nonBraceCharacter)* "}" { return $1 + $2.join("") + $3; } -nonBraceCharacters = nonBraceCharacter+ { return $1.join(""); } +nonBraceCharacters + = nonBraceCharacter+ { return $1.join(""); } -nonBraceCharacter: [^{}] +nonBraceCharacter + = [^{}] equals = "=" __ { return $1; } slash = "/" __ { return $1; } @@ -107,17 +115,20 @@ dot = "." __ { return $1; } * The simplifications were made just to make the implementation little bit * easier, there is no "philosophical" reason behind them. */ -identifier "identifier" = (letter / "_" / "$") (letter / digit / "_" / "$")* __ { - return $1 + $2.join(""); -} +identifier "identifier" + = (letter / "_" / "$") (letter / digit / "_" / "$")* __ { + return $1 + $2.join(""); + } /* * Modelled after ECMA-262, 5th ed., 7.8.4. (syntax & semantics, rules only * vaguely). */ -literal "literal" = (doubleQuotedLiteral / singleQuotedLiteral) __ { return $1; } +literal "literal" + = (doubleQuotedLiteral / singleQuotedLiteral) __ { return $1; } -doubleQuotedLiteral = '"' doubleQuotedCharacter* '"' { return $2.join(""); } +doubleQuotedLiteral + = '"' doubleQuotedCharacter* '"' { return $2.join(""); } doubleQuotedCharacter = simpleDoubleQuotedCharacter @@ -127,9 +138,11 @@ doubleQuotedCharacter / unicodeEscapeSequence / eolEscapeSequence -simpleDoubleQuotedCharacter = !('"' / "\\" / eolChar) . { return $2; } +simpleDoubleQuotedCharacter + = !('"' / "\\" / eolChar) . { return $2; } -singleQuotedLiteral = "'" singleQuotedCharacter* "'" { return $2.join(""); } +singleQuotedLiteral + = "'" singleQuotedCharacter* "'" { return $2.join(""); } singleQuotedCharacter = simpleSingleQuotedCharacter @@ -139,45 +152,51 @@ singleQuotedCharacter / unicodeEscapeSequence / eolEscapeSequence -simpleSingleQuotedCharacter = !("'" / "\\" / eolChar) . { return $2; } - -class "character class" = "[" "^"? (classCharacterRange / classCharacter)* "]" __ { - parts = PEG.ArrayUtils.map($3, function(part) { return part.data; }); - rawText = "[" - + $2 - + PEG.ArrayUtils.map($3, function(part) { return part.rawText; }).join("") - + "]"; - - return { - type: "class", - inverted: $2 === "^", - parts: parts, - // FIXME: Get the raw text from the input directly. - rawText: rawText - }; -} - -classCharacterRange = classCharacter "-" classCharacter { - if ($1.data.charCodeAt(0) > $3.data.charCodeAt(0)) { - throw new this.SyntaxError( - "Invalid character range: " + $1.rawText + "-" + $3.rawText + "." - ); - } - - return { - data: [$1.data, $3.data], - // FIXME: Get the raw text from the input directly. - rawText: $1.rawText + "-" + $3.rawText - } -} - -classCharacter = bracketDelimitedCharacter { - return { - data: $1, - // FIXME: Get the raw text from the input directly. - rawText: PEG.RegExpUtils.quoteForClass($1) - }; -} +simpleSingleQuotedCharacter + = !("'" / "\\" / eolChar) . { return $2; } + +class "character class" + = "[" "^"? (classCharacterRange / classCharacter)* "]" __ { + parts = PEG.ArrayUtils.map($3, function(part) { return part.data; }); + rawText = "[" + + $2 + + PEG.ArrayUtils.map($3, function(part) { + return part.rawText; + }).join("") + + "]"; + + return { + type: "class", + inverted: $2 === "^", + parts: parts, + // FIXME: Get the raw text from the input directly. + rawText: rawText + }; + } + +classCharacterRange + = classCharacter "-" classCharacter { + if ($1.data.charCodeAt(0) > $3.data.charCodeAt(0)) { + throw new this.SyntaxError( + "Invalid character range: " + $1.rawText + "-" + $3.rawText + "." + ); + } + + return { + data: [$1.data, $3.data], + // FIXME: Get the raw text from the input directly. + rawText: $1.rawText + "-" + $3.rawText + } + } + +classCharacter + = bracketDelimitedCharacter { + return { + data: $1, + // FIXME: Get the raw text from the input directly. + rawText: PEG.RegExpUtils.quoteForClass($1) + }; + } bracketDelimitedCharacter = simpleBracketDelimitedCharacter @@ -187,53 +206,76 @@ bracketDelimitedCharacter / unicodeEscapeSequence / eolEscapeSequence -simpleBracketDelimitedCharacter = !("]" / "\\" / eolChar) . { return $2; } - -simpleEscapeSequence = "\\" !(digit / "x" / "u" / eolChar) . { - return $3 - .replace("b", "\b") - .replace("f", "\f") - .replace("n", "\n") - .replace("r", "\r") - .replace("t", "\t") - .replace("v", "\x0B") // IE does not recognize "\v". -} +simpleBracketDelimitedCharacter + = !("]" / "\\" / eolChar) . { return $2; } + +simpleEscapeSequence + = "\\" !(digit / "x" / "u" / eolChar) . { + return $3 + .replace("b", "\b") + .replace("f", "\f") + .replace("n", "\n") + .replace("r", "\r") + .replace("t", "\t") + .replace("v", "\x0B") // IE does not recognize "\v". + } -zeroEscapeSequence = "\\0" !digit { return "\0"; } +zeroEscapeSequence + = "\\0" !digit { return "\0"; } -hexEscapeSequence = "\\x" hexDigit hexDigit { - return String.fromCharCode(parseInt("0x" + $2 + $3)); -} +hexEscapeSequence + = "\\x" hexDigit hexDigit { + return String.fromCharCode(parseInt("0x" + $2 + $3)); + } -unicodeEscapeSequence = "\\u" hexDigit hexDigit hexDigit hexDigit { - return String.fromCharCode(parseInt("0x" + $2 + $3 + $4 + $5)); -} +unicodeEscapeSequence + = "\\u" hexDigit hexDigit hexDigit hexDigit { + return String.fromCharCode(parseInt("0x" + $2 + $3 + $4 + $5)); + } -eolEscapeSequence = "\\" eol { return $2; } +eolEscapeSequence + = "\\" eol { return $2; } -digit = [0-9] +digit + = [0-9] -hexDigit = [0-9a-fA-F] +hexDigit + = [0-9a-fA-F] -letter = lowerCaseLetter / upperCaseLetter +letter + = lowerCaseLetter + / upperCaseLetter -lowerCaseLetter = [a-z] +lowerCaseLetter + = [a-z] -upperCaseLetter = [A-Z] +upperCaseLetter + = [A-Z] __ = (whitespace / eol / comment)* /* Modelled after ECMA-262, 5th ed., 7.4. */ -comment "comment" = singleLineComment / multiLineComment +comment "comment" + = singleLineComment + / multiLineComment -singleLineComment = "//" (!eolChar .)* +singleLineComment + = "//" (!eolChar .)* -multiLineComment = "/*" (!"*/" .)* "*/" +multiLineComment + = "/*" (!"*/" .)* "*/" /* Modelled after ECMA-262, 5th ed., 7.3. */ -eol "end of line" = "\n" / "\r\n" / "\r" / "\u2028" / "\u2029" +eol "end of line" + = "\n" + / "\r\n" + / "\r" + / "\u2028" + / "\u2029" -eolChar = [\n\r\u2028\u2029] +eolChar + = [\n\r\u2028\u2029] /* Modelled after ECMA-262, 5th ed., 7.2. */ -whitespace "whitespace" = [ \t\v\f\u00A0\uFEFF\u1680\u180E\u2000-\u200A\u202F\u205F\u3000] +whitespace "whitespace" + = [ \t\v\f\u00A0\uFEFF\u1680\u180E\u2000-\u200A\u202F\u205F\u3000]