CSS-Selector-Grammar

 view release on metacpan or  search on metacpan

lib/CSS/Selector/Grammar.pm  view on Meta::CPAN

package CSS::Selector::Grammar;
$CSS::Selector::Grammar::VERSION = '0.002';
# ABSTRACT: Generate parse trees for CSS3 selectors.


use v5.10;
use strict;
use warnings;

use parent 'Exporter';

our @EXPORT = qw(parse_selector);

{
    use Regexp::Grammars;

    # lexemes
    qr/

    <grammar: CSS3::Lexemes>
    <nocontext:>
    
    <token: ident>     [-]?<.nmstart><.nmchar>*
    <token: name>      <.nmchar>+
    <token: nmstart>   [_a-zA-Z]|<.nonascii>|<.escape>
    <token: nonascii>  [^\0-\177]
    <token: unicode>   \\[0-9a-fA-F]{1,6}(?:\r\n|[ \n\r\t\f])?+
    <token: escape>    <.unicode>|\\[^\n\r\f0-9a-f]
    <token: nmchar>    [_a-zA-Z0-9-]|<.nonascii>|<.escape>
    <token: num>       [0-9]+|[0-9]*\.[0-9]++
    <token: string>    <.string1>|<.string2>
    <token: string1>   \"(?:[^\n\r\f\\"]|\\<.nl>|<.nonascii>|<.escape>)*+\"
    <token: string2>   \'(?:[^\n\r\f\\']|\\<.nl>|<.nonascii>|<.escape>)*+\'
    <token: invalid>   <.invalid1>|<.invalid2>
    <token: invalid1>  \"(?:[^\n\r\f\\"]|\\<.nl>|<.nonascii>|<.escape>)*+
    <token: invalid2>  \'(?:[^\n\r\f\\']|\\<.nl>|<.nonascii>|<.escape>)*+
    <token: nl>        \n|\r\n|\r|\f
    <token: w>         [ \t\r\n\f]*+
    
    <token: D>         (?i:d|\\0{0,4}(?:44|64)(?:\r\n|[ \t\r\n\f])?)
    <token: E>         (?i:e|\\0{0,4}(?:45|65)(?:\r\n|[ \t\r\n\f])?)
    <token: N>         (?i:n|\\0{0,4}(?:4e|6e)(?:\r\n|[ \t\r\n\f])?|\\n)
    <token: O>         (?i:o|\\0{0,4}(?:4f|6f)(?:\r\n|[ \t\r\n\f])?|\\o)
    <token: T>         (?i:t|\\0{0,4}(?:54|74)(?:\r\n|[ \t\r\n\f])?|\\t)
    <token: V>         (?i:v|\\0{0,4}(?:58|78)(?:\r\n|[ \t\r\n\f])?|\\v)
    
    <token: S> [ \t\r\n\f]+
    
    <token: INCLUDES>       ~=
    <token: DASHMATCH>      \|=
    <token: PREFIXMATCH>    \^=
    <token: SUFFIXMATCH>    \$=
    <token: SUBSTRINGMATCH> \*=
    <token: IDENT>          <context:> <i=(?{$INDEX})> <.ident>
    <token: STRING>         <context:> <i=(?{$INDEX})> <.string>
    <token: FUNCTION>       <context:> <i=(?{$INDEX})> <.ident> \(
    <token: NUMBER>         <context:> <i=(?{$INDEX})> <.num>
    <token: HASH>           <context:> <i=(?{$INDEX})> \# <.name>
    <token: PLUS>           <.w> \+
    <token: GREATER>        <.w> \>
    <token: COMMA>          <.w> ,
    <token: TILDE>          <.w> ~
    <token: NOT>            : <.N><.O><.T> \(
    <token: ATKEYWORD>      <context:> <i=(?{$INDEX})> @ <.ident>
    <token: INVALID>        <context:> <i=(?{$INDEX})> <.invalid>
    <token: PERCENTAGE>     <context:> <i=(?{$INDEX})> <.num> %
    <token: DIMENSION>      <context:> <i=(?{$INDEX})> <.num> <.ident>
    <token: CDO>            <context:> <i=(?{$INDEX})> \<!--
    <token: CDC>            --\>

    /x;

    # productions
    qr/

    <grammar: CSS3::Selectors>
    <extends: CSS3::Lexemes>
    
    <token: selectors_group>
        <[selector]> (?: <.COMMA> <.S>* <[selector]> )*
    
    <token: selector>
        <first=simple_selector_sequence> <[combined_simple_selector]>*
    
    <token: combined_simple_selector>
        <combinator> <simple_selector_sequence>
    
    <token: combinator>



( run in 1.279 second using v1.01-cache-2.11-cpan-d7f47b0818f )