Posted to tcl by colin at Mon Mar 11 22:29:23 GMT 2013view pretty

PEG css (stylesheet)

leaf: CharSpecial	<- "\\" [nrt'"\[\]\\] ;
leaf: CharUnicode	<- "\\" HexDigit (HexDigit (HexDigit HexDigit?)?)? ;
leaf: CharUnescaped	<- !"\\" . ;
leaf: Ident		<- ('_' / <alpha>) ('_' / <alnum>)* ;
	Char            <- CharSpecial / CharUnicode / CharUnescaped;

void:   EOL             <- "\n\r" / "\n" / "\r" ;
void:   APOSTROPH       <- "'";
void:   DAPOSTROPH      <- '"';

void:	COMMENT		<- "/*" ([^*] [/] / "*" [^/] / nl)* "*/" ;
void:	WS		<- (" " / "\t" / EOL / COMMENT)*;

void: HexDigit	<- [0-9a-fA-F] ;

Literal	<- APOSTROPH  (!APOSTROPH  Char)* APOSTROPH / DAPOSTROPH (!DAPOSTROPH Char)* DAPOSTROPH ;

leaf: CDO <- "<!--";
leaf: CDC <- "-->";
leaf: INCLUDES <- "~=";
leaf: DASHMATCH <- "|=";

leaf: HASH <- "#" Ident;

Uri	<- "url" WS Literal WS;

Function <- Ident WS "(";

leaf: LBRACKET <- "[";
leaf: RBRACKET <- "]";
void: LBRACE <- "{";
void: RBRACE <- "}";
void: LPAREN <- "(";
void: RPAREN <- ")";
leaf: STAR <- "*";
void: SEMI <- [;+];

# stylesheet
#   : [ CHARSET_SYM STRING ';' ]?
#     [S|CDO|CDC]* [ import [ CDO S* | CDC S* ]* ]*
#     [ [ ruleset | media | page ] [ CDO S* | CDC S* ]* ]*
#   ;
leaf: CHARSET <- "@" [Cc][Hh][Aa][Rr][Ss][Ee][Tt];
stylesheet <- WS CHARSET Literal SEMI stylesheet /
	WS (ruleset / import / media / page) stylesheet;

# import
#   : IMPORT_SYM S*
#     [STRING|URI] S* media_list? ';' S*
#   ;
leaf: IMPORT <- [Ii][Mm][Pp][Oo][Rr][Tt];
import <- IMPORT WS Literal WS media_list WS SEMI
	/ IMPORT WS Literal WS SEMI
	/ IMPORT WS Uri WS media_list WS SEMI
	/ IMPORT WS Uri WS SEMI;

# media
#   : MEDIA_SYM WS media_list '{' WS ruleset* '}' WS
#   ;
leaf: MEDIA <- [Mm][Ee][Dd][Ii][Aa];
media <- MEDIA WS media_list LBRACE WS ruleset_seq RBRACE;
    
ruleset_seq <- ruleset ruleset_seq / ruleset;

# media_list
#   : medium [ COMMA WS medium]*
#   ;
media_list <- Ident WS COMMA WS media_list / Ident;

# page
#   : PAGE_SYM WS pseudo_page?
#     '{' WS declaration? [ ';' WS declaration? ]* '}' WS
#   ;
leaf: PAGE <- [Pp][Aa][Gg][Ee];
page <- PAGE WS pseudo_page WS LBRACE WS declaration_seq RBRACE
	/ PAGE WS LBRACE WS declaration_seq RBRACE;

# pseudo_page
#   : ':' IDENT WS
#   ;
pseudo_page <- ":" Ident;
    
# operator
#   : '/' WS | ',' WS
#   ;
operator <- [/,=];
    
# combinator
#   : '+' WS
#   | '>' WS
#   ;
combinator <- [+>];
	
# unary_operator
#   : '-' | '+'
#   ;
unary_operator <- [-+];
	
# property
#   : IDENT WS
#   ;
property <- Ident;
	
# ruleset
#   : selector [ ',' WS selector ]*
#     '{' WS declaration? [ ';' WS declaration? ]* '}' WS
#   ;
ruleset <- selector_seq WS LBRACE WS declaration_seq RBRACE;
    
selector_seq <- selector WS COMMA WS selector_seq / selector;

declaration_seq <- declaration SEMI WS declaration_seq / declaration;
    
	
# selector
#   : simple_selector [ combinator selector | S+ [ combinator? selector ]? ]?
#   ;
selector <- simple_selector / simple_selector WS combinator WS selector / simple_selector S WS combinator WS selector / simple_selector S WS selector;
    
# simple_selector
#   : element_name [ HASH | class | attrib | pseudo ]*
#   | [ HASH | class | attrib | pseudo ]+
#   ;
simple_selector <- element_name selector_sub / element_name / selector_sub;

selector_sub <- HASH selector_sub 
	/ class selector_sub
	/ attrib selector_sub 
	/ pseudo selector_sub 
	/ HASH 
	/ class 
	/ attrib
	/ pseudo;
	
# class
#   : '.' IDENT
#   ;
class <- DOT Ident;
	
# element_name
#   : IDENT | '*'
#   ;
element_name <- Ident / STAR;
    
# attrib
#   : '[' WS IDENT WS [ [ '=' | INCLUDES | DASHMATCH ] WS
#     [ IDENT | Literal ] WS ]? ']'
#   ;
attrib <- LBRACKET WS IDENT WS RBRACKET /
	LBRACKET WS IDENT WS "=" WS IDENT WS RBRACKET /
	LBRACKET WS IDENT WS "=" WS Literal WS RBRACKET /
	LBRACKET WS IDENT WS INCLUDES WS IDENT WS RBRACKET /
	LBRACKET WS IDENT WS INCLUDES WS Literal WS RBRACKET /
	LBRACKET WS IDENT WS DASHMATCH WS IDENT WS RBRACKET /
	LBRACKET WS IDENT WS DASHMATCH WS Literal WS RBRACKET;
	
# pseudo
#   : ':' [ IDENT | FUNCTION WS [IDENT WS]? ')' ]
#   ;
pseudo <- ":" IDENT / ":" FUNCTION WS RPAREN / ":" FUNCTION WS IDENT WS RPAREN;
    
# declaration
#   : property ':' WS expr prio?
#   ;
leaf: IMPORTANT <- "!" WS [Ii][Mm][Pp][Oo][Rr][Tt][Aa][Nn][Tt];

declaration <- property WS ":" WS expr / property WS ":" WS expr WS IMPORTANT;
	
# expr
#   : term [ operator? term ]*
#   ;
expr <- term / term WS expr WS / term WS operator WS expr;

# term
#   : unary_operator?
#     [ NUMBER WS | PERCENTAGE WS | LENGTH WS | EMS WS | EXS WS | ANGLE WS |
#       TIME WS | FREQ WS ]
#   | Literal WS | IDENT WS | URI WS | hexcolor | function
#   ;
term <- unary_operator term_numeric / term_numeric / Literal / Ident / Uri / hexcolor / function;
Digits <- [0-9]+;
Length <- Digits ([Pp][Xx] / [Cc][Mm] / [Mm][Mm] / [Ii][Nn] / [Pp][Tt] / [Pp][Cc]);
Angle <- Digits ([Dd][Ee][Gg] / [Rr][Aa][Dd] / [Gg][Rr][Aa][Dd]);
Time <- Digits ([Mm][Ss] / [Ss]);
Freq <- Digits ([Hh][Zz] / [Kk][Hh][Zz]);
Dimension <- "<digit>"+ Ident;
Percentage <- "<digit>" "%";
Sign	<- [-+];
Number	<- Sign? "<ddigit>"+;
EMS <- Digits [Ee][Mm];
EXS <- Digits [Ee][Xx];

term_numeric <- Number / Percentage / Length / EMS / EXS / Angle / Time / Freq;
	
# function
#   : FUNCTION WS expr ')' WS
#   ;
function <- Function WS expr RPAREN WS;

# /*
#  * There is a constraint on the color that it must
#  * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
#  * after the "#"; e.g., "#000" is OK, but "#abcd" is not.
#  */
# hexcolor
#   : HASH WS
#   ;
hexcolor <- Hash;
END;