-
Notifications
You must be signed in to change notification settings - Fork 1
/
miniml_lex.mll
78 lines (72 loc) · 1.75 KB
/
miniml_lex.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
(*
CS 51 Final Project
MiniML -- Lexical Analyzer
Spring 2017
*)
{
open Printf ;;
open Miniml_parse ;; (* need access to parser's token definitions *)
let create_hashtable size init =
let tbl = Hashtbl.create size in
List.iter (fun (key, data) -> Hashtbl.add tbl key data) init;
tbl
let keyword_table =
create_hashtable 8 [
("if", IF);
("in", IN);
("then", THEN);
("else", ELSE);
("let", LET);
("raise", RAISE);
("rec", REC);
("true", TRUE);
("false", FALSE);
("lambda", FUNCTION);
("fun", FUNCTION);
("function", FUNCTION)
]
let sym_table =
create_hashtable 8 [
("=", EQUALS);
("<", LESSTHAN);
(".", DOT);
("->", DOT);
(";;", EOF);
("~", NEG);
("+", PLUS);
("-", MINUS);
("*", TIMES);
("(", OPEN);
(")", CLOSE)
]
}
let digit = ['0'-'9']
let id = ['a'-'z'] ['a'-'z' '0'-'9']*
let sym = ['(' ')'] | (['+' '-' '*' '.' '=' '~' ';' '<' '>']+)
rule token = parse
| digit+ as inum
{ let num = int_of_string inum in
INT num
}
| id as word
{ try
let token = Hashtbl.find keyword_table word in
token
with Not_found ->
ID word
}
| sym as symbol
{ try
let token = Hashtbl.find sym_table symbol in
token
with Not_found ->
token lexbuf
}
| '{' [^ '\n']* '}' { token lexbuf } (* skip one-line comments *)
| [' ' '\t' '\n'] { token lexbuf } (* skip whitespace *)
| _ as c (* warn and skip unrecognized characters *)
{ printf "Unrecognized character: %c\n" c;
token lexbuf
}
| eof
{ raise End_of_file }