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)
 
  44   fun hexnumber (yyt, yyp) =
 
  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
 
  51                                 ("integral constant `" ^ yyt ^ "' too large") ;
 
  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)
 
  62       ( if (!commentLevel > 0)
 
  63           then (ErrorMsg.error (ParseState.ext (!commentPos,!commentPos)) "unterminated comment")
 
  65         Tokens.EOF (0,0) )              (* bogus position information; unused *)
 
  70 %header (functor L5LexFn(structure Tokens : L5_TOKENS));
 
  72 %s COMMENT COMMENT_LINE;
 
  74 id = [A-Za-z_][A-Za-z0-9_]*;
 
  76 hexnum = 0x[0-9a-fA-F][0-9a-fA-F]*;
 
  82 <INITIAL> {ws}+       => (lex ());
 
  83 <INITIAL> \n          => (ParseState.newline(yypos); lex());
 
  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));
 
  90 <INITIAL> ";"         => (Tokens.SEMI (yypos, yypos + size yytext));
 
  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));
 
 104 <INITIAL> "++"         => (Tokens.PLUSPLUS (yypos, yypos + size yytext));
 
 105 <INITIAL> "--"         => (Tokens.MINUSMINUS (yypos, yypos + size yytext));
 
 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));
 
 128 <INITIAL> "?"         => (Tokens.QUESTION (yypos, yypos + size yytext));
 
 129 <INITIAL> ":"         => (Tokens.COLON (yypos, yypos + size yytext));
 
 130 <INITIAL> ","         => (Tokens.COMMA (yypos, yypos + size yytext));
 
 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));
 
 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));
 
 152 <INITIAL> {decnum}    => (number (yytext, yypos));
 
 153 <INITIAL> {hexnum}    => (hexnumber (yytext, yypos));
 
 155 <INITIAL> {id}        => (let
 
 156                             val id = Symbol.symbol yytext
 
 158                             Tokens.IDENT (id, yypos, yypos + size yytext)
 
 161 <INITIAL> "/*"        => (YYBEGIN COMMENT; enterComment yypos; lex());
 
 162 <INITIAL> "*/"        => (ErrorMsg.error (ParseState.ext (yypos, yypos)) "unbalanced comments";
 
 165 <INITIAL> "//"        => (YYBEGIN COMMENT_LINE; lex());
 
 166 <INITIAL> "#"         => (YYBEGIN COMMENT_LINE; lex());
 
 167 <INITIAL> .           => (ErrorMsg.error (ParseState.ext (yypos,yypos))
 
 168                               ("illegal character: \"" ^ yytext ^ "\"");
 
 171 <COMMENT> "/*"        => (enterComment yypos; lex());
 
 172 <COMMENT> "*/"        => (if exitComment () then YYBEGIN INITIAL else (); lex());
 
 173 <COMMENT> \n          => (ParseState.newline yypos; lex ());
 
 174 <COMMENT> .           => (lex());
 
 176 <COMMENT_LINE> \n     => (ParseState.newline yypos; YYBEGIN INITIAL; lex());
 
 177 <COMMENT_LINE> .      => (lex());