Skip to content

Instantly share code, notes, and snippets.

@EduardoRFS
Created September 30, 2020 13:42
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 EduardoRFS/ab5825d280f1a651123a044fbd9bc53e to your computer and use it in GitHub Desktop.
Save EduardoRFS/ab5825d280f1a651123a044fbd9bc53e to your computer and use it in GitHub Desktop.
%{
open! Location
open! New_css_types
open! Helpers
%}
%token EOF
%token <string> IDENT
%token BAD_IDENT
%token <string> FUNCTION
%token <string> AT_KEYWORD
%token <string * [ `ID | `UNRESTRICTED ]> HASH
%token <string> STRING
%token <string> BAD_STRING
%token <string> URL
%token BAD_URL
%token <string> DELIM
%token <float> NUMBER
%token <float> PERCENTAGE
%token <float * string> DIMENSION
%token WHITESPACE
%token CDO
%token CDC
%token COLON
%token SEMICOLON
%token COMMA
%token LEFT_SQUARE
%token RIGHT_SQUARE
%token LEFT_PARENS
%token RIGHT_PARENS
%token LEFT_CURLY
%token RIGHT_CURLY
%token NEXT_IS_RULE
%token NEXT_IS_DECLARATION
%start <New_css_types.rule option> option_rule
%%
(* all tokens except SEMICOLON, LEFT_CURLY and RIGHT_CURLY *)
let prelude_token ==
| v = IDENT; { IDENT(v) }
| v = FUNCTION; { FUNCTION(v) }
| v = AT_KEYWORD; { AT_KEYWORD(v) }
| v = HASH; { HASH(v) }
| v = STRING; { STRING(v) }
| v = URL; { URL(v) }
| v = DELIM; { DELIM(v) }
| v = NUMBER; { NUMBER(v) }
| v = PERCENTAGE; { PERCENTAGE(v) }
| v = DIMENSION; { DIMENSION(v) }
| WHITESPACE; { WHITESPACE }
| CDO; { CDO }
| CDC; { CDC }
| COLON; { COLON }
| COMMA; { COMMA }
| LEFT_SQUARE; { LEFT_SQUARE }
| RIGHT_SQUARE; { RIGHT_SQUARE }
| LEFT_PARENS; { LEFT_PARENS }
| RIGHT_PARENS; { RIGHT_PARENS }
let prelude_token_with_loc == | d = prelude_token; { loc $loc(d) d }
let prelude := | ts = nonempty_list(prelude_token_with_loc); { ts }
let declaration ==
| list(WHITESPACE); k = IDENT; list(WHITESPACE); COLON;
v = nonempty_list(prelude_token_with_loc); {
let (value, important) = declaration_value v in
{ name = loc $loc(k) k; value; important }
}
let is_declaration := | NEXT_IS_DECLARATION
let is_rule := | NEXT_IS_RULE
let block_value :=
(* I couldn't figure it out a way without lookahead for this *)
| is_declaration; d = declaration; { Declaration(d) }
| is_rule; r = rule; { Rule(r) }
let block_value_with_loc == | b = block_value; { loc $loc(b) b }
let block :=
| RIGHT_CURLY; { [] }
| v = block_value_with_loc; RIGHT_CURLY; { [v] }
| v = block_value_with_loc; SEMICOLON; vs = block; { v :: vs }
(* https://drafts.csswg.org/css-syntax-3/#consume-qualified-rule *)
let rule :=
| p = prelude; LEFT_CURLY; b = block; EOF; {
let prelude = loc $loc(p) p in
let block = loc $loc(b) b in
{ kind = Style; prelude; block }
}
let option_rule :=
| r = rule; EOF; { Some(r) }
| EOF; { None }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment