Formatted all grammars more consistently and transparently

This is purely cosmetical change, no functionality was affected
(hopefully).
redux
David Majda 14 years ago
parent 698564a3c2
commit 409ddf2ae8

@ -3,15 +3,20 @@
* "2*(3+4)". The parser generated from this grammar then computes their value. * "2*(3+4)". The parser generated from this grammar then computes their value.
*/ */
start = additive start
= additive
additive = multiplicative "+" additive { return $1 + $3; } additive
/ multiplicative = multiplicative "+" additive { return $1 + $3; }
/ multiplicative
multiplicative = primary "*" multiplicative { return $1 * $3; } multiplicative
/ primary = primary "*" multiplicative { return $1 * $3; }
/ primary
primary = integer primary
/ "(" additive ")" { return $2; } = integer
/ "(" additive ")" { return $2; }
integer "integer" = [0-9]+ { return parseInt($1.join(""), 10); } integer "integer"
= [0-9]+ { return parseInt($1.join(""), 10); }

@ -14,73 +14,79 @@
/* ===== Syntactical Elements ===== */ /* ===== Syntactical Elements ===== */
start = stylesheet comment* { return $1; } start
= stylesheet comment* { return $1; }
stylesheet =
(CHARSET_SYM STRING ";")? (S / CDO / CDC)* stylesheet
(import (CDO S* / CDC S*)*)* = (CHARSET_SYM STRING ";")? (S / CDO / CDC)*
((ruleset / media / page) (CDO S* / CDC S*)*)* (import (CDO S* / CDC S*)*)*
{ ((ruleset / media / page) (CDO S* / CDC S*)*)* {
var imports = []; var imports = [];
for (var i = 0; i < $3.length; i++) { for (var i = 0; i < $3.length; i++) {
imports.push($3[i][0]); 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 = []; import
for (i = 0; i < $4.length; i++) { = IMPORT_SYM S* (STRING / URI) S* media_list? ";" S* {
rules.push($4[i][0]); return {
type: "import_rule",
href: $3,
media: $5 !== "" ? $5 : []
};
} }
return { media
type: "stylesheet", = MEDIA_SYM S* media_list "{" S* ruleset* "}" S* {
charset: $1 !== "" ? $1[1] : null, return {
imports: imports, type: "media_rule",
rules: rules media: $3,
}; rules: $6
} };
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]);
} }
}
return { media_list
type: "page_rule", = medium ("," S* medium)* {
qualifier: $3 !== "" ? $3 : null, var result = [$1];
declarations: declarations 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 operator
= "/" S* { return $1; } = "/" S* { return $1; }
@ -90,29 +96,34 @@ combinator
= "+" S* { return $1; } = "+" S* { return $1; }
/ ">" 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* { ruleset
var selectors = [$1]; = selector ("," S* selector)*
for (var i = 0; i < $2.length; i++) { "{" S* declaration? (";" S* declaration?)* "}" S* {
selectors.push($2[i][2]); var selectors = [$1];
} for (var i = 0; i < $2.length; i++) {
selectors.push($2[i][2]);
}
var declarations = $5 !== "" ? [$5] : []; var declarations = $5 !== "" ? [$5] : [];
for (i = 0; i < $6.length; i++) { for (i = 0; i < $6.length; i++) {
if ($6[i][2] !== "") { if ($6[i][2] !== "") {
declarations.push($6[i][2]); declarations.push($6[i][2]);
} }
} }
return { return {
type: "ruleset", type: "ruleset",
selectors: selectors, selectors: selectors,
declarations: declarations declarations: declarations
}; };
} }
selector selector
= simple_selector S* combinator selector { = simple_selector S* combinator selector {
@ -160,66 +171,71 @@ simple_selector
}; };
} }
class = "." IDENT { return { type: "class_selector", "class": $2 }; } class
= "." IDENT { return { type: "class_selector", "class": $2 }; }
element_name = IDENT / '*'
element_name
attrib = "[" S* IDENT S* (('=' / INCLUDES / DASHMATCH) S* (IDENT / STRING) S*)? "]" { = IDENT / '*'
return {
type: "attribute_selector", attrib
attribute: $3, = "[" S* IDENT S* (('=' / INCLUDES / DASHMATCH) S* (IDENT / STRING) S*)? "]" {
operator: $5 !== "" ? $5[0] : null, return {
value: $5 !== "" ? $5[2] : null type: "attribute_selector",
}; attribute: $3,
} operator: $5 !== "" ? $5[0] : null,
value: $5 !== "" ? $5[2] : null
pseudo = };
":" }
(
FUNCTION S* (IDENT S*)? ")" { pseudo
return { = ":"
type: "function", (
name: $1, FUNCTION S* (IDENT S*)? ")" {
params: $3 !== "" ? [$3[0]] : [] 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 return result;
) }
{
/*
* 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;
}
term term
= unary_operator? = unary_operator?
@ -239,69 +255,127 @@ term
/ STRING S* { return { type: "string", value: $1 }; } / STRING S* { return { type: "string", value: $1 }; }
/ IDENT S* { return { type: "ident", value: $1 }; } / IDENT S* { return { type: "ident", value: $1 }; }
function = FUNCTION S* expr ")" S* { function
return { = FUNCTION S* expr ")" S* {
type: "function", return {
name: $1, type: "function",
params: $3 name: $1,
}; params: $3
} };
}
hexcolor = HASH S* { return { type: "hexcolor", value: $1}; } hexcolor
= HASH S* { return { type: "hexcolor", value: $1}; }
/* ===== Lexical Elements ===== */ /* ===== Lexical Elements ===== */
/* Macros */ /* Macros */
h = [0-9a-fA-F] h
nonascii = [\x80-\xFF] = [0-9a-fA-F]
unicode = "\\" h h? h? h? h? h? ("\r\n" / [ \t\r\n\f])? {
return String.fromCharCode(parseInt("0x" + $2 + $3 + $4 + $5 + $6 + $7)); nonascii
} = [\x80-\xFF]
escape = unicode / "\\" [^\r\n\f0-9a-fA-F] { return $2; }
nmstart = [_a-zA-Z] / nonascii / escape unicode
nmchar = [_a-zA-Z0-9-] / nonascii / escape = "\\" h h? h? h? h? h? ("\r\n" / [ \t\r\n\f])? {
integer = [0-9]+ { return parseInt($1.join("")); } return String.fromCharCode(parseInt("0x" + $2 + $3 + $4 + $5 + $6 + $7));
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(""); } escape
= unicode
comment = "/*" [^*]* "*"+ ([^/*] [^*]* "*"+)* "/" / "\\" [^\r\n\f0-9a-fA-F] { return $2; }
ident = "-"? nmstart nmchar* { return $1 + $2 + $3.join(""); }
name = nmchar+ { return $1.join(""); } nmstart
num = float / integer = [_a-zA-Z]
string = string1 / string2 / nonascii
url = ([!#$%&*-~] / nonascii / escape)* { return $1.join(""); } / escape
s = [ \t\r\n\f]+
w = s? nmchar
nl = "\n" / "\r\n" / "\r" / "\f" = [_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 A
= [aA] = [aA]
/ "\\" "0"? "0"? "0"? "0"? "41" ("\r\n" / [ \t\r\n\f])? { return "A"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "61" ("\r\n" / [ \t\r\n\f])? { return "a"; }
C C
= [cC] = [cC]
/ "\\" "0"? "0"? "0"? "0"? "43" ("\r\n" / [ \t\r\n\f])? { return "C"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "63" ("\r\n" / [ \t\r\n\f])? { return "c"; }
D D
= [dD] = [dD]
/ "\\" "0"? "0"? "0"? "0"? "44" ("\r\n" / [ \t\r\n\f])? { return "D"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "64" ("\r\n" / [ \t\r\n\f])? { return "d"; }
E E
= [eE] = [eE]
/ "\\" "0"? "0"? "0"? "0"? "45" ("\r\n" / [ \t\r\n\f])? { return "E"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "65" ("\r\n" / [ \t\r\n\f])? { return "e"; }
G G
= [gG] = [gG]
/ "\\" "0"? "0"? "0"? "0"? "47" ("\r\n" / [ \t\r\n\f])? { return "G"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "67" ("\r\n" / [ \t\r\n\f])? { return "g"; }
/ "\\" [gG] { return $2; } / "\\" [gG] { return $2; }
H H
= [hH] = [hH]
/ "\\" "0"? "0"? "0"? "0"? "48" ("\r\n" / [ \t\r\n\f])? { return "H"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "68" ("\r\n" / [ \t\r\n\f])? { return "h"; }
/ "\\" [hH] { return $2; } / "\\" [hH] { return $2; }
I I
= [iI] = [iI]
/ "\\" "0"? "0"? "0"? "0"? "49" ("\r\n" / [ \t\r\n\f])? { return "I"; } / "\\" "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"? "4" [bB] ("\r\n" / [ \t\r\n\f])? { return "K"; }
/ "\\" "0"? "0"? "0"? "0"? "6" [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; } / "\\" [kK] { return $2; }
L L
= [lL] = [lL]
/ "\\" "0"? "0"? "0"? "0"? "4" [cC] ("\r\n" / [ \t\r\n\f])? { return "L"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "6" [cC] ("\r\n" / [ \t\r\n\f])? { return "l"; }
/ "\\" [lL] { return $2; } / "\\" [lL] { return $2; }
M M
= [mM] = [mM]
/ "\\" "0"? "0"? "0"? "0"? "4" [dD] ("\r\n" / [ \t\r\n\f])? { return "M"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "6" [dD] ("\r\n" / [ \t\r\n\f])? { return "m"; }
/ "\\" [mM] { return $2; } / "\\" [mM] { return $2; }
N N
= [nN] = [nN]
/ "\\" "0"? "0"? "0"? "0"? "4" [eE] ("\r\n" / [ \t\r\n\f])? { return "N"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "6" [eE] ("\r\n" / [ \t\r\n\f])? { return "n"; }
/ "\\" [nN] { return $2; } / "\\" [nN] { return $2; }
O O
= [oO] = [oO]
/ "\\" "0"? "0"? "0"? "0"? "4" [fF] ("\r\n" / [ \t\r\n\f])? { return "O"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "6" [fF] ("\r\n" / [ \t\r\n\f])? { return "o"; }
/ "\\" [oO] { return $2; } / "\\" [oO] { return $2; }
P P
= [pP] = [pP]
/ "\\" "0"? "0"? "0"? "0"? "50" ("\r\n" / [ \t\r\n\f])? { return "P"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "70" ("\r\n" / [ \t\r\n\f])? { return "p"; }
/ "\\" [pP] { return $2; } / "\\" [pP] { return $2; }
R R
= [rR] = [rR]
/ "\\" "0"? "0"? "0"? "0"? "52" ("\r\n" / [ \t\r\n\f])? { return "R"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "72" ("\r\n" / [ \t\r\n\f])? { return "r"; }
/ "\\" [rR] { return $2; } / "\\" [rR] { return $2; }
S_ S_
= [sS] = [sS]
/ "\\" "0"? "0"? "0"? "0"? "53" ("\r\n" / [ \t\r\n\f])? { return "S"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "73" ("\r\n" / [ \t\r\n\f])? { return "s"; }
/ "\\" [sS] { return $2; } / "\\" [sS] { return $2; }
T T
= [tT] = [tT]
/ "\\" "0"? "0"? "0"? "0"? "54" ("\r\n" / [ \t\r\n\f])? { return "T"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "74" ("\r\n" / [ \t\r\n\f])? { return "t"; }
/ "\\" [tT] { return $2; } / "\\" [tT] { return $2; }
U U
= [uU] = [uU]
/ "\\" "0"? "0"? "0"? "0"? "55" ("\r\n" / [ \t\r\n\f])? { return "U"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "75" ("\r\n" / [ \t\r\n\f])? { return "u"; }
/ "\\" [uU] { return $2; } / "\\" [uU] { return $2; }
X X
= [xX] = [xX]
/ "\\" "0"? "0"? "0"? "0"? "58" ("\r\n" / [ \t\r\n\f])? { return "X"; } / "\\" "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"; } / "\\" "0"? "0"? "0"? "0"? "78" ("\r\n" / [ \t\r\n\f])? { return "x"; }
/ "\\" [xX] { return $2; } / "\\" [xX] { return $2; }
Z Z
= [zZ] = [zZ]
/ "\\" "0"? "0"? "0"? "0"? "5" [aA] ("\r\n" / [ \t\r\n\f])? { return "Z"; } / "\\" "0"? "0"? "0"? "0"? "5" [aA] ("\r\n" / [ \t\r\n\f])? { return "Z"; }
@ -371,36 +456,77 @@ Z
/* Tokens */ /* Tokens */
S "whitespace" = comment* s S "whitespace"
= comment* s
CDO "<!--"
= comment* "<!--"
CDC "-->"
= comment* "-->"
INCLUDES "~="
= comment* "~="
DASHMATCH "|="
= comment* "|="
CDO "<!--" = comment* "<!--" STRING "string"
CDC "-->" = comment* "-->" = comment* string { return $2; }
INCLUDES "~=" = comment* "~="
DASHMATCH "|=" = comment* "|="
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. */ /* 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; } NUMBER "number"
EXS "length" = comment* num E X { return $2 + $3 + $4; } = comment* num { return $2; }
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; }
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; }

File diff suppressed because it is too large Load Diff

@ -2,34 +2,38 @@
/* ===== Syntactical Elements ===== */ /* ===== Syntactical Elements ===== */
start = _ object { return $2; } start
= _ object { return $2; }
object object
= "{" _ "}" _ { return {}; } = "{" _ "}" _ { return {}; }
/ "{" _ members "}" _ { return $3; } / "{" _ members "}" _ { return $3; }
members = pair ("," _ pair)* { members
var result = {}; = pair ("," _ pair)* {
result[$1[0]] = $1[1]; var result = {};
for (var i = 0; i < $2.length; i++) { result[$1[0]] = $1[1];
result[$2[i][2][0]] = $2[i][2][1]; for (var i = 0; i < $2.length; i++) {
} result[$2[i][2][0]] = $2[i][2][1];
return result; }
} return result;
}
pair = string ":" _ value { return [$1, $4]; } pair
= string ":" _ value { return [$1, $4]; }
array array
= "[" _ "]" _ { return []; } = "[" _ "]" _ { return []; }
/ "[" _ elements "]" _ { return $3; } / "[" _ elements "]" _ { return $3; }
elements = value ("," _ value)* { elements
var result = [$1]; = value ("," _ value)* {
for (var i = 0; i < $2.length; i++) { var result = [$1];
result.push($2[i][2]); for (var i = 0; i < $2.length; i++) {
} result.push($2[i][2]);
return result; }
} return result;
}
value value
= string = string
@ -47,7 +51,8 @@ string "string"
= '"' '"' _ { return ""; } = '"' '"' _ { return ""; }
/ '"' chars '"' _ { return $2; } / '"' chars '"' _ { return $2; }
chars = char+ { return $1.join(""); } chars
= char+ { return $1.join(""); }
char char
// In the original JSON grammar: "any-Unicode-character-except-"-or-\-or-control-character" // In the original JSON grammar: "any-Unicode-character-except-"-or-\-or-control-character"
@ -76,13 +81,17 @@ int
/ "-" digit19 digits { return $1 + $2 + $3; } / "-" digit19 digits { return $1 + $2 + $3; }
/ "-" digit { return $1 + $2; } / "-" 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 * 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. * 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*
// Whitespace is undefined in the original JSON grammar, so I assume a simple // Whitespace is undefined in the original JSON grammar, so I assume a simple
// conventional definition consistent with ECMA-262, 5th ed. // conventional definition consistent with ECMA-262, 5th ed.
whitespace = [ \t\n\r] whitespace
= [ \t\n\r]

@ -86,10 +86,10 @@ PEG.grammarParser = (function(){
} }
var result0 = result1 !== null var result0 = result1 !== null
? (function($1, $2) { ? (function($1, $2) {
var result = {}; var result = {};
PEG.ArrayUtils.each($2, function(rule) { result[rule.name] = rule; }); PEG.ArrayUtils.each($2, function(rule) { result[rule.name] = rule; });
return result; return result;
}).apply(null, result1) }).apply(null, result1)
: null; : null;
@ -158,13 +158,13 @@ PEG.grammarParser = (function(){
} }
var result5 = result6 !== null var result5 = result6 !== null
? (function($1, $2, $3, $4) { ? (function($1, $2, $3, $4) {
return { return {
type: "rule", type: "rule",
name: $1, name: $1,
displayName: $2 !== "" ? $2 : null, displayName: $2 !== "" ? $2 : null,
expression: $4 expression: $4
}; };
}).apply(null, result6) }).apply(null, result6)
: null; : null;
@ -234,19 +234,19 @@ PEG.grammarParser = (function(){
} }
var result13 = result14 !== null var result13 = result14 !== null
? (function($1, $2) { ? (function($1, $2) {
if ($2.length > 0) { if ($2.length > 0) {
var alternatives = [$1].concat(PEG.ArrayUtils.map( var alternatives = [$1].concat(PEG.ArrayUtils.map(
$2, $2,
function(element) { return element[1]; } function(element) { return element[1]; }
)); ));
return { return {
type: "choice", type: "choice",
alternatives: alternatives alternatives: alternatives
} }
} else { } else {
return $1; return $1;
} }
}).apply(null, result14) }).apply(null, result14)
: null; : null;
@ -1421,8 +1421,8 @@ PEG.grammarParser = (function(){
} }
var result129 = result130 !== null var result129 = result130 !== null
? (function($1, $2, $3) { ? (function($1, $2, $3) {
return $1 + $2.join(""); return $1 + $2.join("");
}).apply(null, result130) }).apply(null, result130)
: null; : null;
context.reportMatchFailures = savedReportMatchFailures; context.reportMatchFailures = savedReportMatchFailures;
if (context.reportMatchFailures && result129 === null) { if (context.reportMatchFailures && result129 === null) {
@ -1991,20 +1991,22 @@ PEG.grammarParser = (function(){
} }
var result190 = result191 !== null var result190 = result191 !== null
? (function($1, $2, $3, $4, $5) { ? (function($1, $2, $3, $4, $5) {
parts = PEG.ArrayUtils.map($3, function(part) { return part.data; }); parts = PEG.ArrayUtils.map($3, function(part) { return part.data; });
rawText = "[" rawText = "["
+ $2 + $2
+ PEG.ArrayUtils.map($3, function(part) { return part.rawText; }).join("") + PEG.ArrayUtils.map($3, function(part) {
+ "]"; return part.rawText;
}).join("")
+ "]";
return { return {
type: "class", type: "class",
inverted: $2 === "^", inverted: $2 === "^",
parts: parts, parts: parts,
// FIXME: Get the raw text from the input directly. // FIXME: Get the raw text from the input directly.
rawText: rawText rawText: rawText
}; };
}).apply(null, result191) }).apply(null, result191)
: null; : null;
context.reportMatchFailures = savedReportMatchFailures; context.reportMatchFailures = savedReportMatchFailures;
if (context.reportMatchFailures && result190 === null) { if (context.reportMatchFailures && result190 === null) {
@ -2059,18 +2061,18 @@ PEG.grammarParser = (function(){
} }
var result201 = result202 !== null var result201 = result202 !== null
? (function($1, $2, $3) { ? (function($1, $2, $3) {
if ($1.data.charCodeAt(0) > $3.data.charCodeAt(0)) { if ($1.data.charCodeAt(0) > $3.data.charCodeAt(0)) {
throw new this.SyntaxError( throw new this.SyntaxError(
"Invalid character range: " + $1.rawText + "-" + $3.rawText + "." "Invalid character range: " + $1.rawText + "-" + $3.rawText + "."
); );
} }
return { return {
data: [$1.data, $3.data], data: [$1.data, $3.data],
// FIXME: Get the raw text from the input directly. // FIXME: Get the raw text from the input directly.
rawText: $1.rawText + "-" + $3.rawText rawText: $1.rawText + "-" + $3.rawText
} }
}).apply(null, result202) }).apply(null, result202)
: null; : null;
@ -2096,12 +2098,12 @@ PEG.grammarParser = (function(){
var result207 = this._parse_bracketDelimitedCharacter(context); var result207 = this._parse_bracketDelimitedCharacter(context);
var result206 = result207 !== null var result206 = result207 !== null
? (function($1) { ? (function($1) {
return { return {
data: $1, data: $1,
// FIXME: Get the raw text from the input directly. // FIXME: Get the raw text from the input directly.
rawText: PEG.RegExpUtils.quoteForClass($1) rawText: PEG.RegExpUtils.quoteForClass($1)
}; };
})(result207) })(result207)
: null; : null;
@ -2347,14 +2349,14 @@ PEG.grammarParser = (function(){
} }
var result223 = result224 !== null var result223 = result224 !== null
? (function($1, $2, $3) { ? (function($1, $2, $3) {
return $3 return $3
.replace("b", "\b") .replace("b", "\b")
.replace("f", "\f") .replace("f", "\f")
.replace("n", "\n") .replace("n", "\n")
.replace("r", "\r") .replace("r", "\r")
.replace("t", "\t") .replace("t", "\t")
.replace("v", "\x0B") // IE does not recognize "\v". .replace("v", "\x0B") // IE does not recognize "\v".
}).apply(null, result224) }).apply(null, result224)
: null; : null;
@ -2463,8 +2465,8 @@ PEG.grammarParser = (function(){
} }
var result238 = result239 !== null var result238 = result239 !== null
? (function($1, $2, $3) { ? (function($1, $2, $3) {
return String.fromCharCode(parseInt("0x" + $2 + $3)); return String.fromCharCode(parseInt("0x" + $2 + $3));
}).apply(null, result239) }).apply(null, result239)
: null; : null;
@ -2529,8 +2531,8 @@ PEG.grammarParser = (function(){
} }
var result243 = result244 !== null var result243 = result244 !== null
? (function($1, $2, $3, $4, $5) { ? (function($1, $2, $3, $4, $5) {
return String.fromCharCode(parseInt("0x" + $2 + $3 + $4 + $5)); return String.fromCharCode(parseInt("0x" + $2 + $3 + $4 + $5));
}).apply(null, result244) }).apply(null, result244)
: null; : null;

@ -1,34 +1,38 @@
grammar = __ rule+ { grammar
var result = {}; = __ rule+ {
PEG.ArrayUtils.each($2, function(rule) { result[rule.name] = rule; }); var result = {};
return result; PEG.ArrayUtils.each($2, function(rule) { result[rule.name] = rule; });
} return result;
}
rule = identifier (literal / "") equals expression {
return { rule
type: "rule", = identifier (literal / "") equals expression {
name: $1, return {
displayName: $2 !== "" ? $2 : null, type: "rule",
expression: $4 name: $1,
}; displayName: $2 !== "" ? $2 : null,
} expression: $4
};
expression = choice }
choice = sequence (slash sequence)* { expression
if ($2.length > 0) { = choice
var alternatives = [$1].concat(PEG.ArrayUtils.map(
$2, choice
function(element) { return element[1]; } = sequence (slash sequence)* {
)); if ($2.length > 0) {
return { var alternatives = [$1].concat(PEG.ArrayUtils.map(
type: "choice", $2,
alternatives: alternatives function(element) { return element[1]; }
));
return {
type: "choice",
alternatives: alternatives
}
} else {
return $1;
}
} }
} else {
return $1;
}
}
sequence sequence
= prefixed* action { = prefixed* action {
@ -73,13 +77,17 @@ primary
/* "Lexical" elements */ /* "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; } equals = "=" __ { return $1; }
slash = "/" __ { return $1; } slash = "/" __ { return $1; }
@ -107,17 +115,20 @@ dot = "." __ { return $1; }
* The simplifications were made just to make the implementation little bit * The simplifications were made just to make the implementation little bit
* easier, there is no "philosophical" reason behind them. * easier, there is no "philosophical" reason behind them.
*/ */
identifier "identifier" = (letter / "_" / "$") (letter / digit / "_" / "$")* __ { identifier "identifier"
return $1 + $2.join(""); = (letter / "_" / "$") (letter / digit / "_" / "$")* __ {
} return $1 + $2.join("");
}
/* /*
* Modelled after ECMA-262, 5th ed., 7.8.4. (syntax & semantics, rules only * Modelled after ECMA-262, 5th ed., 7.8.4. (syntax & semantics, rules only
* vaguely). * vaguely).
*/ */
literal "literal" = (doubleQuotedLiteral / singleQuotedLiteral) __ { return $1; } literal "literal"
= (doubleQuotedLiteral / singleQuotedLiteral) __ { return $1; }
doubleQuotedLiteral = '"' doubleQuotedCharacter* '"' { return $2.join(""); } doubleQuotedLiteral
= '"' doubleQuotedCharacter* '"' { return $2.join(""); }
doubleQuotedCharacter doubleQuotedCharacter
= simpleDoubleQuotedCharacter = simpleDoubleQuotedCharacter
@ -127,9 +138,11 @@ doubleQuotedCharacter
/ unicodeEscapeSequence / unicodeEscapeSequence
/ eolEscapeSequence / eolEscapeSequence
simpleDoubleQuotedCharacter = !('"' / "\\" / eolChar) . { return $2; } simpleDoubleQuotedCharacter
= !('"' / "\\" / eolChar) . { return $2; }
singleQuotedLiteral = "'" singleQuotedCharacter* "'" { return $2.join(""); } singleQuotedLiteral
= "'" singleQuotedCharacter* "'" { return $2.join(""); }
singleQuotedCharacter singleQuotedCharacter
= simpleSingleQuotedCharacter = simpleSingleQuotedCharacter
@ -139,45 +152,51 @@ singleQuotedCharacter
/ unicodeEscapeSequence / unicodeEscapeSequence
/ eolEscapeSequence / eolEscapeSequence
simpleSingleQuotedCharacter = !("'" / "\\" / eolChar) . { return $2; } simpleSingleQuotedCharacter
= !("'" / "\\" / eolChar) . { return $2; }
class "character class" = "[" "^"? (classCharacterRange / classCharacter)* "]" __ {
parts = PEG.ArrayUtils.map($3, function(part) { return part.data; }); class "character class"
rawText = "[" = "[" "^"? (classCharacterRange / classCharacter)* "]" __ {
+ $2 parts = PEG.ArrayUtils.map($3, function(part) { return part.data; });
+ PEG.ArrayUtils.map($3, function(part) { return part.rawText; }).join("") rawText = "["
+ "]"; + $2
+ PEG.ArrayUtils.map($3, function(part) {
return { return part.rawText;
type: "class", }).join("")
inverted: $2 === "^", + "]";
parts: parts,
// FIXME: Get the raw text from the input directly. return {
rawText: rawText type: "class",
}; inverted: $2 === "^",
} parts: parts,
// FIXME: Get the raw text from the input directly.
classCharacterRange = classCharacter "-" classCharacter { rawText: rawText
if ($1.data.charCodeAt(0) > $3.data.charCodeAt(0)) { };
throw new this.SyntaxError( }
"Invalid character range: " + $1.rawText + "-" + $3.rawText + "."
); classCharacterRange
} = classCharacter "-" classCharacter {
if ($1.data.charCodeAt(0) > $3.data.charCodeAt(0)) {
return { throw new this.SyntaxError(
data: [$1.data, $3.data], "Invalid character range: " + $1.rawText + "-" + $3.rawText + "."
// FIXME: Get the raw text from the input directly. );
rawText: $1.rawText + "-" + $3.rawText }
}
} return {
data: [$1.data, $3.data],
classCharacter = bracketDelimitedCharacter { // FIXME: Get the raw text from the input directly.
return { rawText: $1.rawText + "-" + $3.rawText
data: $1, }
// FIXME: Get the raw text from the input directly. }
rawText: PEG.RegExpUtils.quoteForClass($1)
}; classCharacter
} = bracketDelimitedCharacter {
return {
data: $1,
// FIXME: Get the raw text from the input directly.
rawText: PEG.RegExpUtils.quoteForClass($1)
};
}
bracketDelimitedCharacter bracketDelimitedCharacter
= simpleBracketDelimitedCharacter = simpleBracketDelimitedCharacter
@ -187,53 +206,76 @@ bracketDelimitedCharacter
/ unicodeEscapeSequence / unicodeEscapeSequence
/ eolEscapeSequence / eolEscapeSequence
simpleBracketDelimitedCharacter = !("]" / "\\" / eolChar) . { return $2; } simpleBracketDelimitedCharacter
= !("]" / "\\" / eolChar) . { return $2; }
simpleEscapeSequence = "\\" !(digit / "x" / "u" / eolChar) . {
return $3 simpleEscapeSequence
.replace("b", "\b") = "\\" !(digit / "x" / "u" / eolChar) . {
.replace("f", "\f") return $3
.replace("n", "\n") .replace("b", "\b")
.replace("r", "\r") .replace("f", "\f")
.replace("t", "\t") .replace("n", "\n")
.replace("v", "\x0B") // IE does not recognize "\v". .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 { hexEscapeSequence
return String.fromCharCode(parseInt("0x" + $2 + $3)); = "\\x" hexDigit hexDigit {
} return String.fromCharCode(parseInt("0x" + $2 + $3));
}
unicodeEscapeSequence = "\\u" hexDigit hexDigit hexDigit hexDigit { unicodeEscapeSequence
return String.fromCharCode(parseInt("0x" + $2 + $3 + $4 + $5)); = "\\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)* __ = (whitespace / eol / comment)*
/* Modelled after ECMA-262, 5th ed., 7.4. */ /* 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. */ /* 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. */ /* 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