]> Joshua Wise's Git repositories - snipe.git/blob - parse/l5.lex
e10f8b7da384d198bb047cce7e2c8f06a21fb1c4
[snipe.git] / parse / l5.lex
1 (* L5 Compiler
2  * Lexer
3  * Author: Kaustuv Chaudhuri <kaustuv+@cs.cmu.edu>
4  * Modified: Frank Pfenning <fp@cs.cmu.edu>
5  * Modified: Chris Lu <czl@andrew.cmu.edu>
6  * Modified: Joshua Wise <jwise@andrew.cmu.edu>
7  *)
8
9 structure A = Ast
10 structure S = Symbol
11
12 type pos = int
13 type svalue = Tokens.svalue
14 type ('a,'b) token = ('a,'b) Tokens.token
15 type lexresult = (svalue,pos) Tokens.token
16
17 local
18   val commentLevel = ref 0
19   val commentPos = ref 0
20 in
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   fun hexnumber (yyt, yyp) =
45       let
46         val t = String.extract (yyt, 2, NONE)
47         val ext = ParseState.ext (yyp, yyp + size yyt)
48         val numOpt = StringCvt.scanString (Word32.scan StringCvt.HEX) t
49                      handle Overflow =>
50                             ( ErrorMsg.error ext
51                                 ("integral constant `" ^ yyt ^ "' too large") ;
52                               NONE )
53       in
54         case numOpt
55           of NONE => ( ErrorMsg.error ext
56                          ("cannot parse integral constant `" ^ yyt ^ "'");
57                        Tokens.INTNUM (Word32Signed.ZERO, yyp, yyp + size yyt) )
58            | SOME n => Tokens.INTNUM (n,yyp,yyp + size yyt)
59       end
60
61   fun eof () = 
62       ( if (!commentLevel > 0)
63           then (ErrorMsg.error (ParseState.ext (!commentPos,!commentPos)) "unterminated comment")
64           else ();
65         Tokens.EOF (0,0) )              (* bogus position information; unused *)
66
67 end
68
69 %%
70 %header (functor L5LexFn(structure Tokens : L5_TOKENS));
71 %full
72 %s COMMENT COMMENT_LINE;
73
74 id = [A-Za-z_][A-Za-z0-9_]*;
75 decnum = [0-9][0-9]*;
76 hexnum = 0x[0-9a-fA-F][0-9a-fA-F]*;
77
78 ws = [\ \t\012];
79
80 %%
81
82 <INITIAL> {ws}+       => (lex ());
83 <INITIAL> \n          => (ParseState.newline(yypos); lex());
84
85 <INITIAL> "{"         => (Tokens.LBRACE (yypos, yypos + size yytext));
86 <INITIAL> "}"         => (Tokens.RBRACE (yypos, yypos + size yytext));
87 <INITIAL> "("         => (Tokens.LPAREN (yypos, yypos + size yytext));
88 <INITIAL> ")"         => (Tokens.RPAREN (yypos, yypos + size yytext));
89
90 <INITIAL> ";"         => (Tokens.SEMI (yypos, yypos + size yytext));
91
92 <INITIAL> "="         => (Tokens.ASSIGN (yypos, yypos + size yytext));
93 <INITIAL> "+="        => (Tokens.PLUSEQ (yypos, yypos + size yytext));
94 <INITIAL> "-="        => (Tokens.MINUSEQ (yypos, yypos + size yytext));
95 <INITIAL> "*="        => (Tokens.STAREQ (yypos, yypos + size yytext));
96 <INITIAL> "/="        => (Tokens.SLASHEQ (yypos, yypos + size yytext));
97 <INITIAL> "%="        => (Tokens.PERCENTEQ (yypos, yypos + size yytext));
98 <INITIAL> "<<="       => (Tokens.LSHEQ (yypos, yypos + size yytext));
99 <INITIAL> ">>="       => (Tokens.RSHEQ (yypos, yypos + size yytext));
100 <INITIAL> "&="        => (Tokens.BITANDEQ (yypos, yypos + size yytext));
101 <INITIAL> "^="        => (Tokens.BITXOREQ (yypos, yypos + size yytext));
102 <INITIAL> "|="        => (Tokens.BITOREQ (yypos, yypos + size yytext));
103
104 <INITIAL> "++"         => (Tokens.PLUSPLUS (yypos, yypos + size yytext));
105 <INITIAL> "--"         => (Tokens.MINUSMINUS (yypos, yypos + size yytext));
106
107 <INITIAL> "+"         => (Tokens.PLUS (yypos, yypos + size yytext));
108 <INITIAL> "-"         => (Tokens.MINUS (yypos, yypos + size yytext));
109 <INITIAL> "!"         => (Tokens.BANG (yypos, yypos + size yytext));
110 <INITIAL> "*"         => (Tokens.STAR (yypos, yypos + size yytext));
111 <INITIAL> "/"         => (Tokens.SLASH (yypos, yypos + size yytext));
112 <INITIAL> "%"         => (Tokens.PERCENT (yypos, yypos + size yytext));
113 <INITIAL> "<<"        => (Tokens.LSH (yypos, yypos + size yytext));
114 <INITIAL> ">>"        => (Tokens.RSH (yypos, yypos + size yytext));
115 <INITIAL> "||"        => (Tokens.LOGOR (yypos, yypos + size yytext));
116 <INITIAL> "&&"        => (Tokens.LOGAND (yypos, yypos + size yytext));
117 <INITIAL> "&"         => (Tokens.BITAND (yypos, yypos + size yytext));
118 <INITIAL> "^"         => (Tokens.BITXOR (yypos, yypos + size yytext));
119 <INITIAL> "|"         => (Tokens.BITOR (yypos, yypos + size yytext));
120 <INITIAL> "~"         => (Tokens.BITNOT (yypos, yypos + size yytext));
121 <INITIAL> "=="        => (Tokens.EQ (yypos, yypos + size yytext));
122 <INITIAL> "!="        => (Tokens.NEQ (yypos, yypos + size yytext));
123 <INITIAL> "<"         => (Tokens.LT (yypos, yypos + size yytext));
124 <INITIAL> "<="        => (Tokens.LE (yypos, yypos + size yytext));
125 <INITIAL> ">="        => (Tokens.GE (yypos, yypos + size yytext));
126 <INITIAL> ">"         => (Tokens.GT (yypos, yypos + size yytext));
127
128 <INITIAL> "?"         => (Tokens.QUESTION (yypos, yypos + size yytext));
129 <INITIAL> ":"         => (Tokens.COLON (yypos, yypos + size yytext));
130 <INITIAL> ","         => (Tokens.COMMA (yypos, yypos + size yytext));
131
132 <INITIAL> "["         => (Tokens.LBRACKET (yypos, yypos + size yytext));
133 <INITIAL> "]"         => (Tokens.RBRACKET (yypos, yypos + size yytext));
134 <INITIAL> "->"        => (Tokens.ARROW (yypos, yypos + size yytext));
135 <INITIAL> "."         => (Tokens.DOT (yypos, yypos + size yytext));
136
137 <INITIAL> "return"    => (Tokens.RETURN (yypos, yypos + size yytext));
138 <INITIAL> "if"        => (Tokens.IF (yypos, yypos + size yytext));
139 <INITIAL> "while"     => (Tokens.WHILE (yypos, yypos + size yytext));
140 <INITIAL> "for"       => (Tokens.FOR (yypos, yypos + size yytext));
141 <INITIAL> "continue"  => (Tokens.CONTINUE (yypos, yypos + size yytext));
142 <INITIAL> "break"     => (Tokens.BREAK (yypos, yypos + size yytext));
143 <INITIAL> "else"      => (Tokens.ELSE (yypos, yypos + size yytext));
144 <INITIAL> "var"       => (Tokens.VAR (yypos, yypos + size yytext));
145 <INITIAL> "int"       => (Tokens.INT (yypos, yypos + size yytext));
146 <INITIAL> "extern"    => (Tokens.EXTERN (yypos, yypos + size yytext));
147 <INITIAL> "struct"    => (Tokens.STRUCT (yypos, yypos + size yytext));
148 <INITIAL> "NULL"      => (Tokens.NULL (yypos, yypos + size yytext));
149 <INITIAL> "new"       => (Tokens.NEW (yypos, yypos + size yytext));
150
151
152 <INITIAL> {decnum}    => (number (yytext, yypos));
153 <INITIAL> {hexnum}    => (hexnumber (yytext, yypos));
154
155 <INITIAL> {id}        => (let
156                             val id = Symbol.symbol yytext
157                           in 
158                             Tokens.IDENT (id, yypos, yypos + size yytext)
159                           end);
160
161 <INITIAL> "/*"        => (YYBEGIN COMMENT; enterComment yypos; lex());
162 <INITIAL> "*/"        => (ErrorMsg.error (ParseState.ext (yypos, yypos)) "unbalanced comments";
163                           lex());
164
165 <INITIAL> "//"        => (YYBEGIN COMMENT_LINE; lex());
166 <INITIAL> "#"         => (YYBEGIN COMMENT_LINE; lex());
167 <INITIAL> .           => (ErrorMsg.error (ParseState.ext (yypos,yypos))
168                               ("illegal character: \"" ^ yytext ^ "\"");
169                           lex ());
170
171 <COMMENT> "/*"        => (enterComment yypos; lex());
172 <COMMENT> "*/"        => (if exitComment () then YYBEGIN INITIAL else (); lex());
173 <COMMENT> \n          => (ParseState.newline yypos; lex ());
174 <COMMENT> .           => (lex());
175
176 <COMMENT_LINE> \n     => (ParseState.newline yypos; YYBEGIN INITIAL; lex());
177 <COMMENT_LINE> .      => (lex());
This page took 0.037605 seconds and 4 git commands to generate.