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