-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathtoy_lang.mll
84 lines (74 loc) · 1.96 KB
/
toy_lang.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
{
open Printf
let create_hashtable size init =
let tbl = Hashtbl.create size in
List.iter (fun (key, data) -> Hashtbl.add tbl key data) init;
tbl
type token =
| IF
| THEN
| ELSE
| BEGIN
| END
| FUNCTION
| ID of string
| OP of char
| INT of int
| FLOAT of float
| CHAR of char
let keyword_table =
create_hashtable 8 [
("if", IF);
("then", THEN);
("else", ELSE);
("begin", BEGIN);
("end", END);
("function", FUNCTION)
]
}
let digit = ['0'-'9']
let id = ['a'-'z' 'A'-'Z']['a'-'z' '0'-'9']*
rule toy_lang = parse
| digit+ as inum {
let num = int_of_string inum in
printf "integer: %s (%d)\n" inum num;
INT num
}
| digit+ '.' digit* as fnum {
let num = float_of_string fnum in
printf "float: %s (%f)\n" fnum num;
FLOAT num
}
| id as word { try
let token = Hashtbl.find keyword_table word in
printf "keyword: %s\n" word;
token
with Not_found ->
printf "identifier: %s\n" word;
ID word
}
| '+'
| '-'
| '*'
| '/' as op { printf "operator: %c\n" op; OP op }
| '{' [^ '\n']* '}' (* eat up one-line comments *)
| [' ' '\t' '\n'] (* eat up whitespace *)
{ toy_lang lexbuf }
| _ as c { printf "Unrecognized character: %c\n" c; CHAR c }
| eof { raise End_of_file }
{
let rec parse lexbuf =
let _ = toy_lang lexbuf in
parse lexbuf
let () =
let cin =
if Array.length Sys.argv > 1 then
open_in Sys.argv.(1)
else
stdin
in
let lexbuf = Lexing.from_channel cin in
try
parse lexbuf
with End_of_file -> ()
}