File: why_lexer.mll

package info (click to toggle)
alt-ergo 0.95.2-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,528 kB
  • ctags: 3,449
  • sloc: ml: 19,645; makefile: 354
file content (304 lines) | stat: -rw-r--r-- 8,149 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
(******************************************************************************)
(*     The Alt-Ergo theorem prover                                            *)
(*     Copyright (C) 2006-2013                                                *)
(*     CNRS - INRIA - Universite Paris Sud                                    *)
(*                                                                            *)
(*     Sylvain Conchon                                                        *)
(*     Evelyne Contejean                                                      *)
(*                                                                            *)
(*     Francois Bobot                                                         *)
(*     Mohamed Iguernelala                                                    *)
(*     Stephane Lescuyer                                                      *)
(*     Alain Mebsout                                                          *)
(*                                                                            *)
(*   This file is distributed under the terms of the CeCILL-C licence         *)
(******************************************************************************)

(*
 * The Why certification tool
 * Copyright (C) 2002 Jean-Christophe FILLIATRE
 * 
 * This software is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation.
 * 
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * 
 * See the GNU General Public License version 2 for more details
 * (enclosed in the file GPL).
 *)

(* $Id: why_lexer.mll,v 1.26 2011-02-24 15:35:48 mebsout Exp $ *)

{
  open Lexing
  open Why_parser
  open Format
  open Options

  let keywords = Hashtbl.create 97
  let () = 
    List.iter 
      (fun (x,y) -> Hashtbl.add keywords x y)
      [ "ac", AC;
	"and", AND;
	"axiom", AXIOM;
	"inversion", INVERSION;
	"bitv", BITV;
        "bool", BOOL;
	"check", CHECK;
	"cut", CUT;
        "distinct", DISTINCT;
        "else", ELSE;
	"exists", EXISTS;
        "false", FALSE;
	"forall", FORALL;
	"function", FUNCTION;
	"goal", GOAL;
	"if", IF;
	"in", IN; 
	"include", INCLUDE;
	"int", INT;
	"let", LET;
	"logic", LOGIC;
	"not", NOT;
	"or", OR;
	"predicate", PREDICATE;
	"prop", PROP;
	"real", REAL;
	"rewriting", REWRITING;
	"then", THEN;
	"true", TRUE;
	"type", TYPE;
	"unit", UNIT;
	"void", VOID;
	"with", WITH;
      ]
	       
  let newline lexbuf =
    let pos = lexbuf.lex_curr_p in
    lexbuf.lex_curr_p <- 
      { pos with pos_lnum = pos.pos_lnum + 1; pos_bol = pos.pos_cnum }

  let string_buf = Buffer.create 1024

  exception Lexical_error of string

  let char_for_backslash = function
    | 'n' -> '\n'
    | 't' -> '\t'
    | c -> c

  let num0 = Num.Int 0
  let num10 = Num.Int 10
  let num16 = Num.Int 16

  let decnumber s =
    let r = ref num0 in
    for i=0 to String.length s - 1 do
      r := Num.add_num (Num.mult_num num10 !r) 
	(Num.num_of_int (Char.code s.[i] - Char.code '0'))
    done;
    !r

  let hexnumber s =
    let r = ref num0 in
    for i=0 to String.length s - 1 do
      let c = s.[i] in
      let v = 
	match c with
	  | '0'..'9' -> Char.code c - Char.code '0'
	  | 'a'..'f' -> Char.code c - Char.code 'a' + 10
	  | 'A'..'F' -> Char.code c - Char.code 'A' + 10
	  | _ -> assert false
      in
      r := Num.add_num (Num.mult_num num16 !r) (Num.num_of_int v)
    done;
    !r

}

let newline = '\n'
let space = [' ' '\t' '\r']
let alpha = ['a'-'z' 'A'-'Z']
let letter = alpha | '_'
let digit = ['0'-'9']
let hexdigit = ['0'-'9''a'-'f''A'-'F']
let ident = (letter | '?') (letter | digit | '?' | '\'')*

rule token = parse
  | newline 
      { newline lexbuf; token lexbuf }
  | space+  
      { token lexbuf }
  | ident as id (* identifiers *)      
      { try 
	  let k = Hashtbl.find keywords id in
	  Options.tool_req 0 "TR-Lexical-keyword";
	  k
	with Not_found -> 
	  Options.tool_req 0 "TR-Lexical-identifier";
	  IDENT id }
  | digit+ as s (* integers *)
      { Options.tool_req 0 "TR-Lexical-integer";
	INTEGER s }
  | (digit+ as i) ("" as f) ['e' 'E'] (['-' '+']? as sign (digit+ as exp))
  | (digit+ as i) '.' (digit* as f) 
      (['e' 'E'] (['-' '+']? as sign (digit+ as exp)))?
  | (digit* as i) '.' (digit+ as f) 
      (['e' 'E'] (['-' '+']? as sign (digit+ as exp)))?
      (* decimal real literals *)
      { (*
          Format.eprintf "decimal real literal found: i=%s f=%s sign=%a exp=%a" 
          i f so sign so exp;
	*)
	Options.tool_req 0 "TR-Lexical-real";
        let v =
	  match exp,sign with
	    | Some exp,Some "-" ->
		Num.div_num (decnumber (i^f)) 
		  (Num.power_num (Num.Int 10) (decnumber exp))
	    | Some exp,_ -> 
		Num.mult_num (decnumber (i^f)) 
		  (Num.power_num (Num.Int 10) (decnumber exp))
	    | None,_ -> decnumber (i^f) 
	in
	let v = 
	  Num.div_num v 
	    (Num.power_num (Num.Int 10) (Num.num_of_int (String.length f))) 
	in
	(* Format.eprintf " -> value = %s@." (Num.string_of_num v); *)
	NUM v
      } 

      (* hexadecimal real literals a la C99 (0x..p..) *)
  | "0x" (hexdigit+ as e) ('.' (hexdigit* as f))?
      ['p''P'] (['+''-']? as sign) (digit+ as exp) 
      { (* Format.eprintf "hex num found: %s" (lexeme lexbuf); *)
	Options.tool_req 0 "TR-Lexical-hexponent";
	Options.tool_req 0 "TR-Lexical-hexa";
	let f = match f with None -> "" | Some f -> f in
	let v =
	  match sign with
	    | "-" ->
		Num.div_num (hexnumber (e^f)) 
		  (Num.power_num (Num.Int 2) (decnumber exp))
	    | _ -> 
		Num.mult_num (hexnumber (e^f)) 
		  (Num.power_num (Num.Int 2) (decnumber exp))
	in
	let v = 
	  Num.div_num v 
	    (Num.power_num (Num.Int 16) (Num.num_of_int (String.length f))) 
	in
	(* Format.eprintf " -> value = %s@." (Num.string_of_num v); *)
	NUM v
      } 
  | "(*"
      { comment lexbuf; token lexbuf }
  | "'"
      { QUOTE }
  | ","
      { COMMA }
  | ";"
      { PV }
  | "("
      { LEFTPAR }
  | ")"
      { RIGHTPAR }
  | ":"
      { COLON }
  | "->"
      { Options.tool_req 0 "TR-Lexical-operator";
	ARROW }
  | "<-"
      { Options.tool_req 0 "TR-Lexical-operator";
	LEFTARROW }
  | "<->"
      { Options.tool_req 0 "TR-Lexical-operator";
	LRARROW }
  | "="
      { Options.tool_req 0 "TR-Lexical-operator";
	EQUAL }
  | "<"
      { Options.tool_req 0 "TR-Lexical-operator";
	LT }
  | "<="
      { Options.tool_req 0 "TR-Lexical-operator";
	LE }
  | ">"
      { Options.tool_req 0 "TR-Lexical-operator";
	GT }
  | ">="
      { Options.tool_req 0 "TR-Lexical-operator";
	GE }
  | "<>"
      { Options.tool_req 0 "TR-Lexical-operator";
	NOTEQ }
  | "+"
      { Options.tool_req 0 "TR-Lexical-operator";
	PLUS }
  | "-"
      { Options.tool_req 0 "TR-Lexical-operator";
	MINUS }
  | "*"
      { Options.tool_req 0 "TR-Lexical-operator";
	TIMES }
  | "/"
      { Options.tool_req 0 "TR-Lexical-operator";
	SLASH }
  | "%"
      { Options.tool_req 0 "TR-Lexical-operator";
	PERCENT }
  | "@"
      { Options.tool_req 0 "TR-Lexical-operator";
	AT }
  | "."
      { DOT }
  | "["
      { LEFTSQ }
  | "]"
      { RIGHTSQ }
  | "{"
      { LEFTBR }
  | "}"
      { RIGHTBR }
  | "|"
      { BAR }
  | "^"
      { HAT }
  | "\""
      { Buffer.clear string_buf; string lexbuf }
  | eof 
      { EOF }
  | _ as c
      { raise (Lexical_error ("illegal character: " ^ String.make 1 c)) }

and comment = parse
  | "*)" 
      { () }
  | "(*" 
      { comment lexbuf; comment lexbuf }
  | newline 
      { newline lexbuf; comment lexbuf }
  | eof
      { raise (Lexical_error "unterminated comment") }
  | _ 
      { comment lexbuf }

and string = parse
  | "\""
      { Options.tool_req 0 "TR-Lexical-string";
	STRING (Buffer.contents string_buf) }
  | "\\" (_ as c)
      { Buffer.add_char string_buf (char_for_backslash c); string lexbuf }
  | newline 
      { newline lexbuf; Buffer.add_char string_buf '\n'; string lexbuf }
  | eof
      { raise (Lexical_error "unterminated string") }
  | _ as c
      { Buffer.add_char string_buf c; string lexbuf }