(************************************************************************) (* v * The Coq Proof Assistant / The Coq Development Team *) (* Buffer.add_string ocaml_buf "{" | Extend -> () in incr num_braces let end_ocaml lexbuf = let () = decr num_braces in if !num_braces < 0 then lex_error lexbuf "Unexpected end of OCaml code" else if !num_braces = 0 then let s = Buffer.contents ocaml_buf in let () = Buffer.reset ocaml_buf in Some (CODE { Coqpp_ast.code = s }) else let () = Buffer.add_string ocaml_buf "}" in None } let letter = ['a'-'z' 'A'-'Z'] let letterlike = ['_' 'a'-'z' 'A'-'Z'] let alphanum = ['_' 'a'-'z' 'A'-'Z' '0'-'9' '\''] let ident = letterlike alphanum* let qualid = ident ('.' ident)* let space = [' ' '\t' '\r'] let number = [ '0'-'9' ] rule extend = parse | "(*" { start_comment (); comment lexbuf } | "{" { start_ocaml (); ocaml lexbuf } | "GRAMMAR" { GRAMMAR } | "VERNAC" { VERNAC } | "TACTIC" { TACTIC } | "EXTEND" { EXTEND } | "END" { END } | "DECLARE" { DECLARE } | "PLUGIN" { PLUGIN } (** Camlp5 specific keywords *) | "GLOBAL" { GLOBAL } | "FIRST" { FIRST } | "LAST" { LAST } | "BEFORE" { BEFORE } | "AFTER" { AFTER } | "LEVEL" { LEVEL } | "LEFTA" { LEFTA } | "RIGHTA" { RIGHTA } | "NONA" { NONA } (** Standard *) | ident { IDENT (Lexing.lexeme lexbuf) } | qualid { QUALID (Lexing.lexeme lexbuf) } | number { INT (int_of_string (Lexing.lexeme lexbuf)) } | space { extend lexbuf } | '\"' { string lexbuf } | '\n' { newline lexbuf; extend lexbuf } | '[' { LBRACKET } | ']' { RBRACKET } | '|' { PIPE } | "->" { ARROW } | ',' { COMMA } | ':' { COLON } | ';' { SEMICOLON } | '(' { LPAREN } | ')' { RPAREN } | '=' { EQUAL } | _ { lex_error lexbuf "syntax error" } | eof { EOF } and ocaml = parse | "{" { start_ocaml (); ocaml lexbuf } | "}" { match end_ocaml lexbuf with Some tk -> tk | None -> ocaml lexbuf } | '\n' { newline lexbuf; Buffer.add_char ocaml_buf '\n'; ocaml lexbuf } | '\"' { Buffer.add_char ocaml_buf '\"'; ocaml_string lexbuf } | (_ as c) { Buffer.add_char ocaml_buf c; ocaml lexbuf } | eof { lex_unexpected_eof lexbuf "OCaml code" } and comment = parse | "*)" { match end_comment lexbuf with Some _ -> extend lexbuf | None -> comment lexbuf } | "(*" { start_comment lexbuf; comment lexbuf } | '\n' { newline lexbuf; Buffer.add_char comment_buf '\n'; comment lexbuf } | (_ as c) { Buffer.add_char comment_buf c; comment lexbuf } | eof { lex_unexpected_eof lexbuf "comment" } and string = parse | '\"' { let s = Buffer.contents string_buf in let () = Buffer.reset string_buf in STRING s } | "\\\"" { Buffer.add_char string_buf '\"'; string lexbuf } | '\n' { newline lexbuf; Buffer.add_char string_buf '\n'; string lexbuf } | (_ as c) { Buffer.add_char string_buf c; string lexbuf } | eof { lex_unexpected_eof lexbuf "string" } and ocaml_string = parse | "\\\"" { Buffer.add_string ocaml_buf "\\\""; ocaml_string lexbuf } | '\"' { Buffer.add_char ocaml_buf '\"'; ocaml lexbuf } | (_ as c) { Buffer.add_char ocaml_buf c; ocaml_string lexbuf } | eof { lex_unexpected_eof lexbuf "OCaml string" } { let token lexbuf = match mode () with | OCaml -> ocaml lexbuf | Extend -> extend lexbuf }