Browse Source

[Project] Add css syntax (adopted from ebnf)

tags/3.0
Vsevolod Stakhov 3 years ago
parent
commit
e422091bab
1 changed files with 110 additions and 0 deletions
  1. 110
    0
      src/libserver/css/css_syntax.rl

+ 110
- 0
src/libserver/css/css_syntax.rl View File

@@ -0,0 +1,110 @@
%%{
# CSS3 EBNF derived
machine css_syntax;

# Primitive Atoms
COMMENT = (
'/*' ( any )* :>> '*/'
);
QUOTED_STRING = ('"' ( [^"\\] | /\\./ )* "'");
BARE_URL_CHARS = ((0x21
| 0x23..0x26
| 0x2A..0xFF)+);
BARE_URL = BARE_URL_CHARS;
URL = 'url(' ( QUOTED_STRING | space* BARE_URL space* ) ')';
nonascii = [^0x00-0x7F];
nmstart = ([_a-zA-Z] | nonascii);
nmchar = ([_a-zA-Z0-9] | 0x2D | nonascii);
name = nmchar+;
num = ([0-9]+ | ([0-9]* '.' [0-9]+));
CRLF = "\r\n" | ("\r" [^\n]) | ([^\r] "\n");
IDENT = ([\-]? nmstart nmchar*);
ATTR = 'attr(' IDENT ')';

DIMENSION = '-'? num space? ( 'ch' | 'cm' | 'em' | 'ex' | 'fr' | 'in' | 'mm' | 'pc' | 'pt' | 'px' | 'Q' | 'rem' | 'vh' | 'vmax' | 'vmin' | 'vw' | 'dpi' );
NUMBER = '-'? num;
HASH = '#' name;
HEX = '#' [0-9a-fA-F]{1,6};
PERCENTAGE = '-'? num '%';
INCLUDES = '~=';
DASHMATCH = '|=';
PREFIXMATCH = '^=';
SUFFIXMATCH = '$=';
SUBSTRINGMATCH = '*=';
PLUS = '+';
GREATER = '>';
COMMA = ',';
TILDE = '~';
S = space;

# Property name
property = ( QUOTED_STRING | IDENT );

# Values
important = space* '!' space* 'important';
expression = ( ( '+' | PERCENTAGE | URL | ATTR | HEX | '-' | DIMENSION | NUMBER | QUOTED_STRING | IDENT | ',') S* )+;
functional_pseudo = (IDENT - ('attr'|'url')) '(' space* expression? ')';
value = ( URL | ATTR | PLUS | HEX | PERCENTAGE | '-' | DIMENSION | NUMBER | QUOTED_STRING | IDENT | functional_pseudo);
values = value (space value | '/' value )* ( space* ',' space* value (space value | '/' value )* )* important?;

# Declaration definition
declaration = (property space? ':' (property ':')* space? values);

# Selectors
class = '.' IDENT;
element_name = IDENT;
namespace_prefix = ( IDENT | '*' )? '|';
type_selector = namespace_prefix? element_name;
universal = namespace_prefix? '*';
attrib = '[' space* namespace_prefix? IDENT space* ( ( PREFIXMATCH | SUFFIXMATCH | SUBSTRINGMATCH | '=' | INCLUDES | DASHMATCH ) space* ( IDENT | QUOTED_STRING ) space* )? ']';
pseudo = ':' ':'? ( IDENT | functional_pseudo );
atrule = '@' IDENT;
mediaquery_selector = '(' declaration ')';
negation_arg = type_selector
| universal
| HASH
| class
| attrib
| pseudo;
negation = 'NOT'|'not' space* negation_arg space* ')';
# Haha, so simple...
# there should be also mediaquery_selector but it makes grammar too large, so rip it off
simple_selector_sequence = ( type_selector | universal ) ( HASH | class | attrib | pseudo | negation | atrule )*
| ( HASH | class | attrib | pseudo | negation | atrule )+;
combinator = space* PLUS space*
| space* GREATER space*
| space* TILDE space*
| space+;
# Combine simple stuff and obtain just... an ordinary selector, bingo
selector = simple_selector_sequence ( combinator simple_selector_sequence )*;
# Multiple beasts
selectors_group = selector ( COMMENT? ',' space* selector )*;

# Rules
# This is mostly used stuff
rule = selectors_group space? "{" space*
(COMMENT? space* declaration ( space? ";" space? declaration?)* ";"? space?)* COMMENT* space* '}';
query_declaration = rule;

# Areas used in css
arearule = '@'('bottom-left'|'bottom-right'|'top-left'|'top-right');
areaquery = arearule space? '{' space* (COMMENT? space* declaration ( S? ';' S? declaration?)* ';'? space?)* COMMENT* space* '}';
# Printed media stuff, useless but we have to parse it :(
printcssrule = '@media print';
pagearea = ':'('left'|'right');
pagerule = '@page' space? pagearea?;
pagequery = pagerule space? '{' space* (areaquery| (COMMENT? space* declaration ( space? ';' space? declaration?)* ';'? S?)*) COMMENT* space* '}';
printcssquery = printcssrule S? '{' ( S? COMMENT* S? (pagequery| COMMENT|query_declaration) S*)* S? '}';
# Something that defines media
conditions = ('and'|'screen'|'or'|'only'|'not'|'amzn-mobi'|'amzn-kf8'|'amzn-mobi7'|',');
mediarule = '@media' space conditions ( space? conditions| space? mediaquery_selector )*;
mediaquery = mediarule space? '{' ( space? COMMENT* query_declaration)* S? '}';

simple_atrule = ("@charset"|"@namespace") space+ QUOTED_STRING space* ";";

import_rule = "@import" space+ ( QUOTED_STRING | URL ) space* ";";

# Final css definition
css_style = space* ( ( rule | simple_atrule | import_rule | mediaquery | printcssquery | COMMENT) space* )*;

}%%

Loading…
Cancel
Save