aboutsummaryrefslogtreecommitdiff
path: root/css/lib/menhir_parser.mly
diff options
context:
space:
mode:
Diffstat (limited to 'css/lib/menhir_parser.mly')
-rwxr-xr-xcss/lib/menhir_parser.mly196
1 files changed, 196 insertions, 0 deletions
diff --git a/css/lib/menhir_parser.mly b/css/lib/menhir_parser.mly
new file mode 100755
index 0000000..fb5a1cf
--- /dev/null
+++ b/css/lib/menhir_parser.mly
@@ -0,0 +1,196 @@
+%{
+
+(* Workaround for this dune bug: https://github.com/ocaml/dune/issues/2450 *)
+module Css = struct end
+
+open Types
+
+%}
+
+%token EOF
+%token LEFT_BRACE
+%token RIGHT_BRACE
+%token LEFT_PAREN
+%token RIGHT_PAREN
+%token LEFT_BRACKET
+%token RIGHT_BRACKET
+%token COLON
+%token DOT
+(* Whitespaces are detected only in selectors, before ":", ".", and "#", to
+ * disambiguate between "p :first-child" and "p:first-child", these
+ * whitespaces are replaced with "*" *)
+%token WHITESPACE
+%token SEMI_COLON
+%token PERCENTAGE
+%token IMPORTANT
+%token <string> IDENT
+%token <string> STRING
+%token <string> URI
+%token <string> OPERATOR
+%token <string> DELIM
+%token <string> NESTED_AT_RULE
+%token <string> AT_RULE_WITHOUT_BODY
+%token <string> AT_RULE
+%token <string> FUNCTION
+%token <string> HASH
+%token <string> NUMBER
+%token <string> UNICODE_RANGE
+%token <string * string * Types.dimension> FLOAT_DIMENSION
+%token <string * string> DIMENSION
+
+%start <Types.Stylesheet.t> stylesheet
+%start <Types.Declaration_list.t> declaration_list
+
+%%
+
+stylesheet:
+ s = stylesheet_without_eof; EOF { s }
+ ;
+
+stylesheet_without_eof:
+ rs = list(rule) { (rs, Lex_buffer.make_loc_and_fix $startpos $endpos) }
+ ;
+
+declaration_list:
+ ds = declarations_with_loc; EOF { ds }
+ ;
+
+rule:
+ | r = at_rule { Rule.At_rule r }
+ | r = style_rule { Rule.Style_rule r }
+ ;
+
+at_rule:
+ | name = AT_RULE_WITHOUT_BODY; xs = prelude_with_loc; SEMI_COLON {
+ { At_rule.name = (name, Lex_buffer.make_loc_and_fix $startpos(name) $endpos(name));
+ prelude = xs;
+ block = Brace_block.Empty;
+ loc = Lex_buffer.make_loc_and_fix $startpos $endpos;
+ }
+ }
+ | name = NESTED_AT_RULE; xs = prelude_with_loc; LEFT_BRACE; s = stylesheet_without_eof; RIGHT_BRACE {
+ { At_rule.name = (name, Lex_buffer.make_loc_and_fix $startpos(name) $endpos(name));
+ prelude = xs;
+ block = Brace_block.Stylesheet s;
+ loc = Lex_buffer.make_loc_and_fix $startpos $endpos;
+ }
+ }
+ | name = AT_RULE; xs = prelude_with_loc; LEFT_BRACE; ds = declarations_with_loc; RIGHT_BRACE {
+ { At_rule.name = (name, Lex_buffer.make_loc_and_fix $startpos(name) $endpos(name));
+ prelude = xs;
+ block = Brace_block.Declaration_list ds;
+ loc = Lex_buffer.make_loc_and_fix $startpos $endpos;
+ }
+ }
+ ;
+
+style_rule:
+ | xs = prelude_with_loc; LEFT_BRACE; RIGHT_BRACE {
+ { Style_rule.prelude = xs;
+ block = [], Location.none;
+ loc = Lex_buffer.make_loc_and_fix $startpos $endpos;
+ }
+ }
+ | xs = prelude_with_loc; LEFT_BRACE; ds = declarations_with_loc; RIGHT_BRACE {
+ { Style_rule.prelude = xs;
+ block = ds;
+ loc = Lex_buffer.make_loc_and_fix $startpos $endpos;
+ }
+ }
+ ;
+
+prelude_with_loc:
+ xs = prelude { (xs, Lex_buffer.make_loc_and_fix $startpos $endpos) }
+ ;
+
+prelude:
+ xs = list(component_value_with_loc_in_prelude) { xs }
+ ;
+
+declarations_with_loc:
+ | ds = declarations { (ds, Lex_buffer.make_loc_and_fix ~loc_ghost:true $startpos $endpos) }
+ ;
+
+declarations:
+ | ds = declarations_without_ending_semi_colon { List.rev ds }
+ | ds = declarations_without_ending_semi_colon; SEMI_COLON { List.rev ds }
+ ;
+
+declarations_without_ending_semi_colon:
+ | d = declaration_or_at_rule { [d] }
+ | ds = declarations_without_ending_semi_colon; SEMI_COLON; d = declaration_or_at_rule { d :: ds }
+ ;
+
+declaration_or_at_rule:
+ | d = declaration { Declaration_list.Declaration d }
+ | r = at_rule { Declaration_list.At_rule r }
+ ;
+
+declaration:
+ n = IDENT; option(WHITESPACE); COLON; v = list(component_value_with_loc); i = boption(IMPORTANT) {
+ { Declaration.name = (n, Lex_buffer.make_loc_and_fix $startpos(n) $endpos(n));
+ value = (v, Lex_buffer.make_loc_and_fix $startpos(v) $endpos(v));
+ important = (i, Lex_buffer.make_loc_and_fix $startpos(i) $endpos(i));
+ loc = Lex_buffer.make_loc_and_fix $startpos $endpos;
+ }
+ }
+ ;
+
+paren_block:
+ LEFT_PAREN; xs = list(component_value_with_loc); RIGHT_PAREN { xs }
+ ;
+
+bracket_block:
+ LEFT_BRACKET; xs = list(component_value_with_loc); RIGHT_BRACKET { xs }
+ ;
+
+component_value_with_loc:
+ | c = component_value { (c, Lex_buffer.make_loc_and_fix $startpos $endpos) }
+
+component_value:
+ | b = paren_block { Component_value.Paren_block b }
+ | b = bracket_block { Component_value.Bracket_block b }
+ | n = NUMBER; PERCENTAGE { Component_value.Percentage n }
+ | i = IDENT { Component_value.Ident i }
+ | s = STRING { Component_value.String s }
+ | u = URI { Component_value.Uri u }
+ | o = OPERATOR { Component_value.Operator o }
+ | d = DELIM { Component_value.Delim d }
+ | option(WHITESPACE); COLON { Component_value.Delim ":" }
+ | option(WHITESPACE); DOT { Component_value.Delim "." }
+ | f = FUNCTION; xs = list(component_value_with_loc); RIGHT_PAREN {
+ Component_value.Function ((f, Lex_buffer.make_loc_and_fix $startpos(f) $endpos(f)),
+ (xs, Lex_buffer.make_loc_and_fix $startpos(xs) $endpos(xs)))
+ }
+ | option(WHITESPACE); h = HASH { Component_value.Hash h }
+ | n = NUMBER { Component_value.Number n }
+ | r = UNICODE_RANGE { Component_value.Unicode_range r }
+ | d = FLOAT_DIMENSION { Component_value.Float_dimension d }
+ | d = DIMENSION { Component_value.Dimension d }
+ ;
+
+component_value_with_loc_in_prelude:
+ | c = component_value_in_prelude { (c, Lex_buffer.make_loc_and_fix $startpos $endpos) }
+
+component_value_in_prelude:
+ | b = paren_block { Component_value.Paren_block b }
+ | b = bracket_block { Component_value.Bracket_block b }
+ | n = NUMBER; PERCENTAGE { Component_value.Percentage n }
+ | i = IDENT { Component_value.Ident i }
+ | s = STRING { Component_value.String s }
+ | u = URI { Component_value.Uri u }
+ | o = OPERATOR { Component_value.Operator o }
+ | d = DELIM { Component_value.Delim d }
+ | WHITESPACE { Component_value.Delim "*" }
+ | COLON { Component_value.Delim ":" }
+ | DOT { Component_value.Delim "." }
+ | f = FUNCTION; xs = list(component_value_with_loc); RIGHT_PAREN {
+ Component_value.Function ((f, Lex_buffer.make_loc_and_fix $startpos(f) $endpos(f)),
+ (xs, Lex_buffer.make_loc_and_fix $startpos(xs) $endpos(xs)))
+ }
+ | h = HASH { Component_value.Hash h }
+ | n = NUMBER { Component_value.Number n }
+ | r = UNICODE_RANGE { Component_value.Unicode_range r }
+ | d = FLOAT_DIMENSION { Component_value.Float_dimension d }
+ | d = DIMENSION { Component_value.Dimension d }
+ ;