1 |
@q scanner.web @> |
2 |
@q CWEB file for creating the Flex input file for 'animctrl' @> |
3 |
@q (Animation Controller) @> |
4 |
@q Created by Laurence Finston Do Mai 12 12:23:05 CEST 2005 @> |
5 |
|
6 |
@q * (1) Copyright and License.@> |
7 |
|
8 |
@q This file is part of GNU 3DLDF, a package for three-dimensional drawing. @> |
9 |
@q Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, @> |
10 |
@q 2011 The Free Software Foundation @> |
11 |
|
12 |
@q GNU 3DLDF is free software; you can redistribute it and/or modify @> |
13 |
@q it under the terms of the GNU General Public License as published by @> |
14 |
@q the Free Software Foundation; either version 3 of the License, or @> |
15 |
@q (at your option) any later version. @> |
16 |
|
17 |
@q GNU 3DLDF is distributed in the hope that it will be useful, @> |
18 |
@q but WITHOUT ANY WARRANTY; without even the implied warranty of @> |
19 |
@q MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @> |
20 |
@q GNU General Public License for more details. @> |
21 |
|
22 |
@q You should have received a copy of the GNU General Public License @> |
23 |
@q along with GNU 3DLDF; if not, write to the Free Software @> |
24 |
@q Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA@> |
25 |
|
26 |
@q GNU 3DLDF is a GNU package. @> |
27 |
@q It is part of the GNU Project of the @> |
28 |
@q Free Software Foundation @> |
29 |
@q and is published under the GNU General Public License. @> |
30 |
@q See the website http://www.gnu.org @> |
31 |
@q for more information. @> |
32 |
@q GNU 3DLDF is available for downloading from @> |
33 |
@q http://www.gnu.org/software/3dldf/LDF.html.@> |
34 |
|
35 |
@q ("@@" stands for a single at-sign in the following paragraph.) @> |
36 |
|
37 |
@q Please send bug reports to Laurence.Finston@gmx.de@> |
38 |
@q The mailing list help-3dldf@@gnu.org is available for people to @> |
39 |
@q ask other users for help. @> |
40 |
@q The mailing list info-3dldf@@gnu.org is for sending @> |
41 |
@q announcements to users. To subscribe to these mailing lists, send an @> |
42 |
@q email with ``subscribe <email-address>'' as the subject. @> |
43 |
|
44 |
@q The author can be contacted at: @> |
45 |
|
46 |
@q Laurence D. Finston @> |
47 |
@q c/o Free Software Foundation, Inc. @> |
48 |
@q 51 Franklin St, Fifth Floor @> |
49 |
@q Boston, MA 02110-1301 @> |
50 |
@q USA @> |
51 |
|
52 |
@q Laurence.Finston@gmx.de (@@ stands for a single "at" sign.)@> |
53 |
|
54 |
|
55 |
@q $Id: scanner.web,v 1.6 2008/01/05 17:57:21 lfinsto1 Exp $ @> |
56 |
|
57 |
@q * (0) Scanner.@> |
58 |
@** Scanner. |
59 |
|
60 |
|
61 |
\LOG |
62 |
\initials{LDF 2005.05.12.} |
63 |
Created this file. Copied it from |
64 |
\filename{\char\~/3DLDF/CWEB/scan.web}, |
65 |
i.e., the CWEB source for the \.{3dldf} scanner. |
66 |
It must be adapted for use with \.{animctrl}, the Animation |
67 |
Controller. |
68 |
\ENDLOG |
69 |
|
70 |
|
71 |
@q * (1) yylex(). @> |
72 |
@* {\bf yylex()} definition. |
73 |
|yylex()| is declared in `parser.w', and the declaration is written to |
74 |
\filename{parser.h++}, which this file includes, so there's no need to |
75 |
repeat it here. |
76 |
\initials{LDF 2005.05.12.} |
77 |
|
78 |
@q ** (2) Definition. @> |
79 |
|
80 |
@<Define scanning functions@>= |
81 |
|
82 |
int |
83 |
yylex(YYSTYPE* value, |
84 |
YYLTYPE* location, |
85 |
void* parameter) |
86 |
{ |
87 |
|
88 |
|
89 |
@q *** (3) Preliminaries.@> |
90 |
@ Preliminaries. |
91 |
|
92 |
|
93 |
@<Define scanning functions@>= |
94 |
|
95 |
#if DEBUG_COMPILE |
96 |
bool DEBUG = false; /* |true| */ @; |
97 |
#endif /* |DEBUG_COMPILE| */@; |
98 |
|
99 |
using namespace Scan_Parse; |
100 |
|
101 |
stringstream cerr_strm; |
102 |
|
103 |
Scanner_Node scanner_node = static_cast<Scanner_Node>(parameter); |
104 |
|
105 |
bool error_stop_value = true; |
106 |
bool warning_stop_value = true; |
107 |
string thread_name = ""; |
108 |
|
109 |
@q **** (4) Error handling: |scanner_node == 0|.@> |
110 |
|
111 |
@ Error handling: |scanner_node == 0|. Signal an error and return |
112 |
|TERMINATE|. |
113 |
\initials{LDF 2004.09.30.} |
114 |
|
115 |
\LOG |
116 |
\initials{LDF 2004.09.30.} |
117 |
Added this section. |
118 |
\ENDLOG |
119 |
|
120 |
@<Define scanning functions@>= |
121 |
|
122 |
if (scanner_node == 0) |
123 |
{ |
124 |
|
125 |
cerr_strm << "ERROR! In `yylex()':" |
126 |
<< "`scanner_node' == 0." |
127 |
<< endl << "Can't continue. Exiting function " |
128 |
<< "with return value `TERMINATE'."; |
129 |
|
130 |
log_message(cerr_strm); |
131 |
cerr_message(cerr_strm); |
132 |
cerr_strm.str(""); |
133 |
|
134 |
return TERMINATE; |
135 |
|
136 |
} /* |if (scanner_node == 0)| */ |
137 |
|
138 |
|
139 |
@q **** (4) |scanner_node != 0|.@> |
140 |
@ |scanner_node != 0|. |
141 |
|
142 |
\LOG |
143 |
\initials{LDF 2004.09.30.} |
144 |
Added this section. |
145 |
|
146 |
\initials{LDF 2004.11.28.} |
147 |
Now calling |scanner_node->get_thread_name_and_stop_values()|. |
148 |
\ENDLOG |
149 |
|
150 |
@<Define scanning functions@>= |
151 |
|
152 |
#if DEBUG_COMPILE |
153 |
else if (DEBUG) /* |scanner_node != 0| */ |
154 |
{ |
155 |
cerr_strm << "In `yylex()':" |
156 |
<< "`scanner_node' != 0."; |
157 |
|
158 |
log_message(cerr_strm); |
159 |
cerr_message(cerr_strm); |
160 |
cerr_strm.str(""); |
161 |
|
162 |
} /* |else if (DEBUG)| (|scanner_node != 0|) */ |
163 |
|
164 |
#endif /* |DEBUG_COMPILE| */@; |
165 |
|
166 |
|
167 |
scanner_node->get_thread_name_and_stop_values(&thread_name, |
168 |
&error_stop_value, |
169 |
&warning_stop_value); |
170 |
|
171 |
const Run_State* run_state = scanner_node->get_run_state(); |
172 |
|
173 |
@q *** (3)@> |
174 |
|
175 |
#if DEBUG_COMPILE |
176 |
if (DEBUG) |
177 |
{ |
178 |
cerr_strm << thread_name << "Entering `yylex()'."; |
179 |
|
180 |
log_message(cerr_strm); |
181 |
cerr_message(cerr_strm); |
182 |
cerr_strm.str(""); |
183 |
} |
184 |
#endif |
185 |
|
186 |
|
187 |
@q *** (3).@> |
188 |
@ |
189 |
@<Define scanning functions@>= |
190 |
|
191 |
int curr_catcode = INVALID_CATCODE; |
192 |
int prev_catcode; |
193 |
int next_catcode; |
194 |
|
195 |
int rescan_catcode; |
196 |
void* rescan_value; |
197 |
bool rescan_retest; |
198 |
|
199 |
int status; |
200 |
|
201 |
|
202 |
yylex_start: |
203 |
|
204 |
|
205 |
@q *** (3) Rescan stack not empty.@> |
206 |
|
207 |
@ Rescan stack not empty. |
208 |
\initials{LDF 2004.09.09.} |
209 |
|
210 |
@<Define scanning functions@>= |
211 |
if (scanner_node->rescan_stack.size() > 0) |
212 |
{ |
213 |
|
214 |
#if DEBUG_COMPILE |
215 |
if (DEBUG) |
216 |
{ |
217 |
cerr_strm << thread_name |
218 |
<< "In `yylex()': " |
219 |
<< "`scanner_node->rescan_stack.size()' > 0."; |
220 |
|
221 |
log_message(cerr_strm); |
222 |
cerr_message(cerr_strm); |
223 |
cerr_strm.str(); |
224 |
} |
225 |
|
226 |
#endif /* |DEBUG_COMPILE| */@; |
227 |
|
228 |
rescan_catcode = scanner_node->rescan_stack.top().i; |
229 |
rescan_value = scanner_node->rescan_stack.top().v; |
230 |
rescan_retest = scanner_node->rescan_stack.top().b; |
231 |
scanner_node->rescan_stack.pop(); |
232 |
|
233 |
#if DEBUG_COMPILE |
234 |
if (DEBUG) |
235 |
{ |
236 |
cerr_strm << thread_name << "In `yylex()':" |
237 |
<< endl << "`rescan_catcode' == `" |
238 |
<< name_map[rescan_catcode] << "'." |
239 |
<< endl; |
240 |
|
241 |
if (rescan_value == 0) |
242 |
cerr_strm << "`rescan_value' == 0" << endl; |
243 |
else |
244 |
{ |
245 |
cerr_strm << "`rescan_value' != 0" << endl; |
246 |
} |
247 |
|
248 |
|
249 |
cerr_strm << "`rescan_retest' == " |
250 |
<< rescan_retest << "."; |
251 |
|
252 |
log_message(cerr_strm); |
253 |
cerr_message(cerr_strm); |
254 |
cerr_strm.str(); |
255 |
|
256 |
} |
257 |
#endif /* |DEBUG_COMPILE| */@; |
258 |
|
259 |
@q **** (4) |rescan_value != 0 || !rescan_retest|.@> |
260 |
|
261 |
@ |rescan_value != 0 || !rescan_retest|. |
262 |
\initials{LDF 2004.11.28.} |
263 |
|
264 |
@<Define scanning functions@>= |
265 |
|
266 |
if (rescan_value != 0 || !rescan_retest) |
267 |
{ |
268 |
|
269 |
value->pointer_value = static_cast<YYSTYPE*>(rescan_value); |
270 |
|
271 |
#if DEBUG_COMPILE |
272 |
if (DEBUG) |
273 |
{ |
274 |
cerr_strm << "In `yylex()': Returning `" |
275 |
<< name_map[rescan_catcode] |
276 |
<< "' immediately."; |
277 |
|
278 |
log_message(cerr_strm); |
279 |
cerr_message(cerr_strm); |
280 |
cerr_strm.str(); |
281 |
} |
282 |
#endif /* |DEBUG_COMPILE| */@; |
283 |
|
284 |
|
285 |
scanner_node->set_first_call_yylex(false); |
286 |
|
287 |
return rescan_catcode; |
288 |
|
289 |
} /* |if (rescan_value != 0 || !rescan_retest)| */@; |
290 |
|
291 |
@q **** (4) |rescan_value == 0 && rescan_retest|.@> |
292 |
|
293 |
@ |rescan_value == 0 && rescan_retest|. |
294 |
\initials{LDF 2004.11.28.} |
295 |
|
296 |
@<Define scanning functions@>= |
297 |
|
298 |
else /* |rescan_value == 0 && rescan_retest| */@; |
299 |
{ |
300 |
#if DEBUG_COMPILE |
301 |
if (DEBUG) |
302 |
{ |
303 |
|
304 |
cerr_strm << "In `yylex()': `rescan_value' == 0 and " |
305 |
<< "`rescan_retest' == " << rescan_retest |
306 |
<< "." << endl << "Will retest."; |
307 |
|
308 |
log_message(cerr_strm); |
309 |
cerr_message(cerr_strm); |
310 |
cerr_strm.str(""); |
311 |
} |
312 |
#endif /* |DEBUG_COMPILE| */@; |
313 |
|
314 |
curr_catcode = rescan_catcode; |
315 |
|
316 |
} /* |else| (|rescan_value == 0 && rescan_retest|) */@; |
317 |
|
318 |
@q **** (4) .@> |
319 |
|
320 |
} /* |if (scanner_node->rescan_stack.size() > 0)| */@; |
321 |
|
322 |
|
323 |
@q *** (3) Rescan stack is empty. Scan new token.@> |
324 |
|
325 |
@ Rescan stack is empty. Scan new token. |
326 |
\initials{LDF 2004.09.09.} |
327 |
|
328 |
@<Define scanning functions@>= |
329 |
|
330 |
else /* |scanner_node->rescan_stack.size() <= 0| */@; |
331 |
{ |
332 |
|
333 |
#if DEBUG_COMPILE |
334 |
if (DEBUG) |
335 |
{ |
336 |
cerr_strm << thread_name << "In `yylex()': " |
337 |
<< "`scanner_node->rescan_stack.size()' <= 0." |
338 |
<< endl |
339 |
<< "Calling `sub_yylex()' to get new token."; |
340 |
|
341 |
log_message(cerr_strm); |
342 |
cerr_message(cerr_strm); |
343 |
cerr_strm.str(); |
344 |
} |
345 |
#endif /* |DEBUG_COMPILE| */@; |
346 |
|
347 |
unsigned int null_ctr = 0; |
348 |
|
349 |
@q **** (4) |scanner_node->get_in_type() == Io_Struct::STDIN_TYPE|.@> |
350 |
@q **** (4) Reading from standard input. ``RETURNS'' @> |
351 |
@q **** (4) (actually ``NEWLINES'') must be handled specially. @> |
352 |
|
353 |
@ |scanner_node->get_in_type() == Io_Struct::STDIN_TYPE|. |
354 |
Reading from standard input. ``RETURNS'' |
355 |
(actually ``NEWLINES'') must be handled specially. |
356 |
\initials{LDF 2004.09.09.} |
357 |
|
358 |
\LOG |
359 |
\initials{LDF 2004.09.09.} |
360 |
Added this section. |
361 |
\ENDLOG |
362 |
|
363 |
@<Define scanning functions@>= |
364 |
|
365 |
if (scanner_node->get_in_type() == Io_Struct::STDIN_TYPE) |
366 |
|
367 |
{ |
368 |
|
369 |
prev_catcode = curr_catcode; |
370 |
|
371 |
if (scanner_node->get_first_call_yylex()) |
372 |
{ |
373 |
cerr_mutex.lock(); |
374 |
cerr << "* "; |
375 |
cerr_mutex.unlock(); |
376 |
} |
377 |
|
378 |
|
379 |
curr_catcode = sub_yylex(value, |
380 |
location, |
381 |
scanner_node); |
382 |
|
383 |
@q ***** (5).@> |
384 |
|
385 |
|
386 |
if ( prev_catcode == INVALID_CATCODE |
387 |
&& curr_catcode == NULL_VALUE) |
388 |
|
389 |
{ |
390 |
null_ctr++; |
391 |
|
392 |
cerr_mutex.lock(); |
393 |
|
394 |
if ( (scanner_node->get_first_call_yylex() && null_ctr >= 1) |
395 |
|| (!scanner_node->get_first_call_yylex() && null_ctr > 1)) |
396 |
cerr << "(Please type a command or say `end')" << endl; |
397 |
|
398 |
cerr << "* "; |
399 |
cerr_mutex.unlock(); |
400 |
prev_catcode = curr_catcode; |
401 |
curr_catcode = sub_yylex(value, |
402 |
location, |
403 |
scanner_node); |
404 |
|
405 |
@q ****** (6).@> |
406 |
|
407 |
while (prev_catcode == NULL_VALUE && curr_catcode == NULL_VALUE) |
408 |
{ |
409 |
|
410 |
null_ctr++; |
411 |
cerr_mutex.lock(); |
412 |
cerr << "(Please type a command or say `end')" << endl; |
413 |
cerr << "* "; |
414 |
cerr_mutex.unlock(); |
415 |
|
416 |
prev_catcode = curr_catcode; |
417 |
curr_catcode = sub_yylex(value, |
418 |
location, |
419 |
scanner_node); |
420 |
|
421 |
|
422 |
} /* |while| */ |
423 |
|
424 |
|
425 |
@q ****** (6).@> |
426 |
|
427 |
} /* |if| */ |
428 |
|
429 |
@q ***** (5) .@> |
430 |
|
431 |
} /* if (scanner_node->get_in_type() == Io_Struct::STDIN_TYPE) */ |
432 |
|
433 |
|
434 |
@q **** (4) |!(scanner_node->get_in_type() == Io_Struct::STDIN_TYPE)|.@> |
435 |
@q **** (4) Not reading from standard input.@> |
436 |
|
437 |
@ |!(scanner_node->get_in_type() == Io_Struct::STDIN_TYPE)|. |
438 |
Not reading from standard input. |
439 |
\initials{LDF 2004.11.28.} |
440 |
|
441 |
@<Define scanning functions@>= |
442 |
|
443 |
else /* |!(scanner_node->get_in_type() == Io_Struct::STDIN_TYPE)| */ |
444 |
{ |
445 |
prev_catcode = curr_catcode; |
446 |
curr_catcode = sub_yylex(value, |
447 |
location, |
448 |
scanner_node); |
449 |
|
450 |
|
451 |
} /* |else| (|!(scanner_node->get_in_type() == Io_Struct::STDIN_TYPE)|) */ |
452 |
|
453 |
|
454 |
@q **** (4)@> |
455 |
|
456 |
} /* |else| (|scanner_node->rescan_stack.size() <= 0|) */@; |
457 |
|
458 |
|
459 |
|
460 |
@q *** (3) TERMINATE. @> |
461 |
@*2 \.{TERMINATE}. |
462 |
|
463 |
\LOG |
464 |
\initials{LDF 2004.09.20.} |
465 |
Added code to this section for popping |scanner_node->in| if |
466 |
|scanner_node->in->up != 0|. |
467 |
\ENDLOG |
468 |
|
469 |
@<Define scanning functions@>= |
470 |
|
471 |
if (curr_catcode == TERMINATE) |
472 |
{ |
473 |
#if DEBUG_COMPILE |
474 |
if (DEBUG) |
475 |
{ |
476 |
cerr_strm << "In `yylex()': `sub_yylex()' returned TERMINATE."; |
477 |
|
478 |
log_message(cerr_strm); |
479 |
cerr_message(cerr_strm); |
480 |
cerr_strm.str(""); |
481 |
} |
482 |
#endif /* |DEBUG_COMPILE| */@; |
483 |
|
484 |
scanner_node->set_first_call_yylex(false); |
485 |
|
486 |
status = scanner_node->pop_in(); |
487 |
|
488 |
@q **** (4) |status == 0|.@> |
489 |
|
490 |
@ |status == 0|. |
491 |
\initials{LDF 2004.11.28.} |
492 |
|
493 |
@<Define scanning functions@>= |
494 |
|
495 |
if (status == 0) |
496 |
{ |
497 |
|
498 |
#if DEBUG_COMPILE |
499 |
if (DEBUG) |
500 |
{ |
501 |
cerr_strm << thread_name << "In `yylex()':" |
502 |
<< endl |
503 |
<< "`scanner_node->pop_in()' succeeded."; |
504 |
|
505 |
log_message(cerr_strm); |
506 |
cerr_message(cerr_strm); |
507 |
cerr_strm.str(""); |
508 |
} |
509 |
#endif /* |DEBUG_COMPILE| */@; |
510 |
|
511 |
@q **** (4) Single-threaded input and inclusion. Return |SEMI_COLON| @> |
512 |
@q **** (4) and continue reading from standard input when @> |
513 |
@q **** (4) this function is called again. @> |
514 |
|
515 |
@ Single-threaded input and inclusion. Return |SEMI_COLON| and |
516 |
continue reading from standard input when this function is called |
517 |
again. |
518 |
\initials{LDF 2004.09.30.} |
519 |
|
520 |
\LOG |
521 |
\initials{LDF 2004.09.30.} |
522 |
Added this section. |
523 |
\ENDLOG |
524 |
|
525 |
\TODO |
526 |
@q { @> |
527 |
@:TO DO}{{\bf TO DO}@> |
528 |
@q } @> |
529 |
@q !! TO DO:@> |
530 |
\initials{LDF 2004.09.30.} |
531 |
Add |endinput|. |
532 |
\ENDTODO |
533 |
|
534 |
@:??@> ?? \initials{LDF 2004.11.28.} I've added |endinput|. |
535 |
Do I need to change anything here? |
536 |
|
537 |
@<Define scanning functions@>= |
538 |
|
539 |
if ( scanner_node->get_in_type() == Io_Struct::STDIN_TYPE |
540 |
&& !( run_state->multithread_input |
541 |
|| run_state->multithread_include)) |
542 |
|
543 |
{ |
544 |
scanner_node->set_first_call_yylex(true); |
545 |
return SEMI_COLON; |
546 |
} |
547 |
|
548 |
|
549 |
|
550 |
goto yylex_start; |
551 |
|
552 |
@q **** (4) @> |
553 |
|
554 |
} /* |if (status == 0)| */ |
555 |
|
556 |
@q *** (3).@> |
557 |
@ |
558 |
@<Define scanning functions@>= |
559 |
|
560 |
|
561 |
else /* |status != 0| */ |
562 |
{ |
563 |
|
564 |
#if DEBUG_COMPILE |
565 |
if (DEBUG) |
566 |
{ |
567 |
cerr_strm << thread_name << "In `yylex()':" |
568 |
<< endl |
569 |
<< "`scanner_node->pop_in()' failed."; |
570 |
|
571 |
log_message(cerr_strm); |
572 |
cerr_message(cerr_strm); |
573 |
cerr_strm.str(""); |
574 |
} |
575 |
#endif /* |DEBUG_COMPILE| */@; |
576 |
|
577 |
|
578 |
@q **** (4) | run_state->multithread_input @> |
579 |
@q **** (4) || run_state->multithread_include|.@> |
580 |
@q **** (4) Issue a warning and return |END|. @> |
581 |
|
582 |
@ |run_state->multithread_input || run_state->multithread_include|. |
583 |
Issue a warning and return |END|. |
584 |
\initials{LDF 2004.09.30.} |
585 |
|
586 |
\LOG |
587 |
\initials{LDF 2004.09.30.} |
588 |
Added this section. |
589 |
\ENDLOG |
590 |
|
591 |
@<Define scanning functions@>= |
592 |
|
593 |
if ( run_state->multithread_input |
594 |
|| run_state->multithread_include) |
595 |
|
596 |
|
597 |
{ |
598 |
|
599 |
cerr_strm << thread_name << "WARNING! In `yylex()':" |
600 |
<< endl |
601 |
<< "End-of-file found and multithreaded input and/or " |
602 |
<< "multithreaded inclusion is enabled." |
603 |
<< endl << "In these cases, input files should contain " |
604 |
<< "an `end' or `endinput' command." |
605 |
<< endl << "I'll pretend this one does and continue."; |
606 |
|
607 |
|
608 |
log_message(cerr_strm); |
609 |
cerr_message(cerr_strm); |
610 |
cerr_strm.str(""); |
611 |
|
612 |
return END; |
613 |
|
614 |
|
615 |
} /* |if ( run_state->multithread_input |
616 |
|| run_state->multithread_include)| */ |
617 |
|
618 |
|
619 |
|
620 |
@q **** (4) Error handling: |!( run_state->multithread_input @> |
621 |
@q **** (4) || run_state->multithread_include)|.@> |
622 |
@q **** (4) Signal an error and return |END|. @> |
623 |
|
624 |
@ |!(run_state->multithread_input || run_state->multithread_include)|. |
625 |
Signal an error and return |END|. It may be possible to continue. |
626 |
\initials{LDF 2004.09.30.} |
627 |
|
628 |
\LOG |
629 |
\initials{LDF 2004.09.30.} |
630 |
Added this section. |
631 |
|
632 |
\initials{LDF 2004.09.30.} |
633 |
Now returning |END| rather than |TERMINATE|. |
634 |
\ENDLOG |
635 |
|
636 |
@<Define scanning functions@>= |
637 |
|
638 |
else /* |!( run_state->multithread_input |
639 |
|| run_state->multithread_include)| */ |
640 |
|
641 |
{ |
642 |
|
643 |
cerr_strm << thread_name << "ERROR! In `yylex()':" |
644 |
<< endl |
645 |
<< "End-of-file found when using single-threaded input " |
646 |
<< "and single-threaded inclusion and " |
647 |
<< "`scanner_node->pop_in()' failed." |
648 |
<< endl << "This should never happen. " |
649 |
<< endl << "Exiting function with return value `END' " |
650 |
<< "and will try to continue."; |
651 |
|
652 |
log_message(cerr_strm); |
653 |
cerr_message(cerr_strm); |
654 |
cerr_strm.str(""); |
655 |
|
656 |
return END; |
657 |
|
658 |
} /* |else| (|!( run_state->multithread_input |
659 |
|| run_state->multithread_include)|) */ |
660 |
|
661 |
@q **** (4).@> |
662 |
|
663 |
} /* |else| (|status != 0|) */ |
664 |
|
665 |
@q *** (3).@> |
666 |
|
667 |
} /* |if (curr_catcode == TERMINATE)| */ |
668 |
|
669 |
|
670 |
@q ** (2) Handle special assignments.@> |
671 |
@*1 Handle special assignments. |
672 |
\initials{LDF 2004.08.26.} |
673 |
|
674 |
\LOG |
675 |
\initials{LDF 2004.08.26.} |
676 |
Added this section. |
677 |
\ENDLOG |
678 |
|
679 |
@<Define scanning functions@>= |
680 |
|
681 |
else if ( curr_catcode == PLUS_ASSIGN |
682 |
|| curr_catcode == MINUS_ASSIGN |
683 |
|| curr_catcode == TIMES_ASSIGN |
684 |
|| curr_catcode == DIVIDE_ASSIGN) /* Special assignment. */ |
685 |
{ |
686 |
#if DEBUG_COMPILE |
687 |
if (DEBUG) |
688 |
{ |
689 |
cerr_strm << "In `yylex()': Special assignment." |
690 |
<< endl << "Returning `curr_catcode' == " |
691 |
<< name_map[curr_catcode] << "."; |
692 |
|
693 |
log_message(cerr_strm); |
694 |
cerr_message(cerr_strm); |
695 |
cerr_strm.str(""); |
696 |
} |
697 |
#endif /* |DEBUG_COMPILE| */@; |
698 |
|
699 |
|
700 |
scanner_node->set_first_call_yylex(false); |
701 |
|
702 |
return curr_catcode; |
703 |
|
704 |
} /* |else if| (Special assignment). */ |
705 |
|
706 |
@q ** (2) Handle sparks. @> |
707 |
@ Handle sparks. |
708 |
|
709 |
@<Define scanning functions@>= |
710 |
else if (curr_catcode >= SYMBOL_0 && curr_catcode <= SYMBOL_7) |
711 |
{ |
712 |
#if DEBUG_COMPILE |
713 |
if (DEBUG) |
714 |
{ |
715 |
cerr_strm << "In `yylex()': `curr_catcode' == `" |
716 |
<< name_map[curr_catcode] << "'" << endl |
717 |
<< "`value->string_value' == \"" |
718 |
<< value->string_value << "\"."; |
719 |
|
720 |
log_message(cerr_strm); |
721 |
cerr_message(cerr_strm); |
722 |
cerr_strm.str(""); |
723 |
} |
724 |
#endif |
725 |
|
726 |
|
727 |
@q *** (3) Call |scanner_node->lookup()|.@> |
728 |
|
729 |
@ Call |scanner_node->lookup()|. |
730 |
\initials{LDF 2004.08.25.} |
731 |
|
732 |
@<Define scanning functions@>= |
733 |
|
734 |
Id_Map_Entry_Node entry = scanner_node->lookup(value->string_value); |
735 |
|
736 |
|
737 |
@q *** (3) |lookup()| failed.@> |
738 |
|
739 |
@ |lookup()| failed. |
740 |
\initials{LDF 2004.04.22.} |
741 |
|
742 |
@<Define scanning functions@>= |
743 |
|
744 |
if (entry == 0) |
745 |
{ |
746 |
#if DEBUG_COMPILE |
747 |
if (DEBUG) |
748 |
{ |
749 |
cerr_strm << thread_name |
750 |
<< "In `yylex()': \"" |
751 |
<< value->string_value << "\" is not in `id_map'."; |
752 |
|
753 |
log_message(cerr_strm); |
754 |
cerr_message(cerr_strm); |
755 |
cerr_strm.str(); |
756 |
} |
757 |
#endif |
758 |
|
759 |
} /* |if (entry == 0)| */ |
760 |
|
761 |
@q *** (3) |lookup()| succeeded. @> |
762 |
@ |lookup()| succeeded. |
763 |
\initials{LDF 2004.04.22.} |
764 |
|
765 |
\LOG |
766 |
\initials{LDF 2004.11.12.} |
767 |
Now checking for |!entry->is_true_internal()|. |
768 |
\ENDLOG |
769 |
|
770 |
@<Define scanning functions@>= |
771 |
else /* |entry != 0| */ |
772 |
{ |
773 |
|
774 |
#if DEBUG_COMPILE |
775 |
if (DEBUG) |
776 |
{ |
777 |
cerr_strm << thread_name |
778 |
<< "In `yylex()': `lookup(" << value->string_value |
779 |
<< ")' succeeded." << endl |
780 |
<< "`type' == `" << name_map[entry->get_type()] << "'."; |
781 |
|
782 |
|
783 |
if (entry->is_spark()) |
784 |
{ |
785 |
cerr << value->string_value << " is a spark. Will return " |
786 |
<< name_map[entry->get_type()] |
787 |
<< endl << flush; |
788 |
} |
789 |
|
790 |
else if (entry->is_internal()) |
791 |
{ |
792 |
cerr << value->string_value << " is an internal quantity. " |
793 |
<< "Will return " |
794 |
<< name_map[curr_catcode] |
795 |
<< endl; |
796 |
} |
797 |
|
798 |
else if (entry->is_regular()) |
799 |
{ |
800 |
cerr << value->string_value << " is regular symbolic token. " |
801 |
<< "Will return " << name_map[curr_catcode] |
802 |
<< endl; |
803 |
} |
804 |
|
805 |
log_message(cerr_strm); |
806 |
cerr_message(cerr_strm); |
807 |
cerr_strm.str(); |
808 |
|
809 |
} /* |if (DEBUG)| */ |
810 |
|
811 |
#endif /* |DEBUG_COMPILE| */@; |
812 |
|
813 |
|
814 |
if ( !entry->is_spark() && !entry->is_internal() |
815 |
&& !entry->is_true_internal() |
816 |
&& !entry->is_regular()) |
817 |
{ |
818 |
cerr_strm << thread_name << "ERROR! In `yylex()':" |
819 |
<< endl |
820 |
<< value->string_value << " has an invalid category." |
821 |
<< "This shouldn't be possible. " |
822 |
<< "Will return " << name_map[curr_catcode] |
823 |
<< " and try to continue." |
824 |
<< endl; |
825 |
|
826 |
log_message(cerr_strm); |
827 |
cerr_message(cerr_strm); |
828 |
cerr_strm.str(); |
829 |
|
830 |
} /* Invalid category. */ |
831 |
|
832 |
if (entry->is_spark()) |
833 |
{ |
834 |
#if DEBUG_COMPILE |
835 |
if (DEBUG) |
836 |
{ |
837 |
cerr_strm << thread_name << "Spark `" |
838 |
<< value->string_value |
839 |
<< "'." << "Returning `" |
840 |
<< name_map[entry->get_type()] |
841 |
<< "'."; |
842 |
|
843 |
log_message(cerr_strm); |
844 |
cerr_message(cerr_strm); |
845 |
cerr_strm.str(); |
846 |
} |
847 |
#endif /* |DEBUG_COMPILE| */@; |
848 |
|
849 |
scanner_node->set_first_call_yylex(false); |
850 |
|
851 |
return entry->get_type(); |
852 |
|
853 |
} /* spark */ |
854 |
|
855 |
} /* |else| (|entry != 0|) */ |
856 |
|
857 |
@q *** (3) End of spark and existing variable handling.@> |
858 |
|
859 |
@ End of spark and existing variable handling. |
860 |
|
861 |
@<Define scanning functions@>= |
862 |
|
863 |
} /* |else if (curr_catcode >= SYMBOL_0 && curr_catcode <= SYMBOL_7)| */ |
864 |
|
865 |
@q ** (2) Return. @> |
866 |
@ Return. |
867 |
|
868 |
@<Define scanning functions@>= |
869 |
|
870 |
#if DEBUG_COMPILE |
871 |
if (DEBUG) |
872 |
{ |
873 |
cerr_strm << thread_name |
874 |
<< "Exiting `yylex()' with return value `" |
875 |
<< name_map[curr_catcode] << "'."; |
876 |
|
877 |
log_message(cerr_strm); |
878 |
cerr_message(cerr_strm); |
879 |
cerr_strm.str(); |
880 |
} |
881 |
#endif /* |DEBUG_COMPILE| */@; |
882 |
|
883 |
scanner_node->set_first_call_yylex(false); |
884 |
|
885 |
return curr_catcode; |
886 |
|
887 |
} /* End of |yylex()| definition. */ |
888 |
|
889 |
@q * (1) sub_yylex() @> |
890 |
@* {\bf sub\_yylex()}. |
891 |
\initials{LDF Undated.} |
892 |
|
893 |
\LOG |
894 |
\initials{LDF 2004.09.12.} |
895 |
Changed |string curr_token| to |string curr_token_string|. Now |
896 |
setting |scanner_node->token_string| to |curr_token_string| before |
897 |
returning. |
898 |
|
899 |
\initials{LDF 2004.10.28.} |
900 |
@:BUG FIX@> BUG FIX: Added code for setting |
901 |
|scanner_node->token_string|. This is used in the parser rules |
902 |
\§for-loop> $\longrightarrow$ |
903 |
\.{FOR} \§symbolic token> \§equate or assign> \§numeric expression> |
904 |
\.{STEP} \§numeric expression> \.{UNTIL} \§numeric expression> \.{COLON}. |
905 |
% |
906 |
and |
907 |
% |
908 |
\§for-loop> $\longrightarrow$ |
909 |
\.{FOREVER} \.{COLON} |
910 |
% |
911 |
in \filename{ploops.w}. |
912 |
ENDLOG |
913 |
|
914 |
\TODO |
915 |
@q { @> |
916 |
@:TO DO}{{\bf TO DO}@> |
917 |
@q } @> |
918 |
@q !! TO DO: @> |
919 |
\initials{LDF 2004.04.03.} |
920 |
Must debug locations. Look up `seek' function and type that it |
921 |
returns. Use it in addition to line and column numbers. |
922 |
|
923 |
\initials{LDF 2004.09.13.} |
924 |
``\<RETURN>'' characters typed in by the user in response to debugging |
925 |
output can cause input characters to be overwritten. Work on a |
926 |
solution to this problem, perhaps by reading the input characters into |
927 |
a buffer. |
928 |
|
929 |
\initials{LDF 2004.11.29.} |
930 |
Made debugging and error output thread-safe. |
931 |
Formatting changes. |
932 |
\ENDTODO |
933 |
|
934 |
@q ** (2) Declaration. @> |
935 |
|
936 |
@<Declare scanning functions@>= |
937 |
int |
938 |
sub_yylex(YYSTYPE *value, |
939 |
YYLTYPE *location, |
940 |
Scanner_Node scanner_node); |
941 |
|
942 |
@q ** (2) Definition. @> |
943 |
|
944 |
@ |
945 |
@<Define scanning functions@>= |
946 |
|
947 |
int |
948 |
sub_yylex(YYSTYPE *value, |
949 |
YYLTYPE *location, |
950 |
Scanner_Node scanner_node) |
951 |
{ |
952 |
|
953 |
|
954 |
@q *** (3) Preliminaries.@> |
955 |
@ Preliminaries. |
956 |
|
957 |
\LOG |
958 |
\initials{LDF 2004.11.28.} |
959 |
Added this section. |
960 |
\ENDLOG |
961 |
|
962 |
@<Define scanning functions@>= |
963 |
|
964 |
using namespace Scan_Parse; |
965 |
|
966 |
stringstream cerr_strm; |
967 |
|
968 |
#if DEBUG_COMPILE |
969 |
bool DEBUG = false; /* |true| */@; |
970 |
if (DEBUG) |
971 |
{ |
972 |
cerr_strm << "Entering `sub_yylex()'."; |
973 |
|
974 |
log_message(cerr_strm); |
975 |
cerr_message(cerr_strm); |
976 |
cerr_strm.str(""); |
977 |
} /* |if (DEBUG)| */ |
978 |
|
979 |
#endif /* |DEBUG_COMPILE| */@; |
980 |
|
981 |
bool error_stop_value = true; |
982 |
bool warning_stop_value = true; |
983 |
string thread_name = ""; |
984 |
|
985 |
@q **** (4) Error handling: |scanner_node == 0|.@> |
986 |
|
987 |
@ Error handling: |scanner_node == 0|. Signal an error and return |
988 |
|TERMINATE|. |
989 |
\initials{LDF 2004.11.28.} |
990 |
|
991 |
\LOG |
992 |
\initials{LDF 2004.11.28.} |
993 |
Added this section. |
994 |
\ENDLOG |
995 |
|
996 |
@<Define scanning functions@>= |
997 |
|
998 |
if (scanner_node == 0) |
999 |
{ |
1000 |
|
1001 |
cerr_strm << "ERROR! In `sub_yylex()':" |
1002 |
<< "`scanner_node' == 0." |
1003 |
<< endl << "Can't continue. Exiting function " |
1004 |
<< "with return value `TERMINATE'."; |
1005 |
|
1006 |
log_message(cerr_strm); |
1007 |
cerr_message(cerr_strm); |
1008 |
cerr_strm.str(""); |
1009 |
|
1010 |
return TERMINATE; |
1011 |
|
1012 |
} /* |if (scanner_node == 0)| */ |
1013 |
|
1014 |
|
1015 |
@q **** (4) |scanner_node != 0|.@> |
1016 |
@ |scanner_node != 0|. |
1017 |
|
1018 |
\LOG |
1019 |
\initials{LDF 2004.11.28.} |
1020 |
Added this section. |
1021 |
\ENDLOG |
1022 |
|
1023 |
@<Define scanning functions@>= |
1024 |
|
1025 |
#if DEBUG_COMPILE |
1026 |
else if (DEBUG) /* |scanner_node != 0| */ |
1027 |
{ |
1028 |
cerr_strm << "In `sub_yylex()':" |
1029 |
<< "`scanner_node' != 0."; |
1030 |
|
1031 |
log_message(cerr_strm); |
1032 |
cerr_message(cerr_strm); |
1033 |
cerr_strm.str(""); |
1034 |
|
1035 |
} /* |else if (DEBUG)| (|scanner_node != 0|) */ |
1036 |
|
1037 |
#endif /* |DEBUG_COMPILE| */@; |
1038 |
|
1039 |
scanner_node->get_thread_name_and_stop_values(&thread_name, |
1040 |
&error_stop_value, |
1041 |
&warning_stop_value); |
1042 |
@q *** (3) Check that input stream is open.@> |
1043 |
@ Check that input stream is open. |
1044 |
\initials{LDF 2004.08.26.} |
1045 |
|
1046 |
@<Define scanning functions@>= |
1047 |
|
1048 |
if (!scanner_node->is_open_in()) |
1049 |
{ |
1050 |
|
1051 |
cerr_strm << "ERROR! in `sub_yylex()': \"" |
1052 |
<< scanner_node->get_in_filename() |
1053 |
<< "\" isn't open. " |
1054 |
<< "Returning `TERMINATE'."; |
1055 |
|
1056 |
log_message(cerr_strm); |
1057 |
cerr_message(cerr_strm); |
1058 |
cerr_strm.str(""); |
1059 |
|
1060 |
return TERMINATE; |
1061 |
|
1062 |
} /* |if (!scanner_node->is_open_in())| */ |
1063 |
|
1064 |
|
1065 |
@q **** (4).@> |
1066 |
@ |
1067 |
@<Define scanning functions@>= |
1068 |
|
1069 |
unsigned int curr_position; |
1070 |
unsigned int start_line; |
1071 |
unsigned int curr_line; |
1072 |
unsigned int start_column; |
1073 |
unsigned int curr_column; |
1074 |
|
1075 |
char prev_char; |
1076 |
char curr_char = EOF; |
1077 |
char next_char = EOF; |
1078 |
|
1079 |
string curr_token_string = ""; |
1080 |
unsigned int curr_catcode; |
1081 |
unsigned int temp_catcode; |
1082 |
|
1083 |
scanner_node->set_token_string(""); |
1084 |
|
1085 |
@q *** (3) Start loop.@> |
1086 |
|
1087 |
@ Start loop. |
1088 |
\initials{LDF 2004.08.26.} |
1089 |
|
1090 |
@<Define scanning functions@>= |
1091 |
|
1092 |
loop_start: |
1093 |
|
1094 |
curr_position = location->position; |
1095 |
start_line = location->last_line; |
1096 |
curr_line = start_line; |
1097 |
start_column = location->last_column; |
1098 |
curr_column = start_column; |
1099 |
|
1100 |
|
1101 |
for (bool first_time = true;;) |
1102 |
{ |
1103 |
prev_char = curr_char; |
1104 |
curr_char = scanner_node->peek(); |
1105 |
|
1106 |
#if DEBUG_COMPILE |
1107 |
if (DEBUG) |
1108 |
{ |
1109 |
cerr_strm << "In `sub_yylex()':" << endl |
1110 |
<< "`curr_char' == `" << curr_char << "'."; |
1111 |
|
1112 |
log_message(cerr_strm); |
1113 |
cerr_message(cerr_strm); |
1114 |
cerr_strm.str(""); |
1115 |
|
1116 |
} |
1117 |
#endif /* |DEBUG_COMPILE| */@; |
1118 |
|
1119 |
|
1120 |
|
1121 |
@q ***** (5) Handle ``RETURNS'' (actually ``NEWLINES'') when reading @> |
1122 |
@q ***** (5) from standard input. @> |
1123 |
|
1124 |
@ Handle ``RETURNS'' (actually ``NEWLINES'') |
1125 |
when reading from standard input. |
1126 |
\initials{LDF 2004.09.09.} |
1127 |
|
1128 |
\LOG |
1129 |
\initials{LDF 2004.09.09.} |
1130 |
Added this section. |
1131 |
\ENDLOG |
1132 |
|
1133 |
@<Define scanning functions@>= |
1134 |
|
1135 |
if ( scanner_node->get_in_type() == Io_Struct::STDIN_TYPE |
1136 |
&& prev_char == EOF && curr_char == '\n') |
1137 |
{ |
1138 |
|
1139 |
scanner_node->ignore(); |
1140 |
++curr_position; |
1141 |
curr_column = 0; |
1142 |
scanner_node->set_token_string(curr_token_string); |
1143 |
return NULL_VALUE; |
1144 |
} |
1145 |
|
1146 |
|
1147 |
|
1148 |
@q ***** (5) |curr_char == EOF|.@> |
1149 |
@ |curr_char == EOF|. |
1150 |
@<Define scanning functions@>= |
1151 |
|
1152 |
|
1153 |
if (curr_char == EOF) |
1154 |
{ |
1155 |
@q ****** (6) |first_time == true|.@> |
1156 |
|
1157 |
@ |first_time == true|. |
1158 |
\initials{LDF 2004.11.28.} |
1159 |
|
1160 |
@<Define scanning functions@>= |
1161 |
|
1162 |
if (first_time) |
1163 |
{ |
1164 |
#if DEBUG_COMPILE |
1165 |
if (DEBUG) |
1166 |
{ |
1167 |
cerr_strm << "In `sub_yylex()': End of file. " |
1168 |
<< "Returning " |
1169 |
<< name_map[TERMINATE] << "."; |
1170 |
|
1171 |
log_message(cerr_strm); |
1172 |
cerr_message(cerr_strm); |
1173 |
cerr_strm.str(""); |
1174 |
} |
1175 |
#endif /* |DEBUG_COMPILE| */@; |
1176 |
|
1177 |
scanner_node->set_token_string(curr_token_string); |
1178 |
return TERMINATE; |
1179 |
|
1180 |
} /* |if (first_time)| */ |
1181 |
|
1182 |
@q ****** (6) |first_time == false|.@> |
1183 |
|
1184 |
@ |first_time == false|. |
1185 |
\initials{LDF 2004.11.28.} |
1186 |
|
1187 |
@<Define scanning functions@>= |
1188 |
|
1189 |
else /* (|!first_time|) */ |
1190 |
{ |
1191 |
|
1192 |
#if DEBUG_COMPILE |
1193 |
if (DEBUG) |
1194 |
{ |
1195 |
cerr_strm << "In `sub_yylex()': Going to `finish'."; |
1196 |
|
1197 |
log_message(cerr_strm); |
1198 |
cerr_message(cerr_strm); |
1199 |
cerr_strm.str(""); |
1200 |
} |
1201 |
#endif /* |DEBUG_COMPILE| */@; |
1202 |
|
1203 |
goto finish; |
1204 |
|
1205 |
} /* |else| (|!first_time|) */ |
1206 |
|
1207 |
@q ****** (6).@> |
1208 |
|
1209 |
} /* |if (curr_char == EOF)| */ |
1210 |
|
1211 |
@q ***** (5) Get |catcode|.@> |
1212 |
|
1213 |
@ Get |catcode|. |
1214 |
\initials{LDF 2004.08.26.} |
1215 |
|
1216 |
@<Define scanning functions@>= |
1217 |
|
1218 |
#if DEBUG_COMPILE |
1219 |
if (DEBUG) |
1220 |
{ |
1221 |
cerr_strm << "In `sub_yylex()': `curr_char' == `" |
1222 |
<< curr_char << "'."; |
1223 |
|
1224 |
log_message(cerr_strm); |
1225 |
cerr_message(cerr_strm); |
1226 |
cerr_strm.str(""); |
1227 |
} |
1228 |
#endif /* |DEBUG_COMPILE| */@; |
1229 |
|
1230 |
temp_catcode = get_catcode(curr_char); |
1231 |
|
1232 |
|
1233 |
#if DEBUG_COMPILE |
1234 |
if (DEBUG) |
1235 |
{ |
1236 |
cerr_strm << "In `sub_yylex()': `temp_catcode' == `" |
1237 |
<< name_map[temp_catcode] << "'."; |
1238 |
|
1239 |
log_message(cerr_strm); |
1240 |
cerr_message(cerr_strm); |
1241 |
cerr_strm.str(""); |
1242 |
} |
1243 |
#endif /* |DEBUG_COMPILE| */@; |
1244 |
|
1245 |
@q ***** (5) |temp_catcode == INVALID_CATCODE|.@> |
1246 |
|
1247 |
@ |temp_catcode == INVALID_CATCODE|. |
1248 |
\initials{LDF 2004.11.28.} |
1249 |
|
1250 |
@<Define scanning functions@>= |
1251 |
|
1252 |
if (temp_catcode == INVALID_CATCODE) |
1253 |
{ |
1254 |
cerr_strm << "ERROR! In sub_yylex():" |
1255 |
<< endl |
1256 |
<< curr_char << " has invalid catcode." |
1257 |
<< endl << "Returning `" << name_map[INVALID_CATCODE] |
1258 |
<< "'."; |
1259 |
|
1260 |
log_message(cerr_strm); |
1261 |
cerr_message(cerr_strm); |
1262 |
cerr_strm.str(""); |
1263 |
|
1264 |
++curr_position; |
1265 |
|
1266 |
if (curr_char == '\n') |
1267 |
{ |
1268 |
++curr_line; |
1269 |
curr_column = 0; |
1270 |
} |
1271 |
else |
1272 |
++curr_column; |
1273 |
|
1274 |
location->first_line = start_line; |
1275 |
location->first_column = start_column; |
1276 |
location->last_line = curr_line; |
1277 |
location->last_column = curr_column; |
1278 |
location->position = curr_position; |
1279 |
|
1280 |
|
1281 |
strcpy(value->string_value, "INVALID"); |
1282 |
|
1283 |
scanner_node->set_token_string(curr_token_string); |
1284 |
|
1285 |
return INVALID_CATCODE; |
1286 |
|
1287 |
} // |if (temp_catcode == INVALID_CATCODE)| |
1288 |
|
1289 |
@q ***** (5) First character in token string.@> |
1290 |
|
1291 |
@ First character in token string. |
1292 |
\initials{LDF 2004.08.26.} |
1293 |
|
1294 |
@<Define scanning functions@>= |
1295 |
|
1296 |
if (first_time) |
1297 |
{ |
1298 |
|
1299 |
first_time = false; |
1300 |
|
1301 |
|
1302 |
@q ****** (6) Handle possible special assignments @> |
1303 |
@q ****** (6) and Pythagorean addition and subtraction.@> |
1304 |
|
1305 |
@ Handle possible special assignments, |
1306 |
and Pythagorean addition and subtraction. |
1307 |
\initials{LDF 2004.08.26.} |
1308 |
|
1309 |
\LOG |
1310 |
\initials{LDF 2004.08.26.} |
1311 |
Added this section. It seems to work. |
1312 |
|
1313 |
\initials{LDF 2004.08.29.} |
1314 |
Added code for handling Pythagorean addition and subtraction. |
1315 |
\ENDLOG |
1316 |
|
1317 |
|
1318 |
@<Define scanning functions@>= |
1319 |
|
1320 |
if ( curr_char == '+' |
1321 |
|| curr_char == '-' |
1322 |
|| curr_char == '*' |
1323 |
|| curr_char == '/') |
1324 |
|
1325 |
{ |
1326 |
|
1327 |
#if DEBUG_COMPILE |
1328 |
if (DEBUG) |
1329 |
{ |
1330 |
cerr_strm << thread_name |
1331 |
<< "In `sub_yylex()': Possible special assignment " |
1332 |
<< "or Pythagorean addition or subtraction " |
1333 |
<< "(first char)."; |
1334 |
|
1335 |
log_message(cerr_strm); |
1336 |
cerr_message(cerr_strm); |
1337 |
cerr_strm.str(""); |
1338 |
} |
1339 |
#endif /* |DEBUG_COMPILE| */@; |
1340 |
|
1341 |
scanner_node->ignore(); |
1342 |
++curr_position; |
1343 |
++curr_column; |
1344 |
|
1345 |
next_char = scanner_node->peek(); |
1346 |
|
1347 |
@q ******* (7) Pythagorean addition.@> |
1348 |
@ Pythagorean addition. |
1349 |
|
1350 |
\LOG |
1351 |
\initials{LDF 2004.08.29.} |
1352 |
Added this section. |
1353 |
\ENDLOG |
1354 |
|
1355 |
@<Define scanning functions@>= |
1356 |
|
1357 |
if (curr_char == '+' && next_char == '+') |
1358 |
{ |
1359 |
|
1360 |
scanner_node->ignore(); |
1361 |
++curr_position; |
1362 |
++curr_column; |
1363 |
|
1364 |
#if DEBUG_COMPILE |
1365 |
if (DEBUG) |
1366 |
{ |
1367 |
cerr_strm << "In `sub_yylex()': Returning " |
1368 |
<< name_map[PYTHAGOREAN_PLUS] << "."; |
1369 |
|
1370 |
log_message(cerr_strm); |
1371 |
cerr_message(cerr_strm); |
1372 |
cerr_strm.str(""); |
1373 |
|
1374 |
} |
1375 |
#endif /* |DEBUG_COMPILE| */@; |
1376 |
|
1377 |
scanner_node->set_token_string(curr_token_string); |
1378 |
return PYTHAGOREAN_PLUS; |
1379 |
|
1380 |
} /* |if (curr_char == '+' && next_char == '+')| */ |
1381 |
|
1382 |
@q ******* (7) Pythagorean subtraction.@> |
1383 |
@ Pythagorean subtraction. |
1384 |
|
1385 |
\LOG |
1386 |
\initials{LDF 2004.08.29.} |
1387 |
Added this section. |
1388 |
\ENDLOG |
1389 |
|
1390 |
@<Define scanning functions@>= |
1391 |
|
1392 |
if (curr_char == '+' && next_char == '-') |
1393 |
{ |
1394 |
|
1395 |
scanner_node->ignore(); |
1396 |
++curr_position; |
1397 |
++curr_column; |
1398 |
|
1399 |
next_char = scanner_node->peek(); |
1400 |
|
1401 |
@q ******** (8).@> |
1402 |
|
1403 |
if (next_char == '+') |
1404 |
{ |
1405 |
|
1406 |
scanner_node->ignore(); |
1407 |
++curr_position; |
1408 |
++curr_column; |
1409 |
|
1410 |
|
1411 |
#if DEBUG_COMPILE |
1412 |
if (DEBUG) |
1413 |
{ |
1414 |
cerr_strm << "In `sub_yylex()': Returning " |
1415 |
<< name_map[PYTHAGOREAN_MINUS] << "."; |
1416 |
|
1417 |
log_message(cerr_strm); |
1418 |
cerr_message(cerr_strm); |
1419 |
cerr_strm.str(""); |
1420 |
|
1421 |
} |
1422 |
#endif /* |DEBUG_COMPILE| */@; |
1423 |
|
1424 |
scanner_node->set_token_string(curr_token_string); |
1425 |
return PYTHAGOREAN_MINUS; |
1426 |
|
1427 |
} /* |if (next_char == '+')| */ |
1428 |
|
1429 |
@q ******** (8).@> |
1430 |
|
1431 |
else /* (|next_char != '+'|) */ |
1432 |
{ |
1433 |
|
1434 |
cerr_strm << "ERROR! In `sub_yylex()': Invalid input: `+-" |
1435 |
<< next_char << "'." << endl |
1436 |
<< "Will try to continue."; |
1437 |
|
1438 |
|
1439 |
log_message(cerr_strm); |
1440 |
cerr_message(cerr_strm); |
1441 |
cerr_strm.str(""); |
1442 |
|
1443 |
} /* |else| (|next_char != '+'|) */ |
1444 |
|
1445 |
@q ******** (8).@> |
1446 |
|
1447 |
} /* |if (curr_char == '+' && next_char == '-')| */ |
1448 |
|
1449 |
|
1450 |
|
1451 |
@q ******* (7) Hyphen pair or hyphen triple (path joins).@> |
1452 |
@ Hyphen pair or hyphen triple (path joins). |
1453 |
\initials{LDF 2004.09.06.} |
1454 |
|
1455 |
\LOG |
1456 |
\initials{LDF 2004.09.06.} |
1457 |
Added this section. |
1458 |
\ENDLOG |
1459 |
|
1460 |
@<Define scanning functions@>= |
1461 |
|
1462 |
if (curr_char == '-' && next_char == '-') |
1463 |
{ |
1464 |
|
1465 |
scanner_node->ignore(); |
1466 |
++curr_position; |
1467 |
++curr_column; |
1468 |
|
1469 |
next_char = scanner_node->peek(); |
1470 |
|
1471 |
@q ******** (8).@> |
1472 |
|
1473 |
if (next_char == '-') |
1474 |
{ |
1475 |
|
1476 |
scanner_node->ignore(); |
1477 |
++curr_position; |
1478 |
++curr_column; |
1479 |
|
1480 |
|
1481 |
#if DEBUG_COMPILE |
1482 |
if (DEBUG) |
1483 |
{ |
1484 |
cerr_strm << "In `sub_yylex()': Returning " |
1485 |
<< name_map[HYPHEN_TRIPLE] << "."; |
1486 |
|
1487 |
log_message(cerr_strm); |
1488 |
cerr_message(cerr_strm); |
1489 |
cerr_strm.str(""); |
1490 |
|
1491 |
} |
1492 |
#endif /* |DEBUG_COMPILE| */@; |
1493 |
|
1494 |
scanner_node->set_token_string("---"); |
1495 |
return HYPHEN_TRIPLE; |
1496 |
|
1497 |
} /* |if (next_char == '-')| */ |
1498 |
|
1499 |
@q ******** (8).@> |
1500 |
|
1501 |
else /* (|next_char != '-'|) */ |
1502 |
{ |
1503 |
|
1504 |
#if DEBUG_COMPILE |
1505 |
if (DEBUG) |
1506 |
{ |
1507 |
cerr_strm << "In `sub_yylex()': Returning " |
1508 |
<< name_map[HYPHEN_PAIR] << "'."; |
1509 |
|
1510 |
log_message(cerr_strm); |
1511 |
cerr_message(cerr_strm); |
1512 |
cerr_strm.str(""); |
1513 |
} |
1514 |
#endif /* |DEBUG_COMPILE| */@; |
1515 |
|
1516 |
scanner_node->set_token_string("--"); |
1517 |
|
1518 |
|
1519 |
@q ********* (9).@> |
1520 |
|
1521 |
@ |
1522 |
|
1523 |
\LOG |
1524 |
\initials{LDF 2004.10.26.} |
1525 |
Commented this out. It caused an error. |
1526 |
\ENDLOG |
1527 |
|
1528 |
@<Define scanning functions@>= |
1529 |
|
1530 |
#if 0 |
1531 |
/* !! START HERE. LDF 2004.10.26. Connectors must be preceded |
1532 |
and/or followed by whitespace or an error occurs. The exact |
1533 |
behavior differs according to what connector is being used. */@; |
1534 |
|
1535 |
if (scanner_node->get_in_type() == Io_Struct::STDIN_TYPE) |
1536 |
scanner_node->putback(next_char); |
1537 |
#endif |
1538 |
|
1539 |
@q ********* (9).@> |
1540 |
|
1541 |
@ |
1542 |
@<Define scanning functions@>= |
1543 |
|
1544 |
return HYPHEN_PAIR; |
1545 |
|
1546 |
} /* |else| (|next_char != '-'|) */ |
1547 |
|
1548 |
@q ******** (8).@> |
1549 |
|
1550 |
} /* |if (curr_char == '-' && next_char == '-')| */ |
1551 |
|
1552 |
|
1553 |
@q ******* (7) Arithmetical operation with assignment.@> |
1554 |
@q ******* (7) |next_char == '='|. @> |
1555 |
|
1556 |
@ Arithmetical operation with assignment. |
1557 |
|next_char == '='|. |
1558 |
\initials{LDF 2004.08.29.} |
1559 |
|
1560 |
\LOG |
1561 |
\initials{LDF 2004.08.29.} |
1562 |
Added this section. |
1563 |
\ENDLOG |
1564 |
|
1565 |
@<Define scanning functions@>= |
1566 |
|
1567 |
else if (next_char == '=') |
1568 |
{ |
1569 |
|
1570 |
int i; |
1571 |
|
1572 |
|
1573 |
if (curr_char == '+') |
1574 |
{ |
1575 |
scanner_node->set_token_string("+="); |
1576 |
i = PLUS_ASSIGN; |
1577 |
} |
1578 |
|
1579 |
else if (curr_char == '-') |
1580 |
{ |
1581 |
scanner_node->set_token_string("-="); |
1582 |
i = MINUS_ASSIGN; |
1583 |
} |
1584 |
|
1585 |
else if (curr_char == '*') |
1586 |
{ |
1587 |
scanner_node->set_token_string("*="); |
1588 |
i = TIMES_ASSIGN; |
1589 |
} |
1590 |
else if (curr_char == '/') |
1591 |
{ |
1592 |
scanner_node->set_token_string("/="); |
1593 |
i = DIVIDE_ASSIGN; |
1594 |
} |
1595 |
|
1596 |
scanner_node->ignore(); |
1597 |
++curr_position; |
1598 |
++curr_column; |
1599 |
|
1600 |
#if DEBUG_COMPILE |
1601 |
if (DEBUG) |
1602 |
{ |
1603 |
cerr_strm << "In `sub_yylex()': Returning `" |
1604 |
<< name_map[i] << "'."; |
1605 |
|
1606 |
log_message(cerr_strm); |
1607 |
cerr_message(cerr_strm); |
1608 |
cerr_strm.str(""); |
1609 |
|
1610 |
} |
1611 |
#endif /* |DEBUG_COMPILE| */@; |
1612 |
|
1613 |
|
1614 |
return i; |
1615 |
|
1616 |
} /* |if (next_char == '=')| */ |
1617 |
|
1618 |
@q ******* (7) |next_char != '='|.@> |
1619 |
|
1620 |
@ |next_char != '='|. |
1621 |
\initials{LDF 2004.11.28.} |
1622 |
|
1623 |
|
1624 |
\LOG |
1625 |
\initials{LDF 2004.11.29.} |
1626 |
@:BUG FIX@> BUG FIX: |
1627 |
Commented-out |scanner_node->putback(next_char)|. |
1628 |
This seems to work, but I'll have to keep an eye on it. |
1629 |
\ENDLOG |
1630 |
|
1631 |
@<Define scanning functions@>= |
1632 |
|
1633 |
else /* |next_char != '='| */ |
1634 |
{ |
1635 |
|
1636 |
#if DEBUG_COMPILE |
1637 |
if (DEBUG) |
1638 |
{ |
1639 |
cerr_strm << "In `sub_yylex()': Not a special assignment." |
1640 |
<< "Returning `" << name_map[temp_catcode] << "'."; |
1641 |
|
1642 |
log_message(cerr_strm); |
1643 |
cerr_message(cerr_strm); |
1644 |
cerr_strm.str(""); |
1645 |
|
1646 |
} |
1647 |
#endif /* |DEBUG_COMPILE| */@; |
1648 |
|
1649 |
value->string_value[0] = curr_char; |
1650 |
value->string_value[1] = '\0'; |
1651 |
|
1652 |
curr_token_string += curr_char; |
1653 |
|
1654 |
scanner_node->set_token_string(curr_token_string); |
1655 |
|
1656 |
#if 0 |
1657 |
if ( scanner_node->get_in_type() == Io_Struct::STDIN_TYPE |
1658 |
&& next_char != EOF) |
1659 |
scanner_node->putback(next_char); |
1660 |
#endif |
1661 |
|
1662 |
|
1663 |
return temp_catcode; |
1664 |
|
1665 |
} /* |else| (|next_char != '='|) */ |
1666 |
|
1667 |
@q ******* (7).@> |
1668 |
|
1669 |
} /* |if| (possible special assignment). */ |
1670 |
|
1671 |
|
1672 |
@q ****** (6) Periods not followed by digits or periods are ignored.@> |
1673 |
@ Periods not followed by digits or periods are ignored. |
1674 |
\initials{LDF Undated.} |
1675 |
|
1676 |
|
1677 |
\LOG |
1678 |
\initials{LDF 2004.05.13.} |
1679 |
Added code that tests for two or three |
1680 |
|PERIODS| in a row. |
1681 |
\ENDLOG |
1682 |
|
1683 |
@<Define scanning functions@>= |
1684 |
|
1685 |
if (temp_catcode == PERIOD) |
1686 |
{ |
1687 |
#if DEBUG_COMPILE |
1688 |
if (DEBUG) |
1689 |
{ |
1690 |
cerr_strm << thread_name |
1691 |
<< "In `sub_yylex()': First character in token is " |
1692 |
<< "`PERIOD'."; |
1693 |
|
1694 |
log_message(cerr_strm); |
1695 |
cerr_message(cerr_strm); |
1696 |
cerr_strm.str(); |
1697 |
} |
1698 |
#endif /* |DEBUG_COMPILE| */@; |
1699 |
|
1700 |
scanner_node->ignore(); |
1701 |
++curr_position; |
1702 |
++curr_column; |
1703 |
|
1704 |
next_char = scanner_node->peek(); |
1705 |
|
1706 |
@q ******* (7) |get_catcode(next_char) == PERIOD|.@> |
1707 |
|
1708 |
@ |get_catcode(next_char) == PERIOD|. |
1709 |
\initials{LDF 2004.11.28.} |
1710 |
|
1711 |
@<Define scanning functions@>= |
1712 |
|
1713 |
if (get_catcode(next_char) == PERIOD) |
1714 |
{ |
1715 |
|
1716 |
#if DEBUG_COMPILE |
1717 |
if (DEBUG) |
1718 |
{ |
1719 |
cerr_strm << thread_name |
1720 |
<< "In `sub_yylex()': " |
1721 |
<< "Two `PERIODS'."; |
1722 |
|
1723 |
log_message(cerr_strm); |
1724 |
cerr_message(cerr_strm); |
1725 |
cerr_strm.str(); |
1726 |
} |
1727 |
#endif /* |DEBUG_COMPILE| */@; |
1728 |
|
1729 |
scanner_node->ignore(); |
1730 |
++curr_position; |
1731 |
++curr_column; |
1732 |
|
1733 |
next_char = scanner_node->peek(); |
1734 |
|
1735 |
@q ******** (8) |get_catcode(next_char) == PERIOD|.@> |
1736 |
|
1737 |
@ |get_catcode(next_char) == PERIOD|. |
1738 |
\initials{LDF 2004.11.28.} |
1739 |
|
1740 |
@<Define scanning functions@>= |
1741 |
|
1742 |
if (get_catcode(next_char) == PERIOD) |
1743 |
{ |
1744 |
|
1745 |
#if DEBUG_COMPILE |
1746 |
if (DEBUG) |
1747 |
{ |
1748 |
cerr_strm << thread_name |
1749 |
<< "In `sub_yylex()': " |
1750 |
<< "Three `PERIODS'. Returning `PERIOD_TRIPLE'."; |
1751 |
|
1752 |
log_message(cerr_strm); |
1753 |
cerr_message(cerr_strm); |
1754 |
cerr_strm.str(); |
1755 |
} |
1756 |
#endif /* |DEBUG_COMPILE| */@; |
1757 |
|
1758 |
scanner_node->set_token_string("..."); |
1759 |
return PERIOD_TRIPLE; |
1760 |
|
1761 |
} /* |if (get_catcode(next_char) == PERIOD)| */ |
1762 |
|
1763 |
@q ******** (8) |get_catcode(next_char) != PERIOD|.@> |
1764 |
|
1765 |
@ |get_catcode(next_char) != PERIOD|. |
1766 |
\initials{LDF 2004.11.28.} |
1767 |
|
1768 |
@<Define scanning functions@>= |
1769 |
|
1770 |
else /* |get_catcode(next_char) != PERIOD| */ |
1771 |
{ |
1772 |
#if DEBUG_COMPILE |
1773 |
if (DEBUG) |
1774 |
{ |
1775 |
cerr_strm << thread_name |
1776 |
<< "In `sub_yylex()': " |
1777 |
<< "Returning `PERIOD_PAIR'."; |
1778 |
|
1779 |
log_message(cerr_strm); |
1780 |
cerr_message(cerr_strm); |
1781 |
cerr_strm.str(); |
1782 |
} |
1783 |
#endif /* |DEBUG_COMPILE| */@; |
1784 |
|
1785 |
scanner_node->set_token_string(".."); |
1786 |
|
1787 |
@q ********* (9).@> |
1788 |
|
1789 |
@ |
1790 |
|
1791 |
\LOG |
1792 |
\initials{LDF 2004.10.26.} |
1793 |
Commented this out. It caused an error. |
1794 |
\ENDLOG |
1795 |
|
1796 |
@<Define scanning functions@>= |
1797 |
#if 0 |
1798 |
/* !! START HERE. LDF 2004.10.26. Connectors must be preceded |
1799 |
and/or followed by whitespace or an error occurs. The exact |
1800 |
behavior differs according to what connector is being used. */@; |
1801 |
|
1802 |
if (scanner_node->get_in_type() == Io_Struct::STDIN_TYPE) |
1803 |
scanner_node->putback(next_char); |
1804 |
#endif |
1805 |
|
1806 |
@q ********* (9).@> |
1807 |
|
1808 |
@ |
1809 |
@<Define scanning functions@>= |
1810 |
|
1811 |
return PERIOD_PAIR; |
1812 |
|
1813 |
} /* |else| (|get_catcode(next_char) != PERIOD|) */@; |
1814 |
|
1815 |
@q ******** (8).@> |
1816 |
|
1817 |
} /* |if (get_catcode(next_char) == PERIOD)| */ |
1818 |
|
1819 |
|
1820 |
@q ******* (7) |DIGIT|.@> |
1821 |
@ |DIGIT| |
1822 |
\initials{LDF 2004.08.26.} |
1823 |
|
1824 |
@<Define scanning functions@>= |
1825 |
|
1826 |
if (get_catcode(next_char) == DIGIT) |
1827 |
{ |
1828 |
|
1829 |
#if DEBUG_COMPILE |
1830 |
if (DEBUG) |
1831 |
{ |
1832 |
cerr_strm << thread_name << "Next character is a digit." |
1833 |
<< endl |
1834 |
<< "Setting `curr_token_string' to \"0.\", " |
1835 |
<< "changing `curr_catcode' to `REAL', " |
1836 |
<< "and continuing."; |
1837 |
|
1838 |
log_message(cerr_strm); |
1839 |
cerr_message(cerr_strm); |
1840 |
cerr_strm.str(); |
1841 |
} |
1842 |
#endif /* |DEBUG_COMPILE| */@; |
1843 |
|
1844 |
curr_token_string = "0."; |
1845 |
curr_catcode = REAL; |
1846 |
continue; |
1847 |
|
1848 |
} /* |if (get_catcode(next_char) == DIGIT)| */ |
1849 |
|
1850 |
@q ******* (7).@> |
1851 |
|
1852 |
else /* |get_catcode(next_char) != DIGIT| */ |
1853 |
{ |
1854 |
#if DEBUG_COMPILE |
1855 |
if (DEBUG) |
1856 |
{ |
1857 |
cerr_strm << thread_name |
1858 |
<< "In `sub_yylex()': " |
1859 |
<< "Next character isn't a digit." |
1860 |
<< endl |
1861 |
<< "Ignoring period and going to `loop_start'."; |
1862 |
|
1863 |
log_message(cerr_strm); |
1864 |
cerr_message(cerr_strm); |
1865 |
cerr_strm.str(); |
1866 |
} |
1867 |
#endif /* |DEBUG_COMPILE| */@; |
1868 |
|
1869 |
location->first_line = start_line; |
1870 |
location->first_column = start_column; |
1871 |
location->last_line = curr_line; |
1872 |
location->last_column = curr_column; |
1873 |
location->position = curr_position; |
1874 |
|
1875 |
goto loop_start; |
1876 |
|
1877 |
} /* |else| (|get_catcode(next_char) != DIGIT|) */ |
1878 |
|
1879 |
@q ******* (7).@> |
1880 |
|
1881 |
} /* |if (temp_catcode == PERIOD)| */@; |
1882 |
|
1883 |
@q ****** (6).@> |
1884 |
@ |
1885 |
@<Define scanning functions@>= |
1886 |
|
1887 |
#if DEBUG_COMPILE |
1888 |
if (DEBUG) |
1889 |
{ |
1890 |
cerr_strm << "In `sub_yylex()': Continuing here. " |
1891 |
<< "`curr_char' == `" << curr_char << "'"; |
1892 |
|
1893 |
log_message(cerr_strm); |
1894 |
cerr_message(cerr_strm); |
1895 |
cerr_strm.str(""); |
1896 |
} |
1897 |
#endif /* |DEBUG_COMPILE| */@; |
1898 |
|
1899 |
|
1900 |
curr_catcode = temp_catcode; |
1901 |
curr_token_string = scanner_node->get(); |
1902 |
++curr_position; |
1903 |
|
1904 |
if (curr_char == '\n') |
1905 |
{ |
1906 |
++curr_line; |
1907 |
curr_column = 0; |
1908 |
} |
1909 |
else |
1910 |
++curr_column; |
1911 |
|
1912 |
|
1913 |
@q ****** (6) Loners, i.e., tokens that consist of a single character.@> |
1914 |
|
1915 |
@ Loners, i.e., tokens that consist of a single character: |
1916 |
|COMMA|, |SEMI_COLON|, |LEFT_PARENTHESIS|, or |
1917 |
|RIGHT_PARENTHESIS|. We go immediately to |finish|. |
1918 |
\initials{LDF 2004.08.26.} |
1919 |
|
1920 |
@<Define scanning functions@>= |
1921 |
|
1922 |
if ( curr_catcode == COMMA |
1923 |
|| curr_catcode == SEMI_COLON |
1924 |
|| curr_catcode == LEFT_PARENTHESIS |
1925 |
|| curr_catcode == RIGHT_PARENTHESIS) |
1926 |
|
1927 |
{ |
1928 |
#if DEBUG_COMPILE |
1929 |
if (DEBUG) |
1930 |
{ |
1931 |
cerr_strm << thread_name << "In `sub_yylex()': `" |
1932 |
<< name_map[curr_catcode] |
1933 |
<< "'." << endl |
1934 |
<< "Going to `finish'."; |
1935 |
|
1936 |
log_message(cerr_strm); |
1937 |
cerr_message(cerr_strm); |
1938 |
cerr_strm.str(); |
1939 |
} |
1940 |
#endif /* |DEBUG_COMPILE| */@; |
1941 |
|
1942 |
goto finish; |
1943 |
|
1944 |
} /* Loners. */ |
1945 |
|
1946 |
@q ******* (7) |LEFT_PARENTHESIS|.@> |
1947 |
|
1948 |
@ |LEFT_PARENTHESIS|. |
1949 |
\initials{LDF 2004.08.26.} |
1950 |
|
1951 |
@<Define scanning functions@>= |
1952 |
|
1953 |
|
1954 |
if (curr_catcode == LEFT_PARENTHESIS) |
1955 |
{ |
1956 |
#if DEBUG_COMPILE |
1957 |
if (DEBUG) |
1958 |
{ |
1959 |
cerr_strm << thread_name << "In `sub_yylex()': " |
1960 |
<< "`LEFT_PARENTHESIS'. " |
1961 |
<< "going to `finish'."; |
1962 |
|
1963 |
log_message(cerr_strm); |
1964 |
cerr_message(cerr_strm); |
1965 |
cerr_strm.str(); |
1966 |
} |
1967 |
#endif /* |DEBUG_COMPILE| */@; |
1968 |
|
1969 |
|
1970 |
goto finish; |
1971 |
|
1972 |
} /* |if (curr_catcode == LEFT_PARENTHESIS)| */ |
1973 |
|
1974 |
|
1975 |
@q ******* (7) |RIGHT_PARENTHESIS|.@> |
1976 |
|
1977 |
@ |RIGHT_PARENTHESIS|. |
1978 |
\initials{LDF 2004.08.26.} |
1979 |
|
1980 |
@<Define scanning functions@>= |
1981 |
|
1982 |
if (curr_catcode == RIGHT_PARENTHESIS) |
1983 |
{ |
1984 |
#if DEBUG_COMPILE |
1985 |
if (DEBUG) |
1986 |
{ |
1987 |
cerr_strm << thread_name << "In `sub_yylex()': " |
1988 |
<< "`RIGHT_PARENTHESIS'. " |
1989 |
<< "going to `finish'."; |
1990 |
|
1991 |
log_message(cerr_strm); |
1992 |
cerr_message(cerr_strm); |
1993 |
cerr_strm.str(); |
1994 |
} |
1995 |
#endif /* |DEBUG_COMPILE| */@; |
1996 |
|
1997 |
goto finish; |
1998 |
|
1999 |
} /* |if (curr_catcode == RIGHT_PARENTHESIS)| */ |
2000 |
|
2001 |
|
2002 |
@q ****** (6) |DIGIT|.@> |
2003 |
|
2004 |
@ |DIGIT|. Change |curr_catcode| to |INTEGER|. It may later change |
2005 |
to |REAL|, if we scan a period. |
2006 |
\initials{LDF 2004.08.26.} |
2007 |
|
2008 |
@<Define scanning functions@>= |
2009 |
|
2010 |
else if (curr_catcode == DIGIT) |
2011 |
curr_catcode = INTEGER; |
2012 |
|
2013 |
|
2014 |
@q ****** (6) |PERCENT|.@> |
2015 |
@ |PERCENT|. Comment. Skip all characters up to and including the |
2016 |
end-of-line character. |
2017 |
\initials{LDF 2004.04.05.} |
2018 |
|
2019 |
\LOG |
2020 |
\initials{LDF 2004.04.05.} |
2021 |
Added this conditional. |
2022 |
|
2023 |
\initials{LDF 2004.11.30.} |
2024 |
@:BUG FIX@> BUG FIX: |
2025 |
Now returning |SEMI_COLON| if |
2026 |
|scanner_node->get_in_type() == Io_Struct::STDIN_TYPE|. This makes it |
2027 |
possible to have comments in code read from standard input. It does |
2028 |
not work perfectly, however, since users must type \<RETURN> twice in |
2029 |
order to end a comment. This will probably also cause problems when |
2030 |
passing input to the standard input of \.{3dldf} by means of a pipe or |
2031 |
redirection. |
2032 |
\ENDLOG |
2033 |
|
2034 |
|
2035 |
@<Define scanning functions@>= |
2036 |
|
2037 |
else if (curr_catcode == PERCENT) |
2038 |
{ |
2039 |
#if DEBUG_COMPILE |
2040 |
if (DEBUG) |
2041 |
{ |
2042 |
cerr_strm << thread_name |
2043 |
<< "In `sub_yylex()': Handling comment."; |
2044 |
|
2045 |
log_message(cerr_strm); |
2046 |
cerr_message(cerr_strm); |
2047 |
cerr_strm.str(); |
2048 |
} |
2049 |
#endif /* |DEBUG_COMPILE| */@; |
2050 |
|
2051 |
for (;;) |
2052 |
{ |
2053 |
prev_char = curr_char; |
2054 |
curr_char = scanner_node->get(); |
2055 |
++curr_position; |
2056 |
|
2057 |
|
2058 |
@q ******* (7).@> |
2059 |
if (curr_char == EOF) |
2060 |
{ |
2061 |
cerr_strm << thread_name |
2062 |
<< "WARNING! In `sub_yylex()':" |
2063 |
<< endl |
2064 |
<< "File \"" |
2065 |
<< scanner_node->get_in_filename() |
2066 |
<< "\" ends in mid-comment." |
2067 |
<< endl |
2068 |
<< "This is probably nothing to worry about, " |
2069 |
<< "though." << endl << "Returning `" |
2070 |
<< name_map[TERMINATE] << "'."; |
2071 |
|
2072 |
log_message(cerr_strm); |
2073 |
cerr_message(cerr_strm); |
2074 |
cerr_strm.str(); |
2075 |
|
2076 |
location->first_line = start_line; |
2077 |
location->first_column = start_column; |
2078 |
location->last_line = curr_line; |
2079 |
location->last_column = curr_column; |
2080 |
location->position = curr_position; |
2081 |
|
2082 |
scanner_node->set_token_string(curr_token_string); |
2083 |
return TERMINATE; |
2084 |
|
2085 |
} /* |if (curr_char == EOF)| */ |
2086 |
|
2087 |
@q ******* (7).@> |
2088 |
else if (curr_char == '\n') |
2089 |
{ |
2090 |
++curr_line; |
2091 |
curr_column = 0; |
2092 |
|
2093 |
|
2094 |
|
2095 |
|
2096 |
#if DEBUG_COMPILE |
2097 |
if (DEBUG) |
2098 |
{ |
2099 |
cerr_strm << thread_name |
2100 |
<< "`sub_yylex()': " |
2101 |
<< "End of comment. " |
2102 |
<< "Going to `loop_start'."; |
2103 |
|
2104 |
log_message(cerr_strm); |
2105 |
cerr_message(cerr_strm); |
2106 |
cerr_strm.str(); |
2107 |
} |
2108 |
#endif /* |DEBUG_COMPILE| */@; |
2109 |
|
2110 |
location->first_line = start_line; |
2111 |
location->first_column = start_column; |
2112 |
location->last_line = curr_line; |
2113 |
location->last_column = curr_column; |
2114 |
location->position = curr_position; |
2115 |
|
2116 |
if (scanner_node->get_in_type() == Io_Struct::STDIN_TYPE) |
2117 |
return SEMI_COLON; |
2118 |
|
2119 |
else |
2120 |
|
2121 |
goto loop_start; |
2122 |
|
2123 |
} /* |else if (curr_char == '\n')| */ |
2124 |
|
2125 |
@q ******* (7).@> |
2126 |
else |
2127 |
++curr_column; |
2128 |
|
2129 |
} /* |for| */ |
2130 |
|
2131 |
} /* |else if (curr_catcode == PERCENT)| (comment) */ |
2132 |
|
2133 |
@q ****** (6) STRING.@> |
2134 |
|
2135 |
@ |STRING|. Collect characters up to next double-quote character |
2136 |
and return it as a |STRING|. Error if |EOF| or |'\n'| occurs before |
2137 |
closing double quote. |
2138 |
|
2139 |
\TODO |
2140 |
@q { @> |
2141 |
@:TO DO}{{\bf TO DO}@> |
2142 |
@q } @> |
2143 |
@q !! TO DO:@> |
2144 |
\initials{LDF 2004.11.28.} |
2145 |
Look up how {\MF} handles this. |
2146 |
\ENDTODO |
2147 |
|
2148 |
\LOG |
2149 |
\initials{LDF 2004.04.05.} |
2150 |
Added this conditional. |
2151 |
\ENDLOG |
2152 |
|
2153 |
@<Define scanning functions@>= |
2154 |
|
2155 |
|
2156 |
else if (curr_catcode == DOUBLE_QUOTE) |
2157 |
{ |
2158 |
#if DEBUG_COMPILE |
2159 |
if (DEBUG) |
2160 |
{ |
2161 |
cerr_strm << thread_name << "In `sub_yylex()':" |
2162 |
<< endl |
2163 |
<< "Double quote character. " |
2164 |
<< "Collecting string."; |
2165 |
|
2166 |
log_message(cerr_strm); |
2167 |
cerr_message(cerr_strm); |
2168 |
cerr_strm.str(); |
2169 |
} |
2170 |
#endif /* |DEBUG_COMPILE| */@; |
2171 |
|
2172 |
curr_catcode = STRING; |
2173 |
|
2174 |
curr_token_string = ""; |
2175 |
|
2176 |
for (;;) |
2177 |
{ |
2178 |
prev_char = curr_char; |
2179 |
curr_char = scanner_node->get(); |
2180 |
++curr_position; |
2181 |
|
2182 |
|
2183 |
@q ******* (7).@> |
2184 |
|
2185 |
if (curr_char == '\"' && prev_char != '\\') |
2186 |
{ |
2187 |
++curr_column; |
2188 |
#if DEBUG_COMPILE |
2189 |
if (DEBUG) |
2190 |
{ |
2191 |
cerr_strm << thread_name << "In `sub_yylex()': " |
2192 |
<< "Ending string." |
2193 |
<< endl |
2194 |
<< "`curr_token_string' == \"" |
2195 |
<< curr_token_string << "\". " |
2196 |
<< "Going to `finish'."; |
2197 |
|
2198 |
log_message(cerr_strm); |
2199 |
cerr_message(cerr_strm); |
2200 |
cerr_strm.str(); |
2201 |
|
2202 |
} |
2203 |
#endif /* |DEBUG_COMPILE| */@; |
2204 |
|
2205 |
goto finish; |
2206 |
|
2207 |
} /* |if (curr_char == '\"' && prev_char != '\\')| */ |
2208 |
|
2209 |
@q ******* (7).@> |
2210 |
|
2211 |
else if (curr_char == '\n') |
2212 |
{ |
2213 |
++curr_line; |
2214 |
curr_column = 0; |
2215 |
|
2216 |
cerr_strm << thread_name |
2217 |
<< "ERROR! In `sub_yylex()':" |
2218 |
<< endl |
2219 |
<< "Line ends before string does: \"" |
2220 |
<< curr_token_string << "\"" |
2221 |
<< endl << "Setting value->string_value to \"" |
2222 |
<< curr_token_string |
2223 |
<< "\", returning `STRING', and will try " |
2224 |
<< "to continue."; |
2225 |
|
2226 |
log_message(cerr_strm); |
2227 |
cerr_message(cerr_strm); |
2228 |
cerr_strm.str(); |
2229 |
|
2230 |
goto finish; |
2231 |
|
2232 |
} /* |else if (curr_char == '\n')| */ |
2233 |
|
2234 |
@q ******* (7).@> |
2235 |
|
2236 |
else if (curr_char == EOF) |
2237 |
{ |
2238 |
cerr_strm << thread_name << "ERROR! In `sub_yylex()':" |
2239 |
<< endl |
2240 |
<< "File ends before string does: \"" |
2241 |
<< curr_token_string << "\"" |
2242 |
<< endl |
2243 |
<< "Setting `value->string_value' to \"" |
2244 |
<< curr_token_string |
2245 |
<< "\", returning `STRING', and will try " |
2246 |
<< "to continue."; |
2247 |
|
2248 |
log_message(cerr_strm); |
2249 |
cerr_message(cerr_strm); |
2250 |
cerr_strm.str(); |
2251 |
|
2252 |
goto finish; |
2253 |
|
2254 |
} /* |else if (curr_char == EOF)| */ |
2255 |
|
2256 |
@q ******* (7).@> |
2257 |
|
2258 |
else |
2259 |
{ |
2260 |
++curr_column; |
2261 |
curr_token_string += curr_char; |
2262 |
} |
2263 |
|
2264 |
} /* |for| */ |
2265 |
|
2266 |
@q ******* (7).@> |
2267 |
|
2268 |
} /* |else if (curr_catcode == DOUBLE_QUOTE)| */ |
2269 |
|
2270 |
|
2271 |
@q ****** (6) End of first characters. @> |
2272 |
@ End of first characters. |
2273 |
@<Define scanning functions@>= |
2274 |
|
2275 |
} /* |if (first_time)| */ |
2276 |
|
2277 |
@q ***** (5) Not first character in token string.@> |
2278 |
@ Not first character in token string. |
2279 |
@<Define scanning functions@>= |
2280 |
|
2281 |
else /* |!first_time| */ |
2282 |
{ |
2283 |
|
2284 |
if ( temp_catcode == curr_catcode |
2285 |
|| ( temp_catcode == DIGIT |
2286 |
&& (curr_catcode == INTEGER || curr_catcode == REAL))) |
2287 |
{ |
2288 |
curr_token_string += scanner_node->get(); |
2289 |
|
2290 |
|
2291 |
++curr_position; |
2292 |
|
2293 |
if (curr_char == '\n') |
2294 |
{ |
2295 |
++curr_line; |
2296 |
curr_column = 0; |
2297 |
} |
2298 |
else |
2299 |
++curr_column; |
2300 |
} |
2301 |
|
2302 |
|
2303 |
|
2304 |
|
2305 |
@q ******* (7) Period, i.e., a decimal point.@> |
2306 |
@ Period, i.e., a decimal point. |
2307 |
@<Define scanning functions@>= |
2308 |
|
2309 |
else if ( temp_catcode == PERIOD |
2310 |
&& curr_catcode == INTEGER) |
2311 |
{ |
2312 |
#if DEBUG_COMPILE |
2313 |
if (DEBUG) |
2314 |
{ |
2315 |
cerr_strm << thread_name |
2316 |
<< "In `sub_yylex()': " |
2317 |
<< "`PERIOD' following `DIGIT'." |
2318 |
<< endl |
2319 |
<< "Changing `curr_catcode' to `REAL'."; |
2320 |
|
2321 |
log_message(cerr_strm); |
2322 |
cerr_message(cerr_strm); |
2323 |
cerr_strm.str(); |
2324 |
} |
2325 |
#endif /* |DEBUG_COMPILE| */@; |
2326 |
|
2327 |
curr_token_string += scanner_node->get(); |
2328 |
|
2329 |
++curr_position; |
2330 |
|
2331 |
if (curr_char == '\n') |
2332 |
{ |
2333 |
++curr_line; |
2334 |
curr_column = 0; |
2335 |
} |
2336 |
else |
2337 |
++curr_column; |
2338 |
|
2339 |
curr_catcode = REAL; |
2340 |
|
2341 |
} /* |else if ( temp_catcode == PERIOD |
2342 |
&& curr_catcode == INTEGER)| */ |
2343 |
|
2344 |
@q ***** (5) |finish|. @> |
2345 |
|
2346 |
@ |finish|. Any other character whose catcode differs |
2347 |
from the catcode of the token we've been building. |
2348 |
Processing also continues here for loners, when |EOF| is |
2349 |
reached when collecting characters for a token, and when a |
2350 |
period is found, except when we're collecting an integer. |
2351 |
\initials{LDF 2004.04.04.} |
2352 |
|
2353 |
@<Define scanning functions@>= |
2354 |
else /* |temp_catcode != curr_catcode| */ |
2355 |
{ |
2356 |
finish: |
2357 |
|
2358 |
@q ****** (6) Whitespace. @> |
2359 |
@ Whitespace. We don't bother returning from this function, |
2360 |
we just skip over the whitespace. |
2361 |
@<Define scanning functions@>= |
2362 |
|
2363 |
if (curr_catcode == SPACE) |
2364 |
{ |
2365 |
#if DEBUG_COMPILE |
2366 |
if (DEBUG) |
2367 |
{ |
2368 |
cerr_strm << thread_name |
2369 |
<< "In `sub_yylex()': Whitespace. " |
2370 |
<< "Going to `loop_start'."; |
2371 |
|
2372 |
log_message(cerr_strm); |
2373 |
cerr_message(cerr_strm); |
2374 |
cerr_strm.str(); |
2375 |
} |
2376 |
#endif /* |DEBUG_COMPILE| */@; |
2377 |
|
2378 |
location->first_line = start_line; |
2379 |
location->first_column = start_column; |
2380 |
location->last_line = curr_line; |
2381 |
location->last_column = curr_column; |
2382 |
location->position = curr_position; |
2383 |
|
2384 |
goto loop_start; |
2385 |
|
2386 |
} /* |if (curr_catcode == SPACE)| */ |
2387 |
|
2388 |
@q ****** (6) Numerical types.@> |
2389 |
@ Numerical types. |
2390 |
\initials{LDF Undated.} |
2391 |
|
2392 |
@q ******* (7) INTEGER.@> |
2393 |
|
2394 |
@ |INTEGER|. We convert |curr_token_string| to |int| and set |
2395 |
|value->int_value| to it. |
2396 |
\initials{LDF Undated.} |
2397 |
|
2398 |
@<Define scanning functions@>= |
2399 |
|
2400 |
if (curr_catcode == INTEGER) |
2401 |
{ |
2402 |
stringstream s(curr_token_string); |
2403 |
s >> value->int_value; |
2404 |
|
2405 |
#if DEBUG_COMPILE |
2406 |
if (DEBUG) |
2407 |
{ |
2408 |
cerr_strm << thread_name |
2409 |
<< "In `sub_yylex()':" |
2410 |
<< endl << "`value->int_value' == `" |
2411 |
<< value->int_value << "'."; |
2412 |
|
2413 |
log_message(cerr_strm); |
2414 |
cerr_message(cerr_strm); |
2415 |
cerr_strm.str(); |
2416 |
} |
2417 |
#endif /* |DEBUG_COMPILE| */@; |
2418 |
|
2419 |
} /* |if (curr_catcode == INTEGER)| */ |
2420 |
|
2421 |
@q ******* (7) REAL.@> |
2422 |
|
2423 |
@ |REAL|. We convert |curr_token_string| to |real| and set |
2424 |
|value->real_value| to it. |
2425 |
\initials{LDF Undated.} |
2426 |
|
2427 |
@<Define scanning functions@>= |
2428 |
|
2429 |
else if (curr_catcode == REAL) |
2430 |
{ |
2431 |
|
2432 |
stringstream s(curr_token_string); |
2433 |
s >> value->real_value; |
2434 |
|
2435 |
#if DEBUG_COMPILE |
2436 |
if (DEBUG) |
2437 |
{ |
2438 |
cerr_strm << thread_name << "In `sub_yylex()':" |
2439 |
<< endl << "`value->real_value' == `" |
2440 |
<< value->real_value << "'."; |
2441 |
|
2442 |
log_message(cerr_strm); |
2443 |
cerr_message(cerr_strm); |
2444 |
cerr_strm.str(); |
2445 |
} |
2446 |
#endif /* |DEBUG_COMPILE| */@; |
2447 |
|
2448 |
} /* |else if (curr_catcode == REAL)| */ |
2449 |
|
2450 |
@q ****** (6) STRING.@> |
2451 |
|
2452 |
@ |STRING|. We create a new |string|, assign to it from |curr_token_string|, |
2453 |
and point |value->pointer_value| at it. |
2454 |
\initials{LDF Undated.} |
2455 |
|
2456 |
\LOG |
2457 |
\initials{LDF 2004.11.28.} |
2458 |
Now calling |new string| within a |try| block and rethrowing |bad_alloc| |
2459 |
upon failure. |
2460 |
\ENDLOG |
2461 |
|
2462 |
@<Define scanning functions@>= |
2463 |
|
2464 |
else if (curr_catcode == STRING) |
2465 |
{ |
2466 |
|
2467 |
string* s; |
2468 |
|
2469 |
try |
2470 |
{ |
2471 |
s = new string; |
2472 |
} |
2473 |
|
2474 |
catch (bad_alloc) |
2475 |
{ |
2476 |
cerr_strm << thread_name |
2477 |
<< "ERROR! In `sub_yylex()':" |
2478 |
<< endl << "`new string' failed. " |
2479 |
<< "Rethrowing `bad_alloc'."; |
2480 |
|
2481 |
log_message(cerr_strm); |
2482 |
cerr_message(cerr_strm); |
2483 |
cerr_strm.str(); |
2484 |
|
2485 |
throw; |
2486 |
|
2487 |
} /* |catch (bad_alloc)| */ |
2488 |
|
2489 |
*s = curr_token_string; |
2490 |
value->pointer_value = static_cast<void*>(s); |
2491 |
|
2492 |
} /* |else if (curr_catcode == STRING)| */ |
2493 |
|
2494 |
|
2495 |
@q ****** (6) Other types.@> |
2496 |
|
2497 |
@ Other types. We set |value->string_value| to |curr_token_string|. |
2498 |
A value won't always be needed, but this will make it possible |
2499 |
to check the token string in |yyparse()|. |
2500 |
\initials{LDF Undated.} |
2501 |
|
2502 |
@<Define scanning functions@>= |
2503 |
|
2504 |
else /* Other types. */ |
2505 |
{ |
2506 |
|
2507 |
strcpy(value->string_value, curr_token_string.c_str()); |
2508 |
|
2509 |
#if DEBUG_COMPILE |
2510 |
if (DEBUG) |
2511 |
{ |
2512 |
cerr_strm << "In `sub_yylex()': `value->string_value' == " |
2513 |
<< value->string_value << endl |
2514 |
<< "catcode == `" << name_map[curr_catcode] |
2515 |
<< "'."; |
2516 |
|
2517 |
log_message(cerr_strm); |
2518 |
cerr_message(cerr_strm); |
2519 |
cerr_strm.str(""); |
2520 |
} |
2521 |
#endif /* |DEBUG_COMPILE| */@; |
2522 |
|
2523 |
} /* |else| (Other types.) */ |
2524 |
|
2525 |
@q ****** (6) Update positions.@> |
2526 |
|
2527 |
@ Update positions. |
2528 |
\initials{LDF 2004.04.04} |
2529 |
|
2530 |
|
2531 |
\LOG |
2532 |
\initials{LDF 2004.11.29.} |
2533 |
@:BUG FIX@> BUG FIX: |
2534 |
Commented-out |scanner_node->putback(next_char)|. |
2535 |
This seems to work, but I'll have to keep an eye on it. |
2536 |
\ENDLOG |
2537 |
|
2538 |
@<Define scanning functions@>= |
2539 |
|
2540 |
location->first_line = start_line; |
2541 |
location->first_column = start_column; |
2542 |
location->last_line = curr_line; |
2543 |
location->last_column = curr_column; |
2544 |
location->position = curr_position; |
2545 |
|
2546 |
#if DEBUG_COMPILE |
2547 |
if (DEBUG) |
2548 |
{ |
2549 |
#if 0 |
2550 |
cerr << "location->first_line == " |
2551 |
<< location->first_line << endl; |
2552 |
cerr << "location->first_column == " |
2553 |
<< location->first_column << endl; |
2554 |
cerr << "location->last_line == " |
2555 |
<< location->last_line << endl; |
2556 |
cerr << "location->last_column == " |
2557 |
<< location->last_column << endl; |
2558 |
cerr << "location->position == " |
2559 |
<< location->position << endl; |
2560 |
#endif |
2561 |
cerr_strm << thread_name << "Exiting `sub_yylex()'."; |
2562 |
|
2563 |
log_message(cerr_strm); |
2564 |
cerr_message(cerr_strm); |
2565 |
cerr_strm.str(); |
2566 |
} |
2567 |
#endif /* |DEBUG_COMPILE| */@; |
2568 |
|
2569 |
scanner_node->set_token_string(curr_token_string); |
2570 |
|
2571 |
|
2572 |
#if 0 |
2573 |
if ( scanner_node->get_in_type() == Io_Struct::STDIN_TYPE |
2574 |
&& next_char != EOF && !isspace(next_char)) |
2575 |
|
2576 |
scanner_node->putback(next_char); |
2577 |
#endif |
2578 |
|
2579 |
return curr_catcode; |
2580 |
|
2581 |
} /* |else| |(temp_catcode != curr_catcode)|. */@; |
2582 |
|
2583 |
} /* |else| (Not first character in token string). */@; |
2584 |
|
2585 |
} /* |for| */@; |
2586 |
|
2587 |
@q **** (4) End of sub_yylex() definition.@> |
2588 |
@ End of |sub_yylex()| definition. |
2589 |
\initials{LDF 2004.04.04} |
2590 |
|
2591 |
@<Define scanning functions@>= |
2592 |
|
2593 |
} /* End of |sub_yylex()| definition. */ |
2594 |
|
2595 |
@q ** (2) get_catcode() @> |
2596 |
@*1 {\bf get\_catcode()}. |
2597 |
\initials{LDF Undated.} |
2598 |
|
2599 |
|
2600 |
\LOG |
2601 |
\initials{LDF 2005.01.02.} |
2602 |
Added code for returning |LEFT_BRACE| and |RIGHT_BRACE|. |
2603 |
|
2604 |
\initials{LDF 2005.01.03.} |
2605 |
Now returning |SYMBOL_0| if the argument |const char c| is the |
2606 |
``\copyright'' character, octal 251. This is used internally for |
2607 |
typed macro arguments in |Scan_Parse::macro_definition_func()|, which |
2608 |
is defined in \filename{scanprsf.web}. This character should normally |
2609 |
not be used by users in identifiers. |
2610 |
\ENDLOG |
2611 |
|
2612 |
@q *** (3) Declaration.@> |
2613 |
|
2614 |
@<Declare scanning functions@>= |
2615 |
|
2616 |
unsigned int |
2617 |
get_catcode(const char c); |
2618 |
|
2619 |
@q *** (3) Definition.@> |
2620 |
|
2621 |
@ |
2622 |
@<Define scanning functions@>= |
2623 |
|
2624 |
unsigned int |
2625 |
get_catcode(const char c) |
2626 |
{ |
2627 |
using namespace Scan_Parse; |
2628 |
|
2629 |
if (isspace(c)) |
2630 |
return SPACE; |
2631 |
|
2632 |
if (c == '.') |
2633 |
return PERIOD; |
2634 |
|
2635 |
if (c == ',') |
2636 |
return COMMA; |
2637 |
|
2638 |
if (c == ';') |
2639 |
return SEMI_COLON; |
2640 |
|
2641 |
if (c == '(') // ) |
2642 |
return LEFT_PARENTHESIS; |
2643 |
// ( |
2644 |
|
2645 |
if (c == ')') |
2646 |
return RIGHT_PARENTHESIS; |
2647 |
|
2648 |
if (isdigit(c)) |
2649 |
return DIGIT; |
2650 |
|
2651 |
if (c == '%') |
2652 |
return PERCENT; |
2653 |
|
2654 |
if (c == '\"') |
2655 |
return DOUBLE_QUOTE; |
2656 |
|
2657 |
if (isalpha(c) || c == '_' || c == '©') |
2658 |
return SYMBOL_0; |
2659 |
|
2660 |
if (c == '<' || c == '=' || c == '>' |
2661 |
|| c == ':' || c == '|') |
2662 |
return SYMBOL_1; |
2663 |
|
2664 |
if (c == '`' || c == '\'') |
2665 |
return SYMBOL_2; |
2666 |
|
2667 |
if (c == '+' || c == '-') |
2668 |
return SYMBOL_3; |
2669 |
|
2670 |
if (c == '/' || c == '*' || c == '\\') |
2671 |
return SYMBOL_4; |
2672 |
|
2673 |
if (c == '!' || c == '?') |
2674 |
return SYMBOL_5; |
2675 |
|
2676 |
if (c == '#' || c == '&' || c == '@@' || c == '$') |
2677 |
return SYMBOL_6; |
2678 |
|
2679 |
if (c == '^' || c == '~') |
2680 |
return SYMBOL_7; |
2681 |
|
2682 |
if (c == '[' /* ] */ ) |
2683 |
return LEFT_BRACKET; |
2684 |
|
2685 |
if (c == /* [ */ ']') |
2686 |
return RIGHT_BRACKET; |
2687 |
|
2688 |
if (c == '{' /* } */ ) |
2689 |
return LEFT_BRACE; |
2690 |
|
2691 |
if (c == /* { */ '}') |
2692 |
return RIGHT_BRACE; |
2693 |
|
2694 |
} /* End of |get_catcode()| definition. */ |
2695 |
|
2696 |
@q * (1) Putting the scanner together.@> |
2697 |
@* Putting the scanner together. |
2698 |
\initials{LDF Undated.} |
2699 |
|
2700 |
@ This is what's compiled. |
2701 |
@c |
2702 |
@<Include files@>@; |
2703 |
@<Version control identifier@>@; |
2704 |
@<Declare scanning functions@>@; |
2705 |
@<Define scanning functions@>@; |
2706 |
|
2707 |
|
2708 |
|
2709 |
|
2710 |
@q * (1) @> |
2711 |
|
2712 |
@q * Emacs-Lisp code for use in indirect buffers when using the @> |
2713 |
@q GNU Emacs editor. The local variable list is not evaluated when an @> |
2714 |
@q indirect buffer is visited, so it's necessary to evaluate the @> |
2715 |
@q following s-expression in order to use the facilities normally @> |
2716 |
@q accessed via the local variables list. @> |
2717 |
@q \initials{LDF 2004.02.12}. @> |
2718 |
@q (progn (cweb-mode) (outline-minor-mode t) (setq fill-column 80)) @> |
2719 |
|
2720 |
|
2721 |
@q * (1) @> |
2722 |
|
2723 |
@q Local Variables: @> |
2724 |
@q mode:CWEB @> |
2725 |
@q eval:(outline-minor-mode t) @> |
2726 |
@q abbrev-file-name:"~/.abbrev_defs" @> |
2727 |
@q eval:(read-abbrev-file) @> |
2728 |
@q fill-column:80 @> |
2729 |
@q End: @> |