Browse Source

Formatted all grammars more consistently and transparently

This is purely cosmetical change, no functionality was affected
(hopefully).
redux
David Majda 13 years ago
parent
commit
409ddf2ae8
  1. 21
      examples/arithmetics.pegjs
  2. 508
      examples/css.pegjs
  3. 1735
      examples/javascript.pegjs
  4. 68
      examples/json.pegjs
  5. 138
      lib/metagrammar.js
  6. 262
      lib/metagrammar.pegjs

21
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); }

508
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* "<!--"
CDC "-->"
= comment* "-->"
INCLUDES "~="
= comment* "~="
DASHMATCH "|="
= comment* "|="
CDO "<!--" = comment* "<!--"
CDC "-->" = 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; }

1735
examples/javascript.pegjs

File diff suppressed because it is too large

68
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]

138
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;

262
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]

Loading…
Cancel
Save