]> Joshua Wise's Git repositories - snipe.git/blame - parse/l3.lex
Initial import of l3c
[snipe.git] / parse / l3.lex
CommitLineData
6ade8b0a 1(* L3 Compiler
12aa4087
JW
2 * Lexer
3 * Author: Kaustuv Chaudhuri <kaustuv+@cs.cmu.edu>
4 * Modified: Frank Pfenning <fp@cs.cmu.edu>
0a24e44d
JW
5 * Modified: Chris Lu <czl@andrew.cmu.edu>
6 * Modified: Joshua Wise <jwise@andrew.cmu.edu>
12aa4087
JW
7 *)
8
9structure A = Ast
10structure S = Symbol
11
12type pos = int
13type svalue = Tokens.svalue
14type ('a,'b) token = ('a,'b) Tokens.token
15type lexresult = (svalue,pos) Tokens.token
16
17local
18 val commentLevel = ref 0
19 val commentPos = ref 0
20in
21 fun enterComment yypos =
22 ( commentLevel := !commentLevel + 1 ;
23 commentPos := yypos )
24
25 fun exitComment () =
26 ( commentLevel := !commentLevel - 1 ;
27 !commentLevel = 0 )
28
29 fun number (yyt, yyp) =
30 let
31 val ext = ParseState.ext (yyp, yyp + size yyt)
32 val numOpt = Word32Signed.fromString yyt
33 handle Overflow =>
34 ( ErrorMsg.error ext
35 ("integral constant `" ^ yyt ^ "' too large") ;
36 NONE )
37 in
38 case numOpt
39 of NONE => ( ErrorMsg.error ext
40 ("cannot parse integral constant `" ^ yyt ^ "'");
41 Tokens.INTNUM (Word32Signed.ZERO, yyp, yyp + size yyt) )
42 | SOME n => Tokens.INTNUM (n,yyp,yyp + size yyt)
43 end
44
45 fun eof () =
46 ( if (!commentLevel > 0)
47 then (ErrorMsg.error (ParseState.ext (!commentPos,!commentPos)) "unterminated comment")
48 else ();
49 Tokens.EOF (0,0) ) (* bogus position information; unused *)
50
51end
52
53%%
6ade8b0a 54%header (functor L3LexFn(structure Tokens : L3_TOKENS));
12aa4087
JW
55%full
56%s COMMENT COMMENT_LINE;
57
58id = [A-Za-z_][A-Za-z0-9_]*;
59decnum = [0-9][0-9]*;
60
61ws = [\ \t\012];
62
63%%
64
65<INITIAL> {ws}+ => (lex ());
66<INITIAL> \n => (ParseState.newline(yypos); lex());
67
68<INITIAL> "{" => (Tokens.LBRACE (yypos, yypos + size yytext));
69<INITIAL> "}" => (Tokens.RBRACE (yypos, yypos + size yytext));
70<INITIAL> "(" => (Tokens.LPAREN (yypos, yypos + size yytext));
71<INITIAL> ")" => (Tokens.RPAREN (yypos, yypos + size yytext));
72
73<INITIAL> ";" => (Tokens.SEMI (yypos, yypos + size yytext));
74
75<INITIAL> "=" => (Tokens.ASSIGN (yypos, yypos + size yytext));
76<INITIAL> "+=" => (Tokens.PLUSEQ (yypos, yypos + size yytext));
77<INITIAL> "-=" => (Tokens.MINUSEQ (yypos, yypos + size yytext));
78<INITIAL> "*=" => (Tokens.STAREQ (yypos, yypos + size yytext));
79<INITIAL> "/=" => (Tokens.SLASHEQ (yypos, yypos + size yytext));
80<INITIAL> "%=" => (Tokens.PERCENTEQ (yypos, yypos + size yytext));
0a24e44d
JW
81<INITIAL> "<<=" => (Tokens.LSHEQ (yypos, yypos + size yytext));
82<INITIAL> ">>=" => (Tokens.RSHEQ (yypos, yypos + size yytext));
83<INITIAL> "&=" => (Tokens.BITANDEQ (yypos, yypos + size yytext));
84<INITIAL> "^=" => (Tokens.BITXOREQ (yypos, yypos + size yytext));
85<INITIAL> "|=" => (Tokens.BITOREQ (yypos, yypos + size yytext));
12aa4087
JW
86
87<INITIAL> "+" => (Tokens.PLUS (yypos, yypos + size yytext));
88<INITIAL> "-" => (Tokens.MINUS (yypos, yypos + size yytext));
0a24e44d 89<INITIAL> "!" => (Tokens.BANG (yypos, yypos + size yytext));
12aa4087
JW
90<INITIAL> "*" => (Tokens.STAR (yypos, yypos + size yytext));
91<INITIAL> "/" => (Tokens.SLASH (yypos, yypos + size yytext));
92<INITIAL> "%" => (Tokens.PERCENT (yypos, yypos + size yytext));
0a24e44d
JW
93<INITIAL> "<<" => (Tokens.LSH (yypos, yypos + size yytext));
94<INITIAL> ">>" => (Tokens.RSH (yypos, yypos + size yytext));
95<INITIAL> "||" => (Tokens.LOGOR (yypos, yypos + size yytext));
96<INITIAL> "&&" => (Tokens.LOGAND (yypos, yypos + size yytext));
97<INITIAL> "&" => (Tokens.BITAND (yypos, yypos + size yytext));
98<INITIAL> "^" => (Tokens.BITXOR (yypos, yypos + size yytext));
99<INITIAL> "|" => (Tokens.BITOR (yypos, yypos + size yytext));
100<INITIAL> "~" => (Tokens.BITNOT (yypos, yypos + size yytext));
101<INITIAL> "==" => (Tokens.EQ (yypos, yypos + size yytext));
102<INITIAL> "!=" => (Tokens.NEQ (yypos, yypos + size yytext));
103<INITIAL> "<" => (Tokens.LT (yypos, yypos + size yytext));
104<INITIAL> "<=" => (Tokens.LE (yypos, yypos + size yytext));
105<INITIAL> ">=" => (Tokens.GE (yypos, yypos + size yytext));
106<INITIAL> ">" => (Tokens.GT (yypos, yypos + size yytext));
12aa4087 107
6ade8b0a
JW
108<INITIAL> ":" => (Tokens.COLON (yypos, yypos + size yytext));
109<INITIAL> "," => (Tokens.COMMA (yypos, yypos + size yytext));
110
12aa4087 111<INITIAL> "return" => (Tokens.RETURN (yypos, yypos + size yytext));
0a24e44d
JW
112<INITIAL> "if" => (Tokens.IF (yypos, yypos + size yytext));
113<INITIAL> "while" => (Tokens.WHILE (yypos, yypos + size yytext));
114<INITIAL> "for" => (Tokens.FOR (yypos, yypos + size yytext));
115<INITIAL> "continue" => (Tokens.CONTINUE (yypos, yypos + size yytext));
116<INITIAL> "break" => (Tokens.BREAK (yypos, yypos + size yytext));
117<INITIAL> "else" => (Tokens.ELSE (yypos, yypos + size yytext));
6ade8b0a
JW
118<INITIAL> "var" => (Tokens.VAR (yypos, yypos + size yytext));
119<INITIAL> "int" => (Tokens.INT (yypos, yypos + size yytext));
120<INITIAL> "extern" => (Tokens.EXTERN (yypos, yypos + size yytext));
121
12aa4087
JW
122
123<INITIAL> {decnum} => (number (yytext, yypos));
124
125<INITIAL> {id} => (let
126 val id = Symbol.symbol yytext
127 in
128 Tokens.IDENT (id, yypos, yypos + size yytext)
129 end);
130
131<INITIAL> "/*" => (YYBEGIN COMMENT; enterComment yypos; lex());
132<INITIAL> "*/" => (ErrorMsg.error (ParseState.ext (yypos, yypos)) "unbalanced comments";
133 lex());
134
135<INITIAL> "//" => (YYBEGIN COMMENT_LINE; lex());
136<INITIAL> "#" => (YYBEGIN COMMENT_LINE; lex());
137<INITIAL> . => (ErrorMsg.error (ParseState.ext (yypos,yypos))
138 ("illegal character: \"" ^ yytext ^ "\"");
139 lex ());
140
141<COMMENT> "/*" => (enterComment yypos; lex());
142<COMMENT> "*/" => (if exitComment () then YYBEGIN INITIAL else (); lex());
143<COMMENT> \n => (ParseState.newline yypos; lex ());
144<COMMENT> . => (lex());
145
146<COMMENT_LINE> \n => (ParseState.newline yypos; YYBEGIN INITIAL; lex());
147<COMMENT_LINE> . => (lex());
This page took 0.037385 seconds and 4 git commands to generate.