forked from cubicle-model-checker/cubicle
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lexer.mll
178 lines (167 loc) · 4.44 KB
/
lexer.mll
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
(**************************************************************************)
(* *)
(* Cubicle *)
(* *)
(* Copyright (C) 2011-2014 *)
(* *)
(* Sylvain Conchon and Alain Mebsout *)
(* Universite Paris-Sud 11 *)
(* *)
(* *)
(* This file is distributed under the terms of the Apache Software *)
(* License version 2.0 *)
(* *)
(**************************************************************************)
{
open Lexing
open Parser
let keywords = Hashtbl.create 97
let () =
List.iter
(fun (x,y) -> Hashtbl.add keywords x y)
[ "type", TYPE;
"init", INIT;
"transition", TRANSITION;
"invariant", INVARIANT;
"requires", REQUIRE;
"array", ARRAY;
"var", VAR;
"const", CONST;
"unsafe", UNSAFE;
"case", CASE;
"forall_other", FORALL_OTHER;
"exists_other", EXISTS_OTHER;
"forall", FORALL;
"exists", EXISTS;
"predicate", PREDICATE;
"if", IF;
"then", THEN;
"else", ELSE;
"not", NOT;
"true", TRUE;
"false", FALSE;
"number_procs", SIZEPROC;
"let", LET;
"in", IN;
]
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 num_of_stringfloat s =
let sign, s =
if s.[0] = '-' then -1, String.sub s 1 (String.length s - 1)
else 1, s in
let r = ref (Num.Int 0) in
let code_0 = Char.code '0' in
let num10 = Num.Int 10 in
let pos_dot = ref (-1) in
for i=0 to String.length s - 1 do
let c = s.[i] in
if c = '.' then pos_dot := i
else
r := Num.add_num (Num.mult_num num10 !r)
(Num.num_of_int (Char.code s.[i] - code_0))
done;
assert (!pos_dot <> -1);
Num.div_num !r
(Num.power_num num10 (Num.num_of_int (String.length s - 1 - !pos_dot)))
|> Num.mult_num (Num.num_of_int sign)
let string_buf = Buffer.create 1024
exception Lexical_error of string
}
let newline = '\n'
let space = [' ' '\t' '\r']
let integer = ('-')? ['0' - '9'] ['0' - '9']*
let real = ('-')? ['0' - '9'] ['0' - '9']* '.' ['0' - '9']*
let mident = ['A'-'Z']['a'-'z' 'A'-'Z' '0'-'9' '_']*
let lident = ['a'-'z']['a'-'z' 'A'-'Z' '0'-'9' '_']*
rule token = parse
| newline
{ newline lexbuf; token lexbuf }
| space+
{ token lexbuf }
| lident as id
{ try Hashtbl.find keywords id
with Not_found ->
if id = "bool" then LIDENT "mbool" else LIDENT id }
| '#'(['1'-'9']['0'-'9']* as n) as id
{ if int_of_string n > !Options.size_proc then raise Parsing.Parse_error;
CONSTPROC id }
| mident as id {
if id = "True" then MIDENT "@MTrue"
else if id = "False" then MIDENT "@MFalse"
else MIDENT id }
| real as r { REAL (num_of_stringfloat r) }
| integer as i { INT (Num.num_of_string i) }
| "("
{ LEFTPAR }
| ")"
{ RIGHTPAR }
| "."
{ DOT }
| "?"
{ QMARK }
| "+"
{ PLUS }
| "-"
{ MINUS }
| "*"
{ TIMES }
| ":"
{ COLON }
| "="
{ EQ }
| "=>"
{ IMP }
| "<=>"
{ EQUIV }
| ":="
{ AFFECT }
| "<>"
{ NEQ }
| "<"
{ LT }
| "<="
{ LE }
| ">"
{ GT }
| ">="
{ GE }
| "["
{ LEFTSQ }
| "]"
{ RIGHTSQ }
| "{"
{ LEFTBR }
| "}"
{ RIGHTBR }
| "||"
{ OR }
| "|"
{ BAR }
| ","
{ COMMA }
| ";"
{ PV }
| '_'
{ UNDERSCORE }
| "&&"
{ AND }
| "(*"
{ comment lexbuf; token lexbuf }
| eof
{ EOF }
| _ as c
{ raise (Lexical_error ("illegal character: " ^ String.make 1 c)) }
and comment = parse
| "*)"
{ () }
| "(*"
{ comment lexbuf; comment lexbuf }
| eof
{ raise (Lexical_error "unterminated comment") }
| newline
{ newline lexbuf; comment lexbuf }
| _
{ comment lexbuf }