Source

erlint / src / lexer.ml

(*pp camlp4o *)

let initial_buffer_size = 10


let keyword_or_atom string =
  match string with
    | "case"
    | "of"
    | "receive"
    | "if"
    | "try"
    | "catch"
    | "with"
    | "after"
    | "when"
    | "begin"
    | "end"
    | "fun" ->
      Token.Keyword string
    | _ ->
      Token.Atom string


let rec lex = parser
  (* Ignore whitespace except new line *)
  | [< _ = whitespace; stream >] -> lex stream
  | [< ''\n'; stream >] -> [< 'Token.Newline; lex stream >]
  | [< ''.'; stream >] -> [< 'Token.Dot; lex stream >]
  | [< ''%'; stream >] ->
    let buffer = Buffer.create initial_buffer_size in
    lex_comment buffer stream
  | [< ' ('\''); stream >] ->
    let buffer = Buffer.create initial_buffer_size in
    Buffer.add_char buffer '\'';
    lex_atom_quoted buffer stream
  | [< ' ('a' .. 'z') as first_char; stream >] ->
    let buffer = Buffer.create initial_buffer_size in
    Buffer.add_char buffer first_char;
    lex_atom buffer stream
  | [< ' ('A' .. 'Z' | '_') as first_char; stream >] ->
    let buffer = Buffer.create initial_buffer_size in
    Buffer.add_char buffer first_char;
    lex_var buffer stream
  | [< ' ('0' .. '9') as first_digit; stream >] ->
    let buffer = Buffer.create initial_buffer_size in
    Buffer.add_char buffer first_digit;
    lex_number buffer stream
  | [< 'c; stream >] ->
    [< 'Token.Keyword (String.make 1 c); lex stream >]
  | [< >] -> [< >]
and lex_comment buffer = parser
  | [< ''\n'; stream >] ->
    [< 'Token.Comment (Buffer.contents buffer); 'Token.Newline; lex stream >]
  | [< 'c; stream >] ->
    Buffer.add_char buffer c;
    lex_comment buffer stream
  | [< >] -> [< 'Token.Comment (Buffer.contents buffer) >]
and lex_atom_quoted buffer = parser
  | [< ' ('\''); stream >] ->
    Buffer.add_char buffer '\'';
    [< 'Token.Atom (Buffer.contents buffer); lex stream >]
  | [< 'c; stream >] ->
    Buffer.add_char buffer c;
    lex_atom_quoted buffer stream
and lex_atom buffer = parser
  | [< ' ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_') as c; stream >] ->
    Buffer.add_char buffer c;
    lex_atom buffer stream
  | [< stream >] ->
    [< 'keyword_or_atom (Buffer.contents buffer); lex stream >]
and lex_var buffer = parser
  | [< ' ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_') as c; stream >] ->
    Buffer.add_char buffer c;
    lex_var buffer stream
  | [< stream >] ->
    [< 'Token.Var (Buffer.contents buffer); lex stream >]
and lex_number buffer = parser
  | [< ''.'; stream >] ->
    Buffer.add_char buffer '.';
    lex_number_nodot buffer stream
  | [< ' ('0' .. '9') as digit; stream >] ->
    Buffer.add_char buffer digit;
    lex_number buffer stream
  | [< stream >] ->
    [< 'Token.Number (Buffer.contents buffer); lex stream >]
and lex_number_nodot buffer = parser
  | [< ' ('0' .. '9') as digit; stream >] ->
    Buffer.add_char buffer digit;
    lex_number buffer stream
  | [< stream >] ->
    [< 'Token.Number (Buffer.contents buffer); lex stream >]
and whitespace = parser
  | [< ' (' ' | '\r' | '\t'); stream >] -> whitespace stream
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.