parser.mly 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. %{
  2. open Lexing
  3. open Types
  4. let prop2str (name, value) = name ^ ":" ^ Stringify.value2str value
  5. %}
  6. (* Tokens *)
  7. %token LPAREN RPAREN LBRACE RBRACE SEMICOL COMMA COLON
  8. %token MEDIA IMPORT CHARSET PAGE FONTFACE NAMESPACE
  9. %token IMPORTANT EOF
  10. %token <string> ID STRING SELECTOR
  11. (* Start symbol *)
  12. %type <Types.decl list> stylesheet
  13. %start stylesheet
  14. %%
  15. (* Left-recursive list (use List.rev to obtain correctly ordered list) *)
  16. llist(x):
  17. | { [] }
  18. | tl=llist(x) hd=x { hd :: tl }
  19. separated_llist(sep, x):
  20. | { [] }
  21. | tl=llist(x) sep hd=x { hd :: tl }
  22. stylesheet:
  23. | decls=llist(decl) EOF
  24. { List.rev decls }
  25. selector:
  26. | id=ID { [id] }
  27. | id=SELECTOR { [id] }
  28. | tl=selector hd=ID { hd :: tl }
  29. | tl=selector hd=SELECTOR { hd :: tl }
  30. value:
  31. | str=STRING { Str str }
  32. | lit=ID { Lit lit }
  33. | name=ID LPAREN arg=value RPAREN { Fn (name, arg) }
  34. | IMPORTANT { Imp }
  35. prop:
  36. | name=ID COLON v=value+
  37. { (name, match v with [hd] -> hd | _ -> Lst v) }
  38. propline:
  39. | p=prop SEMICOL
  40. { p }
  41. props:
  42. | LBRACE p=llist(propline) last=prop? RBRACE
  43. { List.rev p @ (match last with None -> [] | Some p -> [p]) }
  44. group:
  45. | s=separated_nonempty_list(COMMA, selector) p=props
  46. { Group (List.rev s, p) }
  47. %inline media:
  48. | m=ID
  49. { m }
  50. | LPAREN p=prop RPAREN
  51. { "(" ^ prop2str p ^ ")" }
  52. %inline stringopt: f=STRING | f=ID { f }
  53. decl:
  54. | g=group
  55. { g }
  56. | MEDIA queries=separated_nonempty_list(COMMA, media) LBRACE groups=llist(group) RBRACE
  57. { Media (queries, List.rev groups) }
  58. | IMPORT f=stringopt q=separated_list(COMMA, ID) SEMICOL
  59. { Import (f, q) }
  60. | CHARSET c=stringopt SEMICOL
  61. { Charset c }
  62. | PAGE query=ID? p=props
  63. { Page (query, p) }
  64. | FONTFACE p=props
  65. { Fontface p }
  66. | NAMESPACE prefix=ID? uri=STRING SEMICOL
  67. { Namespace (prefix, uri) }
  68. %%