File: coma_lexer.mll

package info (click to toggle)
why3 1.8.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 45,028 kB
  • sloc: xml: 185,443; ml: 111,224; ansic: 3,998; sh: 2,578; makefile: 2,568; java: 865; python: 720; javascript: 290; lisp: 205; pascal: 173
file content (331 lines) | stat: -rw-r--r-- 9,730 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
(********************************************************************)
(*                                                                  *)
(*  The Why3 Verification Platform   /   The Why3 Development Team  *)
(*  Copyright 2010-2025 --  Inria - CNRS - Paris-Saclay University  *)
(*                                                                  *)
(*  This software is distributed under the terms of the GNU Lesser  *)
(*  General Public License version 2.1, with the special exception  *)
(*  on linking described in file LICENSE.                           *)
(********************************************************************)

(* This is a copy of [src/parser/lexer.mll], with the following minor changes:

* addition of keywords:

*)

{
  open Why3
  open Coma_parser

  let keywords = Hashtbl.create 97
  let span_aliases = Hashtbl.create 16
  let attribute_aliases = Hashtbl.create 16
  let () =
    List.iter
      (fun (x,y) -> Hashtbl.add keywords x y)
      [
        "absurd", ABSURD;
        "return", RETURN;
        "abstract", ABSTRACT;
        "alias", ALIAS;
        "any", ANY;
        "as", AS;
        "assert", ASSERT;
        "assume", ASSUME;
        "at", AT;
        "axiom", AXIOM;
        "begin", BEGIN;
        "break", BREAK;
        "by", BY;
        "check", CHECK;
        "clone", CLONE;
        "coinductive", COINDUCTIVE;
        "constant", CONSTANT;
        "continue", CONTINUE;
        "diverges", DIVERGES;
        "do", DO;
        "done", DONE;
        "downto", DOWNTO;
        "else", ELSE;
        "end", END;
        "ensures", ENSURES;
        "epsilon", EPSILON;
        "exception", EXCEPTION;
        "exists", EXISTS;
        "export", EXPORT;
        "false", FALSE;
        "float", FLOAT; (* contextual *)
        "for", FOR;
        "forall", FORALL;
        "fun", FUN;
        "function", FUNCTION;
        "ghost", GHOST;
        "goal", GOAL;
        "if", IF;
        "import", IMPORT;
        "in", IN;
        "inductive", INDUCTIVE;
        "invariant", INVARIANT;
        "label", LABEL;
        "lemma", LEMMA;
        "let", LET;
        "match", MATCH;
        "meta", META;
        "module", MODULE;
        "mutable", MUTABLE;
        "not", NOT;
        "old", OLD;
        "partial", PARTIAL;
        "predicate", PREDICATE;
        "private", PRIVATE;
        "pure", PURE;
        "raise", RAISE;
        "raises", RAISES;
        "range", RANGE; (* contextual *)
        "reads", READS;
        "rec", REC;
        "ref", REF; (* contextual *)
        "requires", REQUIRES;
        "returns", RETURNS;
        "scope", SCOPE;
        "so", SO;
        "then", THEN;
        "theory", THEORY;
        "to", TO;
        "true", TRUE;
        "try", TRY;
        "type", TYPE;
        "use", USE;
        "val", VAL;
        "variant", VARIANT;
        "while", WHILE;
        "with", WITH;
        "writes", WRITES;
      ]
}

let space = [' ' '\t' '\r']
let quote = '\''

let bin     = ['0' '1']
let oct     = ['0'-'7']
let dec     = ['0'-'9']
let hex     = ['0'-'9' 'a'-'f' 'A'-'F']

let bin_sep = ['0' '1' '_']
let oct_sep = ['0'-'7' '_']
let dec_sep = ['0'-'9' '_']
let hex_sep = ['0'-'9' 'a'-'f' 'A'-'F' '_']

let lalpha = ['a'-'z']
let ualpha = ['A'-'Z']
let alpha  = ['a'-'z' 'A'-'Z']

let suffix = (alpha | quote* dec_sep)* quote*
let lident = ['a'-'z' '_'] suffix
let uident = ['A'-'Z'] suffix

let core_suffix = quote alpha suffix
let core_lident = lident core_suffix+
let core_uident = uident core_suffix+

let op_char_1 = ['=' '<' '>' '~']
let op_char_2 = ['+' '-']
let op_char_3 = ['*' '/' '\\' '%']
let op_char_4 = ['!' '$' '&' '?' '@' '^' '.' ':' '|' '#']
let op_char_34 = op_char_3 | op_char_4
let op_char_234 = op_char_2 | op_char_34
let op_char_1234 = op_char_1 | op_char_234

let op_char_pref = ['!' '?']

rule token = parse
  | "[##" space* ("\"" ([^ '\010' '\013' '"' ]* as file) "\"")?
    space* (dec+ as line) space* (dec+ as char) space* "]"
      { let file =
          Option.map (Lexlib.resolve_file Lexing.(lexbuf.lex_curr_p.pos_fname)) file
        in
        Lexlib.update_loc lexbuf file (int_of_string line) (int_of_string char);
        token lexbuf }
  | "[%#" space* (lident as lid) space* "]"
      { try
          let (file, bline, bchar, eline, echar) = Hashtbl.find span_aliases lid in
          POSITION (Loc.user_position file bline bchar eline echar)
        with Not_found -> Loc.errorm "File alias unknown." }
  | "[#" space* "\"" ([^ '\010' '\013' '"' ]* as file) "\"" space*
    (dec+ as bline) space* (dec+ as bchar) space*
    (dec+ as eline) space* (dec+ as echar) space* "]"
      { let file = Lexlib.resolve_file Lexing.(lexbuf.lex_curr_p.pos_fname) file in
        POSITION (Loc.user_position file
                    (int_of_string bline) (int_of_string bchar)
                    (int_of_string eline) (int_of_string echar)) }

  | "let%span" space+ (lident as lid) space* "=" space* "\"" ([^ '\010' '\013' '"' ]* as file) "\""
      space* (dec+ as bline) space* (dec+ as bchar) space* (dec+ as eline) space* (dec+ as echar) space*
      { let file = Lexlib.resolve_file Lexing.(lexbuf.lex_curr_p.pos_fname) file in
        Hashtbl.replace span_aliases lid (file, int_of_string bline, int_of_string bchar, int_of_string eline, int_of_string echar);
        token lexbuf }
  | "let%attr" space+ (lident as lid) space* "=" space* ([^ '\n']+ as cattr)
      { Hashtbl.replace attribute_aliases lid cattr;
        token lexbuf }
  | "[%@" space* (lident (' '+ [^ ' ' '\n' ']']+ as lid)) space* ']'
      { try
          ATTRIBUTE (Hashtbl.find attribute_aliases lid)
        with Not_found -> Loc.errorm "Attribute alias unknown." }
  | "[@" space* ([^ ' ' '\n' ']']+ (' '+ [^ ' ' '\n' ']']+)* as lbl) space* ']'
      { ATTRIBUTE lbl }
  | '\n'
      { Lexing.new_line lexbuf; token lexbuf }
  | space+
      { token lexbuf }
  | '_'
      { UNDERSCORE }
  | lident as id
      { try Hashtbl.find keywords id with Not_found -> LIDENT id }
  | core_lident as id
      { CORE_LIDENT id }
  | uident as id
      { UIDENT id }
  | core_uident as id
      { CORE_UIDENT id }
  | dec dec_sep* as s
      { INTEGER Number.(int_literal ILitDec ~neg:false (Lexlib.remove_underscores s)) }
  | '0' ['x' 'X'] (hex hex_sep* as s)
      { INTEGER Number.(int_literal ILitHex ~neg:false (Lexlib.remove_underscores s)) }
  | '0' ['o' 'O'] (oct oct_sep* as s)
      { INTEGER Number.(int_literal ILitOct ~neg:false (Lexlib.remove_underscores s)) }
  | '0' ['b' 'B'] (bin bin_sep* as s)
      { INTEGER Number.(int_literal ILitBin ~neg:false (Lexlib.remove_underscores s)) }
  | (dec+ as i) ".."
      { Lexlib.backjump lexbuf 2; INTEGER Number.(int_literal ILitDec ~neg:false i) }
  | '0' ['x' 'X'] (hex+ as i) ".."
      { Lexlib.backjump lexbuf 2; INTEGER Number.(int_literal ILitHex ~neg:false i) }
  | (dec+ as i)     ("" as f)    ['e' 'E'] (['-' '+']? dec+ as e)
  | (dec+ as i) '.' (dec* as f) (['e' 'E'] (['-' '+']? dec+ as e))?
  | (dec* as i) '.' (dec+ as f) (['e' 'E'] (['-' '+']? dec+ as e))?
      { REAL (Number.real_literal ~radix:10 ~neg:false ~int:i ~frac:f ~exp:(Option.map Lexlib.remove_leading_plus e)) }
  | '0' ['x' 'X'] (hex+ as i) ("" as f) ['p' 'P'] (['-' '+']? dec+ as e)
  | '0' ['x' 'X'] (hex+ as i) '.' (hex* as f)
        (['p' 'P'] (['-' '+']? dec+ as e))?
  | '0' ['x' 'X'] (hex* as i) '.' (hex+ as f)
        (['p' 'P'] (['-' '+']? dec+ as e))?
      { REAL (Number.real_literal ~radix:16 ~neg:false ~int:i ~frac:f ~exp:(Option.map Lexlib.remove_leading_plus e)) }
  | "(*)"
      { Lexlib.backjump lexbuf 2; LEFTPAR }
  | "(*"
      { Lexlib.comment lexbuf; token lexbuf }
  | "'" (lalpha suffix as id)
      { QUOTE_LIDENT id }
  | ","
      { COMMA }
  | "("
      { LEFTPAR }
  | ")"
      { RIGHTPAR }
  | "{"
      { LEFTBRC }
  | "}"
      { RIGHTBRC }
  | ":"
      { COLON }
  | ";"
      { SEMICOLON }
  | "->"
      { ARROW }
  | "->'"
      { Lexlib.backjump lexbuf 1; ARROW }
  | "<-"
      { LARROW }
  | "<->"
      { LRARROW }
  | "&&"
      { AMPAMP }
  | "||"
      { BARBAR }
  | "/\\"
      { AND }
  | "\\/"
      { OR }
  | "."
      { DOT }
  | ".."
      { DOTDOT }
  | "&"
      { AMP }
  | "|"
      { BAR }
  | "<"
      { LT }
  | ">"
      { GT }
  | "<>"
      { LTGT }
  | "="
      { EQUAL }
  | "-"
      { MINUS }
  | "["
      { LEFTSQ }
  | "]"
      { RIGHTSQ }
  | "]" (quote+ as s)
      { RIGHTSQ_QUOTE s }
  | ")" ('\'' alpha suffix core_suffix* as s)
      { RIGHTPAR_QUOTE s }
  | ")" ('_' alpha suffix core_suffix* as s)
      { RIGHTPAR_USCORE s }
  | "[|"
      { LEFTSQBAR }
  | "|]"
      { BARRIGHTSQ }
  | "-{"
      { LEFTMINBRC }
  | "}-"
      { RIGHTMINBRC }
(* begin coma *)
  | "!"
      { BANG }
  | "?"
      { QUESTION }
  (* | "/"
      { SLASH } *)
  (* | "/" space* "&"
      { SLASHAMP } *)
  | "--" [ ^ '\n' ]*
      { token lexbuf }
(* end coma *)
  | op_char_pref op_char_4* quote* as s
      { OPPREF s }
  | op_char_1234* op_char_1 op_char_1234* quote* as s
      { OP1 s }
  | op_char_234* op_char_2 op_char_234* quote* as s
      { OP2 s }
  | op_char_34* op_char_3 op_char_34* quote* as s
      { OP3 s }
  | op_char_4+ as s
      { OP4 s }
  | "\""
      { STRING (Lexlib.string lexbuf) }
  | eof
      { EOF }
  | _ as c
      { Lexlib.illegal_character c lexbuf }

{

  let () = Exn_printer.register (fun fmt exn -> match exn with
  | Coma_parser.Error -> Format.pp_print_string fmt "syntax error"
  | _ -> raise exn)

  let parse_channel file c =
    let lb = Lexing.from_channel c in
    Loc.set_file file lb;
    try
      Coma_parser.top_level token lb
    with
      Coma_parser.Error as e ->
      raise (Loc.Located
               (Loc.extract (lb.Lexing.lex_start_p, lb.Lexing.lex_curr_p),e))

}