diff options
| author | Pierre Roux | 2018-10-20 14:40:23 +0200 |
|---|---|---|
| committer | Pierre Roux | 2019-04-02 00:02:21 +0200 |
| commit | 552bb5aba750785d8f19aa7b333baa59e9199369 (patch) | |
| tree | df349e57ff8c34e2da48d8c786d2466426822511 /parsing | |
| parent | 4dc3d04d0812005f221e88744c587de8ef0f38ee (diff) | |
Add parsing of decimal constants (e.g., 1.02e+01)
Rather than integers '[0-9]+', numeral constant can now be parsed
according to the regexp '[0-9]+ ([.][0-9]+)? ([eE][+-]?[0-9]+)?'.
This can be used in one of the two following ways:
- using the function `Notation.register_rawnumeral_interpreter` in an OCaml plugin
- using `Numeral Notation` with the type `decimal` added to `Decimal.v`
See examples of each use case in the next two commits.
Diffstat (limited to 'parsing')
| -rw-r--r-- | parsing/cLexer.ml | 30 | ||||
| -rw-r--r-- | parsing/cLexer.mli | 5 | ||||
| -rw-r--r-- | parsing/g_prim.mlg | 12 | ||||
| -rw-r--r-- | parsing/pcoq.mli | 2 | ||||
| -rw-r--r-- | parsing/tok.ml | 18 | ||||
| -rw-r--r-- | parsing/tok.mli | 4 |
6 files changed, 35 insertions, 36 deletions
diff --git a/parsing/cLexer.ml b/parsing/cLexer.ml index f2e51afff5..42ca5f8c05 100644 --- a/parsing/cLexer.ml +++ b/parsing/cLexer.ml @@ -318,10 +318,6 @@ let rec ident_tail loc len s = match Stream.peek s with warn_unrecognized_unicode ~loc (u,id); len | _ -> len -let rec number len s = match Stream.peek s with - | Some ('0'..'9' as c) -> Stream.junk s; number (store len c) s - | _ -> len - let warn_comment_terminator_in_string = CWarnings.create ~name:"comment-terminator-in-string" ~category:"parsing" (fun () -> @@ -706,15 +702,11 @@ let rec next_token ~diff_mode loc s = let id = get_buff len in comment_stop bp; (try find_keyword loc id s with Not_found -> IDENT id), set_loc_pos loc bp ep - | Some ('0'..'9' as c) -> - Stream.junk s; - let len = - try number (store 0 c) s with - Stream.Failure -> raise (Stream.Error "") - in + | Some ('0'..'9') -> + let n = NumTok.parse s in let ep = Stream.count s in comment_stop bp; - (NUMERAL (get_buff len), set_loc_pos loc bp ep) + (NUMERAL n, set_loc_pos loc bp ep) | Some '\"' -> Stream.junk s; let (loc, len) = @@ -796,8 +788,8 @@ let token_text : type c. c Tok.p -> string = function | PKEYWORD t -> "'" ^ t ^ "'" | PIDENT None -> "identifier" | PIDENT (Some t) -> "'" ^ t ^ "'" - | PNUMERAL None -> "integer" - | PNUMERAL (Some s) -> "'" ^ s ^ "'" + | PNUMERAL None -> "numeral" + | PNUMERAL (Some n) -> "'" ^ NumTok.to_string n ^ "'" | PSTRING None -> "string" | PSTRING (Some s) -> "STRING \"" ^ s ^ "\"" | PLEFTQMARK -> "LEFTQMARK" @@ -846,12 +838,6 @@ module LexerDiff = MakeLexer (struct let mode = true end) let is_ident_not_keyword s = is_ident s && not (is_keyword s) -let is_number s = - let rec aux i = - Int.equal (String.length s) i || - match s.[i] with '0'..'9' -> aux (i+1) | _ -> false - in aux 0 - let strip s = let len = let rec loop i len = @@ -875,5 +861,9 @@ let terminal s = let s = strip s in let () = match s with "" -> failwith "empty token." | _ -> () in if is_ident_not_keyword s then PIDENT (Some s) - else if is_number s then PNUMERAL (Some s) else PKEYWORD s + +(* Precondition: the input is a numeral (c.f. [NumTok.t]) *) +let terminal_numeral s = match NumTok.of_string s with + | Some n -> PNUMERAL (Some n) + | None -> failwith "numeral token expected." diff --git a/parsing/cLexer.mli b/parsing/cLexer.mli index 9df3e45f49..464bcf614d 100644 --- a/parsing/cLexer.mli +++ b/parsing/cLexer.mli @@ -46,9 +46,12 @@ val check_ident : string -> unit val is_ident : string -> bool val check_keyword : string -> unit -(** When string is neither an ident nor an int, returns a keyword. *) +(** When string is not an ident, returns a keyword. *) val terminal : string -> string Tok.p +(** Precondition: the input is a numeral (c.f. [NumTok.t]) *) +val terminal_numeral : string -> NumTok.t Tok.p + (** The lexer of Coq: *) module Lexer : diff --git a/parsing/g_prim.mlg b/parsing/g_prim.mlg index 9c5fe2a71d..80dd997860 100644 --- a/parsing/g_prim.mlg +++ b/parsing/g_prim.mlg @@ -21,6 +21,10 @@ let _ = List.iter CLexer.add_keyword prim_kw let local_make_qualid loc l id = make_qualid ~loc (DirPath.make l) id +let check_int loc = function + | { NumTok.int = i; frac = ""; exp = "" } -> i + | _ -> CErrors.user_err ~loc (Pp.str "This number is not an integer.") + let my_int_of_string loc s = try int_of_string s @@ -110,13 +114,13 @@ GRAMMAR EXTEND Gram [ [ s = string -> { CAst.make ~loc s } ] ] ; integer: - [ [ i = NUMERAL -> { my_int_of_string loc i } - | "-"; i = NUMERAL -> { - my_int_of_string loc i } ] ] + [ [ i = NUMERAL -> { my_int_of_string loc (check_int loc i) } + | "-"; i = NUMERAL -> { - my_int_of_string loc (check_int loc i) } ] ] ; natural: - [ [ i = NUMERAL -> { my_int_of_string loc i } ] ] + [ [ i = NUMERAL -> { my_int_of_string loc (check_int loc i) } ] ] ; bigint: (* Negative numbers are dealt with elsewhere *) - [ [ i = NUMERAL -> { i } ] ] + [ [ i = NUMERAL -> { check_int loc i } ] ] ; END diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli index b733ff46d4..5d8897cb47 100644 --- a/parsing/pcoq.mli +++ b/parsing/pcoq.mli @@ -157,7 +157,7 @@ module Prim : val pattern_identref : lident Entry.t val base_ident : Id.t Entry.t val natural : int Entry.t - val bigint : Constrexpr.raw_numeral Entry.t + val bigint : string Entry.t val integer : int Entry.t val string : string Entry.t val lstring : lstring Entry.t diff --git a/parsing/tok.ml b/parsing/tok.ml index 36d319d543..71e2d4aa80 100644 --- a/parsing/tok.ml +++ b/parsing/tok.ml @@ -17,7 +17,7 @@ type 'c p = | PPATTERNIDENT : string option -> string p | PIDENT : string option -> string p | PFIELD : string option -> string p - | PNUMERAL : string option -> string p + | PNUMERAL : NumTok.t option -> NumTok.t p | PSTRING : string option -> string p | PLEFTQMARK : unit p | PBULLET : string option -> string p @@ -30,7 +30,8 @@ let pattern_strings : type c. c p -> string * string option = | PPATTERNIDENT s -> "PATTERNIDENT", s | PIDENT s -> "IDENT", s | PFIELD s -> "FIELD", s - | PNUMERAL s -> "INT", s + | PNUMERAL None -> "NUMERAL", None + | PNUMERAL (Some n) -> "NUMERAL", Some (NumTok.to_string n) | PSTRING s -> "STRING", s | PLEFTQMARK -> "LEFTQMARK", None | PBULLET s -> "BULLET", s @@ -42,7 +43,7 @@ type t = | PATTERNIDENT of string | IDENT of string | FIELD of string - | NUMERAL of string + | NUMERAL of NumTok.t | STRING of string | LEFTQMARK | BULLET of string @@ -57,7 +58,8 @@ let equal_p (type a b) (t1 : a p) (t2 : b p) : (a, b) Util.eq option = | PPATTERNIDENT s1, PPATTERNIDENT s2 when streq s1 s2 -> Some Util.Refl | PIDENT s1, PIDENT s2 when streq s1 s2 -> Some Util.Refl | PFIELD s1, PFIELD s2 when streq s1 s2 -> Some Util.Refl - | PNUMERAL s1, PNUMERAL s2 when streq s1 s2 -> Some Util.Refl + | PNUMERAL None, PNUMERAL None -> Some Util.Refl + | PNUMERAL (Some n1), PNUMERAL (Some n2) when NumTok.equal n1 n2 -> Some Util.Refl | PSTRING s1, PSTRING s2 when streq s1 s2 -> Some Util.Refl | PLEFTQMARK, PLEFTQMARK -> Some Util.Refl | PBULLET s1, PBULLET s2 when streq s1 s2 -> Some Util.Refl @@ -71,7 +73,7 @@ let equal t1 t2 = match t1, t2 with | PATTERNIDENT s1, PATTERNIDENT s2 -> string_equal s1 s2 | IDENT s1, IDENT s2 -> string_equal s1 s2 | FIELD s1, FIELD s2 -> string_equal s1 s2 -| NUMERAL s1, NUMERAL s2 -> string_equal s1 s2 +| NUMERAL n1, NUMERAL n2 -> NumTok.equal n1 n2 | STRING s1, STRING s2 -> string_equal s1 s2 | LEFTQMARK, LEFTQMARK -> true | BULLET s1, BULLET s2 -> string_equal s1 s2 @@ -98,7 +100,7 @@ let extract_string diff_mode = function else s | PATTERNIDENT s -> s | FIELD s -> if diff_mode then "." ^ s else s - | NUMERAL s -> s + | NUMERAL n -> NumTok.to_string n | LEFTQMARK -> "?" | BULLET s -> s | QUOTATION(_,s) -> s @@ -122,7 +124,7 @@ let match_pattern (type c) (p : c p) : t -> c = let err () = raise Stream.Failure in let seq = string_equal in match p with - | PKEYWORD s -> (function KEYWORD s' when seq s s' -> s' | _ -> err ()) + | PKEYWORD s -> (function KEYWORD s' when seq s s' -> s' | NUMERAL n when seq s (NumTok.to_string n) -> s | _ -> err ()) | PIDENT None -> (function IDENT s' -> s' | _ -> err ()) | PIDENT (Some s) -> (function (IDENT s' | KEYWORD s') when seq s s' -> s' | _ -> err ()) | PPATTERNIDENT None -> (function PATTERNIDENT s -> s | _ -> err ()) @@ -130,7 +132,7 @@ let match_pattern (type c) (p : c p) : t -> c = | PFIELD None -> (function FIELD s -> s | _ -> err ()) | PFIELD (Some s) -> (function FIELD s' when seq s s' -> s' | _ -> err ()) | PNUMERAL None -> (function NUMERAL s -> s | _ -> err ()) - | PNUMERAL (Some s) -> (function NUMERAL s' when seq s s' -> s' | _ -> err ()) + | PNUMERAL (Some n) -> let s = NumTok.to_string n in (function NUMERAL n' when s = NumTok.to_string n' -> n' | _ -> err ()) | PSTRING None -> (function STRING s -> s | _ -> err ()) | PSTRING (Some s) -> (function STRING s' when seq s s' -> s' | _ -> err ()) | PLEFTQMARK -> (function LEFTQMARK -> () | _ -> err ()) diff --git a/parsing/tok.mli b/parsing/tok.mli index 2b3bb85174..a5fb5ad9cd 100644 --- a/parsing/tok.mli +++ b/parsing/tok.mli @@ -15,7 +15,7 @@ type 'c p = | PPATTERNIDENT : string option -> string p | PIDENT : string option -> string p | PFIELD : string option -> string p - | PNUMERAL : string option -> string p + | PNUMERAL : NumTok.t option -> NumTok.t p | PSTRING : string option -> string p | PLEFTQMARK : unit p | PBULLET : string option -> string p @@ -29,7 +29,7 @@ type t = | PATTERNIDENT of string | IDENT of string | FIELD of string - | NUMERAL of string + | NUMERAL of NumTok.t | STRING of string | LEFTQMARK | BULLET of string |
