/[3dldf]/3dldf/Group/ANIMATNS/scanner.web
ViewVC logotype

Contents of /3dldf/Group/ANIMATNS/scanner.web

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (show annotations) (download)
Wed Dec 29 13:32:06 2010 UTC (13 years, 8 months ago) by lfinsto1
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +2 -1 lines
Added "2011" to copyright notice.

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: @>

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26