Skip to content

Instantly share code, notes, and snippets.

Created September 6, 2010 21:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/567539 to your computer and use it in GitHub Desktop.
Save anonymous/567539 to your computer and use it in GitHub Desktop.
use v6;
grammar CSS {
# http://www.w3.org/TR/css3-syntax/#tokenization
rule ident { '-'? <nmstart> <nmchar>* }
rule name { <nmchar>+ }
rule nmstart { <[a..zA..Z_]> | <nonascii> | <escape> }
rule nonascii { <[\x80..\xd7ff\xe000..\xfffd\x10000..\x10ffff]> }
rule unicode { '\\' <xdigit>**1..6 <wc>? }
rule escape { '\\' <[\x20..\x7e]> | <unicode> | <nonascii> }
rule nmchar { <nmstart> | <digit> | '-' }
rule num { <digit>* '.' <digit>+ | <digit>+ }
rule string { '"' ~ '"' [ <stringchar> | "'" ]*
| "'" ~ "'" [ <stringchar> | '"' ]* }
rule stringchar { <urlchar> | ' ' | '\\' <nl> }
rule urlchar { <nmstart> | <[\x9\x21\x23..\x26\x27..\x7e]> }
rule nl { "\n" | "\r\n" | "\r" | "\xc" }
rule w { <wc>* }
rule wc { "\t" | "\n" | "\xc" | "\xd" | ' ' }
rule IDENT { <ident> }
rule ATKEYWORD { '@' <ident> }
rule STRING { <string> }
rule HASH { '#' <name> }
rule NUMBER { <num> }
rule PERCENTAGE { <num> '%' }
rule DIMENSION { <num> <ident> }
rule URI { 'url(' <w> [ <string> | <urlchar> ]* <w> ')' }
rule UNICODE_RANGE { 'U+' <[0..9A..F]>**1..6 [ '-' <[0..9A..F]>**1..6 ]? }
rule CDO { '<!--' }
rule CDC { '-->' }
rule S { <wc>+ }
rule COMMENT { '/*' <[^*]>* '*'+ [ <[^/]> <[^*]>* '*'+ ]* '/' }
rule FUNCTION { <ident> '(' }
rule INCLUDES { '~=' }
rule DASHMATCH { '|=' }
rule PREFIXMATCH { '^=' }
rule SUFFIXMATCH { '$=' }
rule SUBSTRINGMATCH { '*=' }
rule CHAR { <[^'"]> }
# http://www.w3.org/TR/css3-syntax/#style
token TOP { [ <CDO> | <CDC> | <S> | <statement> ]* }
token statement { <ruleset> | <at_rule> }
token at_rule { <ATKEYWORD> <S>* <css_any>* [ <block> | ';' <S>* ] }
token block { '{' ~ [ '}' <S>* ] <S>* [ <css_any> | <block> | <ATKEYWORD> <S>* | ';' <S>* ]* }
token ruleset { <selector>? '{' <S>* <declaration>? [ ';' <S>* <declaration>? ]* '}' <S>* }
token selector { <css_any>+ }
token declaration { <property> ':' <S>* <value> }
token property { <IDENT> <S>* }
token value { [ <css_any> | <block> | <ATKEYWORD> <S>* ]+ }
token css_any { [ <IDENT> | <NUMBER> | <PERCENTAGE> | <DIMENSION> | <STRING> | <CHAR>
| <URI> | <HASH> | <UNICODE_RANGE> | <INCLUDES>
| <FUNCTION> <S>* <css_any>* ')' | <DASHMATCH>
| '(' <S>* <css_any>* ')' | '[' <S>* <css_any>* ']'
] <S>* }
}
sub MAIN {
# Should all parse
my @tests = (
abc => 'ident',
ab => 'ident',
a => 'ident',
abc => 'name',
ab => 'name',
a => 'name',
);
for @tests {
say "$_ \t", CSS.parse($_.key, :rule($_.value)).Bool;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment