d4tocchini
6/27/2014 - 3:09 PM

selector parser

selector parser

{
  var p; 

  p = this;
  
  p.toString = function (x) {
    if (typeof x === "string") {return x}
    if (x instanceof Array) {return x.join("")}
    return ""
  }

}

start
  = Selector



Selector
  = "(" _ chain:SelectorFilter _ ")" {return chain;}
  / left:AtomicSelector _ {return left;}


SelectorFilter
  = filters:AtomicSelector+  {
    var i, len;
    len = filters.length;
    for (i=len-1; i>0; i--) {
      filters[i].splice(1,0,filters[i-1]);
    }
    return filters[len-1];
  }

Combinator "Combinator"
  = _ c:([,><+~!]) _ {return c}
  / " "+ {return " "}

AtomicSelector "AtomicSelector"
  = VirtualSelector / TagSel / IdSel / ClassSel / PseudoSel / AttrSel
  / c:Combinator {return ["$combin",c]}

VirtualSelector
  = ["] id:[^"]+ ["] {
    id = id.join("");
    return ["$virtual",id];
}

TagSel
  = name:SelectorName {return ["$tag",name];}
  / "*" {return ["$*"];}
  
IdSel
  = "#" name:SelectorName {
    return ["$id",name];
  }

ClassSel
  = "." name:SelectorName {
    return ["$class",name];
  }

ReservedSel
  =

PseudoSel
  = ("::" / ":") name:SelectorName option:PseudoSelOption? {
    if (option) {return ["$pseudo",name,option];}
    return ["$pseudo",name];
  }
  
PseudoSelOption
  = "(" option:[^)]* ")" {
    return option.join("");
  }

AttrSel
  = "[" attr:[^\]]+ "]" {
    return ["attr",attr.join("")];
}

SelectorName
  = name:SelectorNameChars+ {return name.join("")}

SelectorNameChars
  = [a-zA-Z0-9\-_$]




SourceCharacter
  = .

WhiteSpace "whitespace"
  = [\t\v\f \u00A0\uFEFF]

LineTerminator
  = [\n\r\u2028\u2029]

LineTerminatorSequence "end of line"
  = "\n"
  / "\r\n"
  / "\r"
  / "\u2028" // line separator
  / "\u2029" // paragraph separator

EOS
  = __ ";"
  / _ LineTerminatorSequence
  / __ EOF

EOF
  = !.

Comment "comment"
  = MultiLineComment
  / SingleLineComment

MultiLineComment
  = "/*" (!"*/" SourceCharacter)* "*/"

MultiLineCommentNoLineTerminator
  = "/*" (!("*/" / LineTerminator) SourceCharacter)* "*/"

SingleLineComment
  = "//" (!LineTerminator SourceCharacter)* (LineTerminator / EOF)
_
  = (WhiteSpace / MultiLineCommentNoLineTerminator / SingleLineComment)*

__
  = (WhiteSpace / LineTerminatorSequence / Comment)*