Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/cm/parse/cm.lex
ViewVC logotype

Annotation of /sml/trunk/src/cm/parse/cm.lex

Parent Directory Parent Directory | Revision Log Revision Log


Revision 267 - (view) (download)

1 : blume 267 (* -*- sml -*-
2 :     *
3 :     * lexical analysis (ML-Lex specification) for CM description files
4 :     *
5 :     * (C) 1999 Lucent Technologies, Bell Laboratories
6 :     *
7 :     * Author: Matthias Blume (blume@kurims.kyoto-u.ac.jp)
8 :     *)
9 : blume 262
10 :     type svalue = Tokens.svalue
11 :     type pos = int
12 : blume 265
13 : blume 262 type ('a, 'b) token = ('a, 'b) Tokens.token
14 :     type lexresult = (svalue, pos) token
15 :    
16 : blume 265 type lexarg = {
17 :     enterC: unit -> unit,
18 :     leaveC: unit -> bool,
19 : blume 266 newS: pos * string -> unit,
20 : blume 265 addS: char -> unit,
21 :     addSC: string * int -> unit,
22 :     addSN: string * pos -> unit,
23 : blume 266 getS: pos * (string * pos * pos -> lexresult) -> lexresult,
24 : blume 265 handleEof: unit -> lexresult,
25 :     newline: pos -> unit,
26 :     error: pos -> string -> unit
27 :     }
28 : blume 262
29 : blume 265 type arg = lexarg
30 :    
31 :     fun eof (arg: lexarg) = (#handleEof arg ())
32 :    
33 :     (*
34 : blume 262 local
35 :     val depth = ref 0
36 :     val curstring = ref ([]: char list)
37 :     val startpos = ref 0
38 :     val instring = ref false
39 :     in
40 : blume 265
41 :    
42 : blume 262 fun resetAll () = (depth := 0; startpos := 0; instring := false)
43 :    
44 :     (* comment stuff *)
45 :     fun enterC () = depth := !depth + 1
46 :     fun leaveC () = let
47 :     val d = !depth - 1
48 :     val _ = depth := d
49 :     in
50 :     d = 0
51 :     end
52 :    
53 :     (* string stuff *)
54 :     fun newS sp = (curstring := []; startpos := sp; instring := true)
55 :     fun addS c = curstring := c :: (!curstring)
56 :     fun addSC (t, p, b) = addS (chr (ord (String.sub (t, 2)) - b))
57 :     fun addSN (t, p) = let
58 :     val ns = substring (t, 1, 3)
59 :     val n = Int.fromString ns
60 :     in
61 :     addS (chr (valOf n))
62 :     handle _ =>
63 :     ErrorMsg.error p ("illegal decimal char spec " ^ ns)
64 :     end
65 :     fun getS endpos =
66 :     (instring := false;
67 :     Tokens.STRING (implode (rev (!curstring)), !startpos, endpos + 1))
68 :    
69 :     (* handling EOF *)
70 : blume 265 fun eof (arg: ) = let
71 : blume 262 val pos = ErrorMsg.lastLinePos ()
72 :     in
73 :     if !depth > 0 then
74 :     ErrorMsg.error pos "unexpected EOF in COMMENT"
75 :     else if !instring then
76 :     ErrorMsg.error pos "unexpected EOF in STRING"
77 :     else ();
78 :     resetAll ();
79 :     Tokens.EOF(pos,pos)
80 :     end
81 :     end
82 : blume 265 *)
83 : blume 262
84 :     local
85 :     val idlist = [("Alias", Tokens.ALIAS),
86 :     ("Group", Tokens.GROUP),
87 :     ("Library", Tokens.LIBRARY),
88 :     ("is", Tokens.IS),
89 :     ("structure", Tokens.STRUCTURE),
90 :     ("signature", Tokens.SIGNATURE),
91 :     ("functor", Tokens.FUNCTOR),
92 :     ("funsig", Tokens.FUNSIG),
93 :     ("defined", Tokens.DEFINED),
94 :     ("div", Tokens.DIV),
95 :     ("mod", Tokens.MOD),
96 :     ("andalso", Tokens.ANDALSO),
97 :     ("orelse", Tokens.ORELSE),
98 :     ("not", Tokens.NOT)]
99 :     in
100 :     fun idToken (t, p) =
101 :     case List.find (fn (id, _) => id = t) idlist of
102 : blume 265 NONE => Tokens.FILE_STANDARD (t, p, p + size t)
103 : blume 262 | SOME (_, tok) => tok (p, p + size t)
104 :     end
105 :    
106 : blume 265 (* states:
107 : blume 262
108 : blume 265 INITIAL -> C
109 :     |
110 :     +------> P -> PC
111 :     | |
112 :     | +--> PM -> PMC
113 :     |
114 :     +------> M -> MC
115 :     |
116 :     +------> S -> SS
117 : blume 266 |
118 :     +------> ES -> E
119 : blume 265
120 :     "C" -- COMMENT
121 :     "P" -- PREPROC
122 :     "M" -- MLSYMBOL
123 :     "S" -- STRING
124 :     "SS" -- STRINGSKIP
125 : blume 266 "ES" -- ERRORSTART
126 :     "E" -- ERROR
127 : blume 265 *)
128 :    
129 : blume 262 %%
130 :    
131 : blume 266 %s C P PC PM PMC M MC S SS E ES;
132 : blume 265
133 : blume 262 %header(functor CMLexFun (structure Tokens: CM_TOKENS));
134 :    
135 : blume 265 %arg ({ enterC, leaveC,
136 :     newS, addS, addSC, addSN, getS,
137 :     handleEof,
138 :     newline,
139 :     error });
140 :    
141 : blume 262 idchars=[A-Za-z'_0-9];
142 :     id=[A-Za-z]{idchars}*;
143 : blume 265 cmextrachars=[!%&$+/<=>?@~|#*]|\-|\^;
144 :     cmidchars={idchars}|{cmextrachars};
145 :     cmid={cmextrachars}+;
146 : blume 262 ws=("\012"|[\t\ ]);
147 :     eol=("\013\010"|"\013"|"\010");
148 :     sym=[!%&$+/:<=>?@~|#*]|\-|\^|"\\";
149 :     digit=[0-9];
150 :     sharp="#";
151 :     %%
152 :    
153 : blume 265 <INITIAL>"(*" => (enterC (); YYBEGIN C; continue ());
154 :     <P>"(*" => (enterC (); YYBEGIN PC; continue ());
155 :     <PM>"(*" => (enterC (); YYBEGIN PMC; continue ());
156 :     <M>"(*" => (enterC (); YYBEGIN MC; continue ());
157 :    
158 :     <C,PC,PMC,MC>"(*" => (enterC (); continue ());
159 :    
160 :     <C>"*)" => (if leaveC () then YYBEGIN INITIAL else ();
161 : blume 262 continue ());
162 : blume 265 <PC>"*)" => (if leaveC () then YYBEGIN P else ();
163 :     continue ());
164 :     <PMC>"*)" => (if leaveC () then YYBEGIN PM else ();
165 :     continue ());
166 :     <MC>"*)" => (if leaveC () then YYBEGIN M else ();
167 :     continue ());
168 :     <C,PC,PMC,MC>{eol} => (newline yypos; continue ());
169 :     <C,PC,PMC,MC>. => (continue ());
170 : blume 262
171 : blume 265 <INITIAL,P,PM,M>"*)" => (error yypos "unmatched comment delimiter";
172 :     continue ());
173 : blume 262
174 : blume 266 <INITIAL>"\"" => (YYBEGIN S; newS (yypos, "string"); continue ());
175 : blume 262
176 : blume 265 <S>"\\a" => (addS #"\a"; continue ());
177 :     <S>"\\b" => (addS #"\b"; continue ());
178 :     <S>"\\f" => (addS #"\f"; continue ());
179 :     <S>"\\n" => (addS #"\n"; continue ());
180 :     <S>"\\r" => (addS #"\r"; continue ());
181 :     <S>"\\t" => (addS #"\t"; continue ());
182 :     <S>"\\v" => (addS #"\v"; continue ());
183 : blume 262
184 : blume 265 <S>"\\^"@ => (addS (chr 0); continue ());
185 :     <S>"\\^"[a-z] => (addSC (yytext, ord #"a"); continue ());
186 :     <S>"\\^"[A-Z] => (addSC (yytext, ord #"A"); continue ());
187 :     <S>"\\^[" => (addS (chr 27); continue ());
188 :     <S>"\\^\\" => (addS (chr 28); continue ());
189 :     <S>"\\^]" => (addS (chr 29); continue ());
190 :     <S>"\\^^" => (addS (chr 30); continue ());
191 :     <S>"\\^_" => (addS (chr 31); continue ());
192 : blume 262
193 : blume 265 <S>"\\"[0-9][0-9][0-9] => (addSN (yytext, yypos); continue ());
194 : blume 262
195 : blume 265 <S>"\\\"" => (addS #"\""; continue ());
196 :     <S>"\\\\" => (addS #"\\"; continue ());
197 :    
198 :     <S>"\\"{eol} => (YYBEGIN SS; newline (yypos + 1); continue ());
199 :     <S>"\\"{ws}+ => (YYBEGIN SS; continue ());
200 :    
201 :     <S>"\\". => (error yypos
202 : blume 262 ("illegal escape character in string " ^ yytext);
203 :     continue ());
204 :    
205 : blume 266 <S>"\"" => (YYBEGIN INITIAL; getS (yypos, Tokens.FILE_NATIVE));
206 : blume 265 <S>{eol} => (newline yypos;
207 :     error yypos "illegal linebreak in string";
208 : blume 262 continue ());
209 :    
210 : blume 265 <S>. => (addS (String.sub (yytext, 0)); continue ());
211 :    
212 :     <SS>{eol} => (newline yypos; continue ());
213 :     <SS>{ws}+ => (continue ());
214 :     <SS>"\\" => (YYBEGIN S; continue ());
215 :     <SS>. => (error yypos
216 : blume 262 ("illegal character in stringskip " ^ yytext);
217 :     continue ());
218 :    
219 : blume 265 <INITIAL,P>"(" => (Tokens.LPAREN (yypos, yypos + 1));
220 :     <INITIAL,P>")" => (Tokens.RPAREN (yypos, yypos + 1));
221 : blume 262 <INITIAL>":" => (Tokens.COLON (yypos, yypos + 1));
222 : blume 265 <P>"+" => (Tokens.PLUS (yypos, yypos + 1));
223 :     <P>"-" => (Tokens.MINUS (yypos, yypos + 1));
224 :     <P>"*" => (Tokens.TIMES (yypos, yypos + 1));
225 :     <P>"<>" => (Tokens.NE (yypos, yypos + 2));
226 :     <P>"<=" => (Tokens.LE (yypos, yypos + 2));
227 :     <P>"<" => (Tokens.LT (yypos, yypos + 1));
228 :     <P>">=" => (Tokens.GE (yypos, yypos + 2));
229 :     <P>">" => (Tokens.GT (yypos, yypos + 1));
230 :     <P>"=" => (Tokens.EQ (yypos, yypos + 1));
231 :     <P>"~" => (Tokens.TILDE (yypos, yypos + 1));
232 : blume 262
233 : blume 265 <P>{digit}+ => (Tokens.NUMBER
234 : blume 262 (valOf (Int.fromString yytext)
235 :     handle _ =>
236 : blume 265 (error yypos "number too large"; 0),
237 : blume 262 yypos, yypos + size yytext));
238 :    
239 : blume 265 <P>{id} => (Tokens.CM_ID (yytext, yypos, yypos + size yytext));
240 :    
241 :     <M>({id}|{sym}+) => (YYBEGIN INITIAL;
242 :     Tokens.ML_ID (yytext, yypos, yypos + size yytext));
243 :     <PM>({id}|{sym}+) => (YYBEGIN P;
244 :     Tokens.ML_ID (yytext, yypos, yypos + size yytext));
245 :    
246 :     <INITIAL>{eol}{sharp}{ws}*"if" => (YYBEGIN P;
247 :     newline yypos;
248 :     Tokens.IF (yypos, yypos + size yytext));
249 :     <INITIAL>{eol}{sharp}{ws}*"then" => (YYBEGIN P;
250 :     newline yypos;
251 :     Tokens.THEN (yypos, yypos + size yytext));
252 :     <INITIAL>{eol}{sharp}{ws}*"elif" => (YYBEGIN P;
253 :     newline yypos;
254 :     Tokens.ELIF (yypos, yypos + size yytext));
255 :     <INITIAL>{eol}{sharp}{ws}*"else" => (YYBEGIN P;
256 :     newline yypos;
257 :     Tokens.ELSE (yypos, yypos + size yytext));
258 :     <INITIAL>{eol}{sharp}{ws}*"endif" => (YYBEGIN P;
259 :     newline yypos;
260 :     Tokens.ENDIF (yypos,
261 : blume 262 yypos + size yytext));
262 : blume 266 <INITIAL>{eol}{sharp}{ws}*"error" => (YYBEGIN ES; newline yypos;
263 :     newS (yypos, "error"); continue ());
264 :     <ES>{ws}+ => (continue ());
265 :     <ES>{eol} => (YYBEGIN INITIAL; newline yypos;
266 :     getS (yypos, Tokens.ERROR));
267 :     <ES>. => (YYBEGIN E;
268 :     addS (String.sub (yytext, 0)); continue ());
269 :     <E>{eol} => (YYBEGIN INITIAL; newline yypos;
270 :     getS (yypos, Tokens.ERROR));
271 :     <E>. => (addS (String.sub (yytext, 0)); continue ());
272 : blume 262
273 : blume 265 <INITIAL,M,PM>{eol} => (newline yypos; continue ());
274 :     <P>{eol} => (YYBEGIN INITIAL; newline yypos; continue ());
275 :    
276 :     <INITIAL,M,PM,P>{ws}+ => (continue ());
277 :    
278 :     <M,PM>. => (error yypos
279 :     ("illegal character at start of ML symbol: " ^
280 :     yytext);
281 : blume 262 continue ());
282 : blume 265
283 :     <INITIAL>{cmid} => (idToken (yytext, yypos));
284 :    
285 :    
286 :     <INITIAL>. => (error yypos
287 :     ("illegal character: " ^ yytext);
288 :     continue ());

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0