(* $Id: xstrp4_here_lexer.mll 23 2004-07-13 21:03:13Z gerd $ * ---------------------------------------------------------------------- * *) { open Xstrp4_here_types type val_id = LC of string | UC of string | End_of_id let rec parse_val_id f buf = let id = f buf in match id with UC s -> s :: parse_val_id f buf | LC s -> [s] | End_of_id -> [] } let ucletter = [ 'A' - 'Z' ] let lcletter = [ 'a' - 'z' '_' ] let acletter = ucletter | lcletter let format = '%' [ '0' '-' ' ' ]* (* no more modifiers are supported by Ocaml *) ['0'-'9']* ( '.' ['0'-'9']* )? ( ( ['L' 'l' 'n'] [ 'd' 'i' 'u' 'x' 'X' 'o' ]) | [ 'd' 'i' 'u' 'x' 'X' 's' 'c' 'f' 'e' 'E' 'g' 'G' 'b' 'a' 't' ] ) rule token = parse '$' ( ucletter acletter* '.' )* lcletter acletter* { let s = Lexing.lexeme lexbuf in let buf = Lexing.from_string (String.sub s 1 (String.length s - 1)) in let start_p = Lexing.lexeme_start_p lexbuf in let end_p = Lexing.lexeme_end_p lexbuf in Variable (parse_val_id value_identifier buf, "%s", ({ start_p with Lexing.pos_cnum = start_p.Lexing.pos_cnum (* + 1 *) }, end_p)) } | '$' '{' ( ucletter acletter* '.' )* lcletter acletter* ( ',' format )? '}' { let s = Lexing.lexeme lexbuf in let k_close = String.index s '}' in let k_percent = try String.index s '%' with Not_found -> (-1) in let buf = Lexing.from_string (String.sub s 2 (k_close - 1)) in let fmt = if k_percent >= 0 then String.sub s k_percent (String.length s - k_percent - 1) else "%s" in let start_p = Lexing.lexeme_start_p lexbuf in let end_p = Lexing.lexeme_end_p lexbuf in let start = Lexing.lexeme_start lexbuf in Variable (parse_val_id value_identifier buf, fmt, ({ start_p with Lexing.pos_cnum = start_p.Lexing.pos_cnum (* + 2 *) }, { end_p with Lexing.pos_cnum = end_p.Lexing.pos_cnum (* + (if k_percent >= 0 then k_percent-1 else k_close) *) }) ) } | '$' { failwith "Bad $ expander" } | '\\' '\n' { Literal("", (Lexing.lexeme_start_p lexbuf, Lexing.lexeme_end_p lexbuf)) } | '\\' '$' { Literal("$", (Lexing.lexeme_start_p lexbuf, Lexing.lexeme_end_p lexbuf)) } | '\\' [ '0'-'9' ] [ '0'-'9' ] [ '0'-'9' ] { let s = Lexing.lexeme lexbuf in let n = int_of_string(String.sub s 1 3) in let lit = Printf.sprintf "%c" (Char.chr n) in Literal(lit, (Lexing.lexeme_start_p lexbuf, Lexing.lexeme_end_p lexbuf)) } (* | '\\' 'o' [ '0'-'7' ] [ '0'-'7' ] [ '0'-'7' ] { Literal (let s = Lexing.lexeme lexbuf in let n = int_of_string("0" ^ String.sub s 1 4) in Printf.sprintf "%c" (Char.chr n) ) } *) | '\\' 'x' [ '0'-'9' 'a'-'f' 'A'-'F' ] [ '0'-'9' 'a'-'f' 'A'-'F' ] { let s = Lexing.lexeme lexbuf in let n = int_of_string("0" ^ String.sub s 1 3) in let lit = Printf.sprintf "%c" (Char.chr n) in Literal(lit, (Lexing.lexeme_start_p lexbuf, Lexing.lexeme_end_p lexbuf)) } | '\\' _ { let lit = Lexing.lexeme lexbuf in Literal(lit, (Lexing.lexeme_start_p lexbuf, Lexing.lexeme_end_p lexbuf)) } | [^ '$' '\\']+ { let lit = Lexing.lexeme lexbuf in Literal(lit, (Lexing.lexeme_start_p lexbuf, Lexing.lexeme_end_p lexbuf)) } | eof { Textend } | _ { let lit = Lexing.lexeme lexbuf in Literal(lit, (Lexing.lexeme_start_p lexbuf, Lexing.lexeme_end_p lexbuf)) } and value_identifier = parse ucletter acletter* '.' { let s = Lexing.lexeme lexbuf in UC (String.sub s 0 (String.length s - 1)) } | lcletter acletter* { LC(Lexing.lexeme lexbuf) } | eof { End_of_id }