Nathan
Nathan

Reputation: 3195

Why can't I use module in my lex file?

This is what I currently have for my mll file which runs just fine.

{ type token = EOF | Word of string }

rule token = parse
    | eof { EOF }
    | ['a'-'z' 'A'-'Z']+ as word {Word(word)}
    | _ { token lexbuf }
{
    let lexbuf = Lexing.from_channel stdin in
    let wordlist = 
        let rec next l = 
            match token lexbuf with
                EOF -> l
            | Word(s) -> next (s::l)
        in next []
    in

    List.iter print_endline wordlist
}

I do ocamllex a.mll and then ocamlc -o a a.ml. Running ./a < a.mll will print out all the strings that exist in the mll file, which is exactly what I expect it to do.

However, if I add module StringMap = Map.Make(String) just before the List.iter call, I get a syntax error...
File "a.mll", line 17, characters 4-10: where line 17 is the line with module and 4-10 is the word module.

I cannot figure out why adding this line is giving me a syntax error... If I enter the same code into toplevel it works just fine.

Upvotes: 0

Views: 90

Answers (1)

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66823

I would assume that the code generated by ocamllex ends up inside a function. You can't declare a global-style module inside a function.

However you can declare a local module like this:

let module StringMap = Map.Make(String) in ...

Example:

# let fgm () =
      module StringMap = Map.Make(String)
      StringMap.cardinal StringMap.empty;;
Error: Syntax error
# let flm () =
      let module StringMap = Map.Make(String) in
      StringMap.cardinal StringMap.empty;;
val flm : unit -> int = <fun>
# flm ();;
- : int = 0

Upvotes: 2

Related Questions