]> Joshua Wise's Git repositories - snipe.git/blob - parse/l2.lex
9caa8e1a829e4fc91469f47a958c4002372af63a
[snipe.git] / parse / l2.lex
1 (* L2 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
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
51 end
52
53 %%
54 %header (functor L2LexFn(structure Tokens : L2_TOKENS));
55 %full
56 %s COMMENT COMMENT_LINE;
57
58 id = [A-Za-z_][A-Za-z0-9_]*;
59 decnum = [0-9][0-9]*;
60
61 ws = [\ \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));
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));
86
87 <INITIAL> "+"         => (Tokens.PLUS (yypos, yypos + size yytext));
88 <INITIAL> "-"         => (Tokens.MINUS (yypos, yypos + size yytext));
89 <INITIAL> "!"         => (Tokens.BANG (yypos, yypos + size yytext));
90 <INITIAL> "*"         => (Tokens.STAR (yypos, yypos + size yytext));
91 <INITIAL> "/"         => (Tokens.SLASH (yypos, yypos + size yytext));
92 <INITIAL> "%"         => (Tokens.PERCENT (yypos, yypos + size yytext));
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));
107
108 <INITIAL> "return"    => (Tokens.RETURN (yypos, yypos + size yytext));
109 <INITIAL> "if"        => (Tokens.IF (yypos, yypos + size yytext));
110 <INITIAL> "while"     => (Tokens.WHILE (yypos, yypos + size yytext));
111 <INITIAL> "for"       => (Tokens.FOR (yypos, yypos + size yytext));
112 <INITIAL> "continue"  => (Tokens.CONTINUE (yypos, yypos + size yytext));
113 <INITIAL> "break"     => (Tokens.BREAK (yypos, yypos + size yytext));
114 <INITIAL> "else"      => (Tokens.ELSE (yypos, yypos + size yytext));
115
116 <INITIAL> {decnum}    => (number (yytext, yypos));
117
118 <INITIAL> {id}        => (let
119                             val id = Symbol.symbol yytext
120                           in 
121                             Tokens.IDENT (id, yypos, yypos + size yytext)
122                           end);
123
124 <INITIAL> "/*"        => (YYBEGIN COMMENT; enterComment yypos; lex());
125 <INITIAL> "*/"        => (ErrorMsg.error (ParseState.ext (yypos, yypos)) "unbalanced comments";
126                           lex());
127
128 <INITIAL> "//"        => (YYBEGIN COMMENT_LINE; lex());
129 <INITIAL> "#"         => (YYBEGIN COMMENT_LINE; lex());
130 <INITIAL> .           => (ErrorMsg.error (ParseState.ext (yypos,yypos))
131                               ("illegal character: \"" ^ yytext ^ "\"");
132                           lex ());
133
134 <COMMENT> "/*"        => (enterComment yypos; lex());
135 <COMMENT> "*/"        => (if exitComment () then YYBEGIN INITIAL else (); lex());
136 <COMMENT> \n          => (ParseState.newline yypos; lex ());
137 <COMMENT> .           => (lex());
138
139 <COMMENT_LINE> \n     => (ParseState.newline yypos; YYBEGIN INITIAL; lex());
140 <COMMENT_LINE> .      => (lex());
This page took 0.022122 seconds and 2 git commands to generate.