-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmylang.lex
71 lines (52 loc) · 2.54 KB
/
mylang.lex
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
structure Tokens = Tokens
(* Any functions or values defined here will be available in the
semantic actions.
Set want_debug = true to get information from the lexer via stdout.
*)
type pos = int
type col = int
type svalue = Tokens.svalue
type ('a,'b) token = ('a,'b) Tokens.token
type lexresult= (svalue,pos) token
val lineNum = ref 1
val pos = ref 1
val col = ref 1
fun advance_column(str) = col := (!col) + String.size(str)
fun eof () = Tokens.EOF(!pos, !col)
fun error (e,l : int,_) = TextIO.output (TextIO.stdOut, String.concat[
"line ", (Int.toString l), ": ", e, "\n"
])
val want_debug = false;
fun debug str =
if want_debug then print ("lexer found: "^str^"\n") else ()
%%
%header (functor MyLangLexFun(structure Tokens: MyLang_TOKENS));
ws=[\ \t];
ALPHABETIC=[A-Za-z];
IDENTIFIER={ALPHABETIC}+;
STRLIT=\"{ALPHABETIC}+\";
LINE_COMMENT=\/\/.*;
BLOCK_COMMENT=##(#?[^#])*##;
%%
\n => (pos := (!pos) + 1; col := 0; debug (yytext^"=>return ");lex());
{ws}+ => (advance_column(yytext); debug (yytext^"=> whitespace ");lex());
[pP][rR][iI][nN][tT] => (debug (yytext^"=>RW_PRINT "); advance_column(yytext); Tokens.RW_PRINT(!pos, !col));
[cC][lL][aA][sS][sS] => (debug (yytext^"=>RW_CLASS "); advance_column(yytext); Tokens.RW_CLASS(!pos, !col));
[vV][oO][iI][dI] => (debug (yytext^"=>RW_VOID "); advance_column(yytext); Tokens.RW_VOID(!pos, !col));
{STRLIT} => (debug (yytext^"=>STRLIT "); advance_column(yytext); Tokens.STRLIT(yytext, !pos, !col));
";" => (debug (yytext^"=>SEMI "); advance_column(yytext);Tokens.SEMI(!pos, !col));
"{" => (debug (yytext^"=>LBRACE "); advance_column(yytext); Tokens.LBRACE(!pos, !col));
"}" => (debug (yytext^"=>RBRACE "); advance_column(yytext); Tokens.RBRACE(!pos, !col));
"(" => (debug (yytext^"=>LPAREN "); advance_column(yytext); Tokens.LPAREN(!pos, !col));
")" => (debug (yytext^"=>RPAREN "); advance_column(yytext); Tokens.RPAREN(!pos, !col));
{BLOCK_COMMENT} => (debug (yytext^"=>block comment");
let val num_nl = length(List.filter (fn c => c = #"\n") (explode yytext))
in
pos := (!pos) + num_nl;
lex()
end);
{IDENTIFIER} => (debug (yytext^"=>ID "); advance_column(yytext); Tokens.ID(yytext, !pos, !col));
{LINE_COMMENT} => (debug (yytext^"=>line comment");
lex());
. => (error ("Invalid Token: "^yytext, !pos,!pos);
OS.Process.exit(OS.Process.success));