comparison lab1/lexer.mll @ 0:bfdcc3820b32

Basis
author Mike Spivey <mike@cs.ox.ac.uk>
date Thu, 05 Oct 2017 08:04:15 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:bfdcc3820b32
1 (* lab1/lexer.mll *)
2 (* Copyright (c) 2017 J. M. Spivey *)
3
4 {
5 open Lexing
6 open Tree
7 open Keiko
8 open Parser
9
10 (* |lineno| -- line number for use in error messages *)
11 let lineno = ref 1
12
13 (* |make_hash| -- create hash table from list of pairs *)
14 let make_hash n ps =
15 let t = Hashtbl.create n in
16 List.iter (fun (k, v) -> Hashtbl.add t k v) ps;
17 t
18
19 (* |kwtable| -- a little table to recognize keywords *)
20 let kwtable =
21 make_hash 64
22 [ ("begin", BEGIN); ("do", DO); ("if", IF ); ("else", ELSE);
23 ("end", END); ("then", THEN); ("while", WHILE); ("print", PRINT);
24 ("newline", NEWLINE); ("and", MULOP And); ("div", MULOP Div);
25 ("or", ADDOP Or); ("not", MONOP Not); ("mod", MULOP Mod);
26 ("true", NUMBER 1); ("false", NUMBER 0) ]
27
28 (* |idtable| -- table of all identifiers seen so far *)
29 let idtable = Hashtbl.create 64
30
31 (* |lookup| -- convert string to keyword or identifier *)
32 let lookup s =
33 try Hashtbl.find kwtable s with
34 Not_found ->
35 Hashtbl.replace idtable s ();
36 IDENT s
37
38 (* |get_vars| -- get list of identifiers in the program *)
39 let get_vars () =
40 Hashtbl.fold (fun k () ks -> k::ks) idtable []
41 }
42
43 rule token =
44 parse
45 ['A'-'Z''a'-'z']['A'-'Z''a'-'z''0'-'9''_']* as s
46 { lookup s }
47 | ['0'-'9']+ as s { NUMBER (int_of_string s) }
48 | ";" { SEMI }
49 | "." { DOT }
50 | ":" { COLON }
51 | "(" { LPAR }
52 | ")" { RPAR }
53 | "," { COMMA }
54 | "=" { RELOP Eq }
55 | "+" { ADDOP Plus }
56 | "-" { MINUS }
57 | "*" { MULOP Times }
58 | "<" { RELOP Lt }
59 | ">" { RELOP Gt }
60 | "<>" { RELOP Neq }
61 | "<=" { RELOP Leq }
62 | ">=" { RELOP Geq }
63 | ":=" { ASSIGN }
64 | [' ''\t']+ { token lexbuf }
65 | "(*" { comment lexbuf; token lexbuf }
66 | "\n" { incr lineno; Source.note_line !lineno lexbuf;
67 token lexbuf }
68 | _ { BADTOK }
69 | eof { EOF }
70
71 and comment =
72 parse
73 "*)" { () }
74 | "\n" { incr lineno; Source.note_line !lineno lexbuf;
75 comment lexbuf }
76 | _ { comment lexbuf }
77 | eof { () }