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>
13 type svalue = Tokens.svalue
14 type ('a,'b) token = ('a,'b) Tokens.token
15 type lexresult = (svalue,pos) Tokens.token
18 val commentLevel = ref 0
19 val commentPos = ref 0
21 fun enterComment yypos =
22 ( commentLevel := !commentLevel + 1 ;
26 ( commentLevel := !commentLevel - 1 ;
29 fun number (yyt, yyp) =
31 val ext = ParseState.ext (yyp, yyp + size yyt)
32 val numOpt = Word32Signed.fromString yyt
35 ("integral constant `" ^ yyt ^ "' too large") ;
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)
46 ( if (!commentLevel > 0)
47 then (ErrorMsg.error (ParseState.ext (!commentPos,!commentPos)) "unterminated comment")
49 Tokens.EOF (0,0) ) (* bogus position information; unused *)
54 %header (functor L4LexFn(structure Tokens : L4_TOKENS));
56 %s COMMENT COMMENT_LINE;
58 id = [A-Za-z_][A-Za-z0-9_]*;
65 <INITIAL> {ws}+ => (lex ());
66 <INITIAL> \n => (ParseState.newline(yypos); lex());
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));
73 <INITIAL> ";" => (Tokens.SEMI (yypos, yypos + size yytext));
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));
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));
108 <INITIAL> ":" => (Tokens.COLON (yypos, yypos + size yytext));
109 <INITIAL> "," => (Tokens.COMMA (yypos, yypos + size yytext));
111 <INITIAL> "[" => (Tokens.LBRACKET (yypos, yypos + size yytext));
112 <INITIAL> "]" => (Tokens.RBRACKET (yypos, yypos + size yytext));
113 <INITIAL> "->" => (Tokens.ARROW (yypos, yypos + size yytext));
114 <INITIAL> "." => (Tokens.DOT (yypos, yypos + size yytext));
116 <INITIAL> "return" => (Tokens.RETURN (yypos, yypos + size yytext));
117 <INITIAL> "if" => (Tokens.IF (yypos, yypos + size yytext));
118 <INITIAL> "while" => (Tokens.WHILE (yypos, yypos + size yytext));
119 <INITIAL> "for" => (Tokens.FOR (yypos, yypos + size yytext));
120 <INITIAL> "continue" => (Tokens.CONTINUE (yypos, yypos + size yytext));
121 <INITIAL> "break" => (Tokens.BREAK (yypos, yypos + size yytext));
122 <INITIAL> "else" => (Tokens.ELSE (yypos, yypos + size yytext));
123 <INITIAL> "var" => (Tokens.VAR (yypos, yypos + size yytext));
124 <INITIAL> "int" => (Tokens.INT (yypos, yypos + size yytext));
125 <INITIAL> "extern" => (Tokens.EXTERN (yypos, yypos + size yytext));
126 <INITIAL> "struct" => (Tokens.STRUCT (yypos, yypos + size yytext));
127 <INITIAL> "NULL" => (Tokens.NULL (yypos, yypos + size yytext));
128 <INITIAL> "new" => (Tokens.NEW (yypos, yypos + size yytext));
131 <INITIAL> {decnum} => (number (yytext, yypos));
133 <INITIAL> {id} => (let
134 val id = Symbol.symbol yytext
136 Tokens.IDENT (id, yypos, yypos + size yytext)
139 <INITIAL> "/*" => (YYBEGIN COMMENT; enterComment yypos; lex());
140 <INITIAL> "*/" => (ErrorMsg.error (ParseState.ext (yypos, yypos)) "unbalanced comments";
143 <INITIAL> "//" => (YYBEGIN COMMENT_LINE; lex());
144 <INITIAL> "#" => (YYBEGIN COMMENT_LINE; lex());
145 <INITIAL> . => (ErrorMsg.error (ParseState.ext (yypos,yypos))
146 ("illegal character: \"" ^ yytext ^ "\"");
149 <COMMENT> "/*" => (enterComment yypos; lex());
150 <COMMENT> "*/" => (if exitComment () then YYBEGIN INITIAL else (); lex());
151 <COMMENT> \n => (ParseState.newline yypos; lex ());
152 <COMMENT> . => (lex());
154 <COMMENT_LINE> \n => (ParseState.newline yypos; YYBEGIN INITIAL; lex());
155 <COMMENT_LINE> . => (lex());