Your IP : 216.73.216.40


Current Path : /var/www/html/test/wetty2/node_modules/pegjs/examples/
Upload File :
Current File : /var/www/html/test/wetty2/node_modules/pegjs/examples/css.pegjs

/*
 * CSS Grammar
 * ===========
 *
 * Based on grammar from CSS 2.1 specification [1] (including the errata [2]).
 * Generated parser builds a syntax tree composed of nested JavaScript objects,
 * vaguely inspired by CSS DOM [3]. The CSS DOM itself wasn't used as it is not
 * expressive enough (e.g. selectors are reflected as text, not structured
 * objects) and somewhat cumbersome.
 *
 * Limitations:
 *
 *   * Many errors which should be recovered from according to the specification
 *     (e.g. malformed declarations or unexpected end of stylesheet) are fatal.
 *     This is a result of straightforward rewrite of the CSS grammar to PEG.js.
 *
 * [1] http://www.w3.org/TR/2011/REC-CSS2-20110607
 * [2] http://www.w3.org/Style/css2-updates/REC-CSS2-20110607-errata.html
 * [3] http://www.w3.org/TR/DOM-Level-2-Style/css.html
 */

{
  function extractOptional(optional, index) {
    return optional ? optional[index] : null;
  }

  function extractList(list, index) {
    var result = [], i;

    for (i = 0; i < list.length; i++) {
      if (list[i][index] !== null) {
        result.push(list[i][index]);
      }
    }

    return result;
  }

  function buildList(head, tail, index) {
    return (head !== null ? [head] : []).concat(extractList(tail, index));
  }

  function buildExpression(head, tail) {
    var result = head, i;

    for (i = 0; i < tail.length; i++) {
      result = {
        type:     "Expression",
        operator: tail[i][0],
        left:     result,
        right:    tail[i][1]
      };
    }

    return result;
  }
}

start
  = stylesheet:stylesheet comment* { return stylesheet; }

/* ----- G.1 Grammar ----- */

stylesheet
  = charset:(CHARSET_SYM STRING ";")? (S / CDO / CDC)*
    imports:(import (CDO S* / CDC S*)*)*
    rules:((ruleset / media / page) (CDO S* / CDC S*)*)*
    {
      return {
        type:    "StyleSheet",
        charset: extractOptional(charset, 1),
        imports: extractList(imports, 0),
        rules:   extractList(rules, 0)
      };
    }

import
  = IMPORT_SYM S* href:(STRING / URI) S* media:media_list? ";" S* {
      return {
        type:  "ImportRule",
        href:  href,
        media: media !== null ? media : []
      };
    }

media
  = MEDIA_SYM S* media:media_list "{" S* rules:ruleset* "}" S* {
      return {
        type: "MediaRule",
        media: media,
        rules: rules
      };
    }

media_list
  = head:medium tail:("," S* medium)* { return buildList(head, tail, 2); }

medium
  = name:IDENT S* { return name; }

page
  = PAGE_SYM S* selector:pseudo_page?
    "{" S*
    declarationsFirst:declaration?
    declarationsRest:(";" S* declaration?)*
    "}" S*
    {
      return {
        type:         "PageRule",
        selector:     selector,
        declarations: buildList(declarationsFirst, declarationsRest, 2)
      };
    }

pseudo_page
  = ":" value:IDENT S* { return { type: "PseudoSelector", value: value }; }

operator
  = "/" S* { return "/"; }
  / "," S* { return ","; }

combinator
  = "+" S* { return "+"; }
  / ">" S* { return ">"; }

property
  = name:IDENT S* { return name; }

ruleset
  = selectorsFirst:selector
    selectorsRest:("," S* selector)*
    "{" S*
    declarationsFirst:declaration?
    declarationsRest:(";" S* declaration?)*
    "}" S*
    {
      return {
        type:         "RuleSet",
        selectors:    buildList(selectorsFirst, selectorsRest, 2),
        declarations: buildList(declarationsFirst, declarationsRest, 2)
      };
    }

selector
  = left:simple_selector S* combinator:combinator right:selector {
      return {
        type:       "Selector",
        combinator: combinator,
        left:       left,
        right:      right
      };
    }
  / left:simple_selector S+ right:selector {
      return {
        type:       "Selector",
        combinator: " ",
        left:       left,
        right:      right
      };
    }
  / selector:simple_selector S* { return selector; }

simple_selector
  = element:element_name qualifiers:(id / class / attrib / pseudo)* {
      return {
        type:       "SimpleSelector",
        element:    element,
        qualifiers: qualifiers
      };
    }
  / qualifiers:(id / class / attrib / pseudo)+ {
      return {
        type:       "SimpleSelector",
        element:    "*",
        qualifiers: qualifiers
      };
    }

id
  = id:HASH { return { type: "IDSelector", id: id }; }

class
  = "." class_:IDENT { return { type: "ClassSelector", "class": class_ }; }

element_name
  = IDENT
  / "*"

attrib
  = "[" S*
    attribute:IDENT S*
    operatorAndValue:(("=" / INCLUDES / DASHMATCH) S* (IDENT / STRING) S*)?
    "]"
    {
      return {
        type:      "AttributeSelector",
        attribute: attribute,
        operator:  extractOptional(operatorAndValue, 0),
        value:     extractOptional(operatorAndValue, 2)
      };
    }

pseudo
  = ":"
    value:(
        name:FUNCTION S* params:(IDENT S*)? ")" {
          return {
            type:   "Function",
            name:   name,
            params: params !== null ? [params[0]] : []
          };
        }
      / IDENT
    )
    { return { type: "PseudoSelector", value: value }; }

declaration
  = name:property ':' S* value:expr prio:prio? {
      return {
        type:      "Declaration",
        name:      name,
        value:     value,
        important: prio !== null
      };
    }

prio
  = IMPORTANT_SYM S*

expr
  = head:term tail:(operator? term)* { return buildExpression(head, tail); }

term
  = quantity:(PERCENTAGE / LENGTH / EMS / EXS / ANGLE / TIME / FREQ / NUMBER)
    S*
    {
      return {
        type:  "Quantity",
        value: quantity.value,
        unit:  quantity.unit
      };
    }
  / value:STRING S* { return { type: "String", value: value }; }
  / value:URI S*    { return { type: "URI",    value: value }; }
  / function
  / hexcolor
  / value:IDENT S*  { return { type: "Ident",  value: value }; }

function
  = name:FUNCTION S* params:expr ")" S* {
      return { type: "Function", name: name, params: params };
    }

hexcolor
  = value:HASH S* { return { type: "Hexcolor", value: value }; }

/* ----- G.2 Lexical scanner ----- */

/* Macros */

h
  = [0-9a-f]i

nonascii
  = [\x80-\uFFFF]

unicode
  = "\\" digits:$(h h? h? h? h? h?) ("\r\n" / [ \t\r\n\f])? {
      return String.fromCharCode(parseInt(digits, 16));
    }

escape
  = unicode
  / "\\" ch:[^\r\n\f0-9a-f]i { return ch; }

nmstart
  = [_a-z]i
  / nonascii
  / escape

nmchar
  = [_a-z0-9-]i
  / nonascii
  / escape

string1
  = '"' chars:([^\n\r\f\\"] / "\\" nl:nl { return ""; } / escape)* '"' {
      return chars.join("");
    }

string2
  = "'" chars:([^\n\r\f\\'] / "\\" nl:nl { return ""; } / escape)* "'" {
      return chars.join("");
    }

comment
  = "/*" [^*]* "*"+ ([^/*] [^*]* "*"+)* "/"

ident
  = prefix:$"-"? start:nmstart chars:nmchar* {
      return prefix + start + chars.join("");
    }

name
  = chars:nmchar+ { return chars.join(""); }

num
  = [+-]? ([0-9]+ / [0-9]* "." [0-9]+) ("e" [+-]? [0-9]+)? {
      return parseFloat(text());
    }

string
  = string1
  / string2

url
  = chars:([!#$%&*-\[\]-~] / nonascii / escape)* { return chars.join(""); }

s
  = [ \t\r\n\f]+

w
  = s?

nl
  = "\n"
  / "\r\n"
  / "\r"
  / "\f"

A  = "a"i / "\\" "0"? "0"? "0"? "0"? [\x41\x61] ("\r\n" / [ \t\r\n\f])? { return "a"; }
C  = "c"i / "\\" "0"? "0"? "0"? "0"? [\x43\x63] ("\r\n" / [ \t\r\n\f])? { return "c"; }
D  = "d"i / "\\" "0"? "0"? "0"? "0"? [\x44\x64] ("\r\n" / [ \t\r\n\f])? { return "d"; }
E  = "e"i / "\\" "0"? "0"? "0"? "0"? [\x45\x65] ("\r\n" / [ \t\r\n\f])? { return "e"; }
G  = "g"i / "\\" "0"? "0"? "0"? "0"? [\x47\x67] ("\r\n" / [ \t\r\n\f])? / "\\g"i { return "g"; }
H  = "h"i / "\\" "0"? "0"? "0"? "0"? [\x48\x68] ("\r\n" / [ \t\r\n\f])? / "\\h"i { return "h"; }
I  = "i"i / "\\" "0"? "0"? "0"? "0"? [\x49\x69] ("\r\n" / [ \t\r\n\f])? / "\\i"i { return "i"; }
K  = "k"i / "\\" "0"? "0"? "0"? "0"? [\x4b\x6b] ("\r\n" / [ \t\r\n\f])? / "\\k"i { return "k"; }
L  = "l"i / "\\" "0"? "0"? "0"? "0"? [\x4c\x6c] ("\r\n" / [ \t\r\n\f])? / "\\l"i { return "l"; }
M  = "m"i / "\\" "0"? "0"? "0"? "0"? [\x4d\x6d] ("\r\n" / [ \t\r\n\f])? / "\\m"i { return "m"; }
N  = "n"i / "\\" "0"? "0"? "0"? "0"? [\x4e\x6e] ("\r\n" / [ \t\r\n\f])? / "\\n"i { return "n"; }
O  = "o"i / "\\" "0"? "0"? "0"? "0"? [\x4f\x6f] ("\r\n" / [ \t\r\n\f])? / "\\o"i { return "o"; }
P  = "p"i / "\\" "0"? "0"? "0"? "0"? [\x50\x70] ("\r\n" / [ \t\r\n\f])? / "\\p"i { return "p"; }
R  = "r"i / "\\" "0"? "0"? "0"? "0"? [\x52\x72] ("\r\n" / [ \t\r\n\f])? / "\\r"i { return "r"; }
S_ = "s"i / "\\" "0"? "0"? "0"? "0"? [\x53\x73] ("\r\n" / [ \t\r\n\f])? / "\\s"i { return "s"; }
T  = "t"i / "\\" "0"? "0"? "0"? "0"? [\x54\x74] ("\r\n" / [ \t\r\n\f])? / "\\t"i { return "t"; }
U  = "u"i / "\\" "0"? "0"? "0"? "0"? [\x55\x75] ("\r\n" / [ \t\r\n\f])? / "\\u"i { return "u"; }
X  = "x"i / "\\" "0"? "0"? "0"? "0"? [\x58\x78] ("\r\n" / [ \t\r\n\f])? / "\\x"i { return "x"; }
Z  = "z"i / "\\" "0"? "0"? "0"? "0"? [\x5a\x7a] ("\r\n" / [ \t\r\n\f])? / "\\z"i { return "z"; }

/* Tokens */

S "whitespace"
  = comment* s

CDO "<!--"
  = comment* "<!--"

CDC "-->"
  = comment* "-->"

INCLUDES "~="
  = comment* "~="

DASHMATCH "|="
  = comment* "|="

STRING "string"
  = comment* string:string { return string; }

IDENT "identifier"
  = comment* ident:ident { return ident; }

HASH "hash"
  = comment* "#" name:name { return "#" + name; }

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 "

/* We use |s| instead of |w| here to avoid infinite recursion. */
IMPORTANT_SYM "!important"
  = comment* "!" (s / comment)* I M P O R T A N T

EMS "length"
  = comment* value:num E M { return { value: value, unit: "em" }; }

EXS "length"
  = comment* value:num E X { return { value: value, unit: "ex" }; }

LENGTH "length"
  = comment* value:num P X { return { value: value, unit: "px" }; }
  / comment* value:num C M { return { value: value, unit: "cm" }; }
  / comment* value:num M M { return { value: value, unit: "mm" }; }
  / comment* value:num I N { return { value: value, unit: "in" }; }
  / comment* value:num P T { return { value: value, unit: "pt" }; }
  / comment* value:num P C { return { value: value, unit: "pc" }; }

ANGLE "angle"
  = comment* value:num D E G   { return { value: value, unit: "deg"  }; }
  / comment* value:num R A D   { return { value: value, unit: "rad"  }; }
  / comment* value:num G R A D { return { value: value, unit: "grad" }; }

TIME "time"
  = comment* value:num M S_ { return { value: value, unit: "ms" }; }
  / comment* value:num S_   { return { value: value, unit: "s"  }; }

FREQ "frequency"
  = comment* value:num H Z   { return { value: value, unit: "hz" }; }
  / comment* value:num K H Z { return { value: value, unit: "kh" }; }

PERCENTAGE "percentage"
  = comment* value:num "%" { return { value: value, unit: "%" }; }

NUMBER "number"
  = comment* value:num { return { value: value, unit: null }; }

URI "uri"
  = comment* U R L "("i w url:string w ")" { return url; }
  / comment* U R L "("i w url:url w ")"    { return url; }

FUNCTION "function"
  = comment* name:ident "(" { return name; }