1268896Sbapt(* Modified by sweeks@acm.org on 2000-8-24. 2268896Sbapt * Ported to MLton. 3268896Sbapt *) 4268896Sbapt 5268896Sbapt(* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi 6268896Sbapt 7268896Sbapt yacc.lex: Lexer specification 8268896Sbapt *) 9268896Sbapt 10268896Sbaptstructure Tokens = Tokens 11268896Sbapttype svalue = Tokens.svalue 12268896Sbapttype pos = int 13268896Sbapttype ('a,'b) token = ('a,'b) Tokens.token 14268896Sbapttype lexresult = (svalue,pos) token 15268896Sbapt 16268896Sbapttype lexarg = Hdr.inputSource 17268896Sbapttype arg = lexarg 18268896Sbapt 19268896Sbaptopen Tokens 20268896Sbaptval error = Hdr.error 21268896Sbaptval lineno = Hdr.lineno 22268896Sbaptval text = Hdr.text 23268896Sbapt 24268896Sbaptval pcount: int ref = ref 0 25268896Sbaptval commentLevel: int ref = ref 0 26268896Sbaptval actionstart: int ref = ref 0 27268896Sbapt 28268896Sbaptval eof = fn i => (if (!pcount)>0 then 29268896Sbapt error i (!actionstart) 30268896Sbapt " eof encountered in action beginning here !" 31268896Sbapt else (); EOF(!lineno,!lineno)) 32268896Sbapt 33268896Sbaptval Add = fn s => (text := s::(!text)) 34268896Sbapt 35268896Sbapt 36268896Sbaptlocal val dict = [("%prec",PREC_TAG),("%term",TERM), 37268896Sbapt ("%nonterm",NONTERM), ("%eop",PERCENT_EOP),("%start",START), 38268896Sbapt ("%prefer",PREFER),("%subst",SUBST),("%change",CHANGE), 39268896Sbapt ("%keyword",KEYWORD),("%name",NAME), 40268896Sbapt ("%verbose",VERBOSE), ("%nodefault",NODEFAULT), 41268896Sbapt ("%value",VALUE), ("%noshift",NOSHIFT), 42268896Sbapt ("%header",PERCENT_HEADER),("%pure",PERCENT_PURE), 43268896Sbapt ("%token_sig_info",PERCENT_TOKEN_SIG_INFO), 44268896Sbapt ("%arg",PERCENT_ARG), 45268896Sbapt ("%pos",PERCENT_POS)] 46268896Sbaptin val lookup = 47268896Sbapt fn (s,left,right) => 48268896Sbapt let fun f ((a,d)::b) = if a=s then d(left,right) else f b 49268896Sbapt | f nil = UNKNOWN(s,left,right) 50268896Sbapt in f dict 51268896Sbapt end 52268896Sbaptend 53268896Sbapt 54268896Sbaptfun inc (ri as ref i : int ref) = (ri := i+1) 55268896Sbaptfun dec (ri as ref i : int ref) = (ri := i-1) 56268896Sbapt 57268896Sbapt%% 58268896Sbapt%header ( 59268896Sbaptfunctor LexMLYACC(structure Tokens : Mlyacc_TOKENS 60268896Sbapt structure Hdr : HEADER (* = Header *) 61268896Sbapt where type prec = Header.prec 62268896Sbapt and type inputSource = Header.inputSource) : ARG_LEXER 63268896Sbapt); 64268896Sbapt%arg (inputSource); 65268896Sbapt%s A CODE F COMMENT STRING EMPTYCOMMENT; 66268896Sbaptws = [\t\ ]+; 67268896Sbaptidchars = [A-Za-z_'0-9]; 68268896Sbaptid=[A-Za-z]{idchars}*; 69tyvar="'"{idchars}*; 70qualid ={id}"."; 71%% 72<INITIAL>"(*" => (Add yytext; YYBEGIN COMMENT; commentLevel := 1; 73 continue(); YYBEGIN INITIAL; continue()); 74<A>"(*" => (YYBEGIN EMPTYCOMMENT; commentLevel := 1; continue()); 75<CODE>"(*" => (Add yytext; YYBEGIN COMMENT; commentLevel := 1; 76 continue(); YYBEGIN CODE; continue()); 77<INITIAL>[^(%\n]+ => (Add yytext; continue()); 78<INITIAL>"%%" => (YYBEGIN A; HEADER (concat (rev (!text)),!lineno,!lineno)); 79<INITIAL,CODE,COMMENT,F,EMPTYCOMMENT>\n => (Add yytext; inc lineno; continue()); 80<INITIAL>. => (Add yytext; continue()); 81 82<A>\n => (inc lineno; continue ()); 83<A>{ws}+ => (continue()); 84<A>of => (OF(!lineno,!lineno)); 85<A>for => (FOR(!lineno,!lineno)); 86<A>"{" => (LBRACE(!lineno,!lineno)); 87<A>"}" => (RBRACE(!lineno,!lineno)); 88<A>"," => (COMMA(!lineno,!lineno)); 89<A>"*" => (ASTERISK(!lineno,!lineno)); 90<A>"->" => (ARROW(!lineno,!lineno)); 91<A>"%left" => (PREC(Hdr.LEFT,!lineno,!lineno)); 92<A>"%right" => (PREC(Hdr.RIGHT,!lineno,!lineno)); 93<A>"%nonassoc" => (PREC(Hdr.NONASSOC,!lineno,!lineno)); 94<A>"%"[a-z_]+ => (lookup(yytext,!lineno,!lineno)); 95<A>{tyvar} => (TYVAR(yytext,!lineno,!lineno)); 96<A>{qualid} => (IDDOT(yytext,!lineno,!lineno)); 97<A>[0-9]+ => (INT (yytext,!lineno,!lineno)); 98<A>"%%" => (DELIMITER(!lineno,!lineno)); 99<A>":" => (COLON(!lineno,!lineno)); 100<A>"|" => (BAR(!lineno,!lineno)); 101<A>{id} => (ID ((yytext,!lineno),!lineno,!lineno)); 102<A>"(" => (pcount := 1; actionstart := (!lineno); 103 text := nil; YYBEGIN CODE; continue() before YYBEGIN A); 104<A>. => (UNKNOWN(yytext,!lineno,!lineno)); 105<CODE>"(" => (inc pcount; Add yytext; continue()); 106<CODE>")" => (dec pcount; 107 if !pcount = 0 then 108 PROG (concat (rev (!text)),!lineno,!lineno) 109 else (Add yytext; continue())); 110<CODE>"\"" => (Add yytext; YYBEGIN STRING; continue()); 111<CODE>[^()"\n]+ => (Add yytext; continue()); 112 113<COMMENT>[(*)] => (Add yytext; continue()); 114<COMMENT>"*)" => (Add yytext; dec commentLevel; 115 if !commentLevel=0 116 then BOGUS_VALUE(!lineno,!lineno) 117 else continue() 118 ); 119<COMMENT>"(*" => (Add yytext; inc commentLevel; continue()); 120<COMMENT>[^*()\n]+ => (Add yytext; continue()); 121 122<EMPTYCOMMENT>[(*)] => (continue()); 123<EMPTYCOMMENT>"*)" => (dec commentLevel; 124 if !commentLevel=0 then YYBEGIN A else (); 125 continue ()); 126<EMPTYCOMMENT>"(*" => (inc commentLevel; continue()); 127<EMPTYCOMMENT>[^*()\n]+ => (continue()); 128 129<STRING>"\"" => (Add yytext; YYBEGIN CODE; continue()); 130<STRING>\\ => (Add yytext; continue()); 131<STRING>\n => (Add yytext; error inputSource (!lineno) "unclosed string"; 132 inc lineno; YYBEGIN CODE; continue()); 133<STRING>[^"\\\n]+ => (Add yytext; continue()); 134<STRING>\\\" => (Add yytext; continue()); 135<STRING>\\[\ \t\n] => (Add yytext; 136 if substring(yytext,1,1)="\n" then inc lineno else (); 137 YYBEGIN F; continue()); 138 139<F>{ws} => (Add yytext; continue()); 140<F>\\ => (Add yytext; YYBEGIN STRING; continue()); 141<F>. => (Add yytext; error inputSource (!lineno) "unclosed string"; 142 YYBEGIN CODE; continue()); 143 144