(* $Id: mll_lexer.mll 667 2004-06-02 15:21:19Z gerd $ *)
{
type mlltok =
[ `Brace of Lexing.position * mlltok list
| `Bracket of mlltok list
| `Char of char
| `Charliteral of string
| `Comment of mlltok list
| `EOF
| `E_Brace
| `E_Bracket
| `E_Comment
| `E_Paren
| `Ident of string
| `Paren of mlltok list
| `Stringliteral of string
| `Sep of string (* "" or white space string *)
]
let rec recurse_until stop_tok f lexbuf =
let tok = f lexbuf in
if tok = stop_tok then
[]
else
if tok = `EOF then
failwith "Unexpected end of file"
else
tok :: (recurse_until stop_tok f lexbuf)
}
let ident_start = [ 'A'-'Z' 'a'-'z' '_' ]
let ident_rest = [ 'A'-'Z' 'a'-'z' '_' '\'' '0'-'9' ]
rule definition = parse
[' ' '\013' '\009' '\012' '\010' ]+
{ let s = Lexing.lexeme lexbuf in
`Sep s
}
| "(*"
{ let r =
`Comment (recurse_until `E_Comment definition lexbuf) in
r
}
| "*)"
{ `E_Comment }
| '{'
{ let p = Lexing.lexeme_start_p lexbuf in
`Brace (p, recurse_until `E_Brace definition lexbuf) }
| '}'
{ `E_Brace }
| '('
{ `Paren (recurse_until `E_Paren definition lexbuf) }
| ')'
{ `E_Paren }
| '['
{ `Bracket (recurse_until `E_Bracket definition lexbuf) }
| ']'
{ `E_Bracket }
| '"'
{ let buf = Buffer.create 256 in
while stringliteral buf lexbuf do () done;
`Stringliteral (Buffer.contents buf)
}
| '\'' [ ^ '\\' ] '\''
{ let s = Lexing.lexeme lexbuf in
`Charliteral (String.sub s 1 1)
}
| '\'' '\\' ( [ 'n' 't' 'b' 'r' '"' '\\' '\'' ] |
( ['0'-'9'] ['0'-'9'] ['0'-'9'] ) |
( 'x' ['0'-'9' 'a'-'f' 'A'-'F'] ['0'-'9' 'a'-'f' 'A'-'F'] ) )
'\''
{ let s = Lexing.lexeme lexbuf in
`Charliteral (String.sub s 1 (String.length s - 2))
}
| ident_start ident_rest*
{ `Ident (Lexing.lexeme lexbuf) }
| _
{ let s = Lexing.lexeme lexbuf in
`Char s.[0]
}
| eof
{ `EOF }
and stringliteral buf = parse
'"'
{ false }
| [ ^ '\\' '"' ] +
{ Buffer.add_string buf (Lexing.lexeme lexbuf);
true
}
| '\\' ("\010" | "\013" | "\013\010") [ ' ' '\t' ] *
{ true
}
| '\\' ( [ 'n' 't' 'b' 'r' '"' '\\' '\'' ] |
( ['0'-'9'] ['0'-'9'] ['0'-'9'] ) |
( 'x' ['0'-'9' 'a'-'f' 'A'-'F'] ['0'-'9' 'a'-'f' 'A'-'F'] ) )
{ Buffer.add_string buf (Lexing.lexeme lexbuf);
true
}
| '\\' _
{ failwith "illegal backslash escape" }
| eof
{ failwith "Unexpected end of file" }