Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: b29cfce896
Fetching contributors…

Cannot retrieve contributors at this time

file 109 lines (95 sloc) 2.98 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
{

  (* Ohm is © 2012 Victor Nicollet *)
  open ParseAsset
  open SyntaxAsset

  let string_of_token = function
    | STR _ -> "%"
    | EOL _ -> "\n"
    | OPEN_LIST _ -> "{#"
    | CLOSE_LIST _ -> "{/#}"
    | OPEN_OPTION _ -> "{?"
    | CLOSE_OPTION _ -> "}"
    | OPEN_SUB _ -> "{="
    | CLOSE_SUB _ -> "{/=}"
    | OPEN_DEF _ -> "{@"
    | OPEN_SDEF _ -> "{@!"
    | CLOSE_DEF _ -> "{/@}"
    | OPEN_IF _ -> "{if"
    | CLOSE_IF _ -> "{/if}"
    | ELSE _ -> "{else}"
    | OPEN _ -> "{"
    | CLOSE _ -> "}"
    | STYLE _ -> "<style/>"
    | EOF -> "EOF"
    | MODULE (_,_) -> "Module"
    | DOT _ -> "."
    | PIPE _ -> "|"
    | IDENT (_,_) -> "ident"
    | EQUAL _ -> "="
    | VARIANT (_,_) -> "`Variant"
    | ERROR (c,_) -> Printf.sprintf "#! %C !#" c
}

rule outer = parse
  | ( [ ^ '\n' '{' '<' ] | "\\{" ) + as str { STR (str, pos lexbuf) }
  | '\n' { Lexing.new_line lexbuf ; EOL (pos lexbuf) }
  | '<' { STR ("<", pos lexbuf) }

  | "{#" { OPEN_LIST (pos lexbuf) }
  | "{/#}" { CLOSE_LIST (pos lexbuf) }
  | "{/?}" { CLOSE_OPTION (pos lexbuf) }
  | "{else}" { ELSE (pos lexbuf) }
  | "{if" { OPEN_IF (pos lexbuf) }
  | "{/if}" { CLOSE_IF (pos lexbuf) }
  | "{?" { OPEN_OPTION (pos lexbuf) }
  | "{" { OPEN (pos lexbuf) }
  | "{=" { OPEN_SUB (pos lexbuf) }
  | "{/=}" { CLOSE_SUB (pos lexbuf) }
  | "{@" { OPEN_DEF (pos lexbuf) }
  | "{@!" { OPEN_SDEF (pos lexbuf) }
  | "{/@}" { CLOSE_DEF (pos lexbuf) }

  | "<style>" { let s = style lexbuf in STYLE s }

  | eof { EOF }

and inner = parse
  | '\n' { Lexing.new_line lexbuf ; inner lexbuf }
  | [ ' ' '\t' '\r' ] { inner lexbuf }
  | [ 'A' - 'Z'] [ 'A'-'Z' 'a'-'z' '_' '0'-'9' ] * as str
      { MODULE (str, pos lexbuf) }
  | '`' [ 'A' - 'Z'] [ 'A'-'Z' 'a'-'z' '_' '0'-'9' ] * as str
      { VARIANT (str, pos lexbuf) }
  | '.' { DOT (pos lexbuf) }
  | '|' { PIPE (pos lexbuf) }
  | [ 'a' - 'z' ] [ 'A'-'Z' 'a'-'z' '_' '0'-'9' ] * as str
      { IDENT (str, pos lexbuf) }
  | '}' { CLOSE (pos lexbuf) }
  | '=' { EQUAL (pos lexbuf) }

  | _ as c { ERROR (c, pos lexbuf) }
  | eof { EOF }

and style = shortest
  | ([^ '\n']* as s) "</style>" { s }
  | ([^ '\n']* as s) '\n' { Lexing.new_line lexbuf ; s ^ "\n" ^ style lexbuf }
  | ([^ '\n']* as s) eof{ s }

{

  let opens = function
    | OPEN_LIST _
    | OPEN_OPTION _
    | OPEN_IF _
    | OPEN _
    | OPEN_SUB _
    | OPEN_SDEF _
    | OPEN_DEF _ -> true
    | _ -> false

  let closes = function
    | CLOSE _ -> true
    | _ -> false

  let read () =
    let mode = ref `OUTER in
    fun lexbuf ->
      match !mode with
| `OUTER -> let tok = outer lexbuf in
if opens tok then mode := `INNER ;
(* print_string (string_of_token tok) ; *)
tok
| `INNER -> let tok = inner lexbuf in
if closes tok then mode := `OUTER ;
(* print_string (string_of_token tok) ; *)
tok

}
Something went wrong with that request. Please try again.