1 /* Generated by re2c */
2 #line 1 "push.re"
3 // re2c $INPUT -o $OUTPUT
4 /*
5  *  A push-model scanner example for re2c -f
6  *  Written Mon Apr 11 2005 by mgix@mgix.com
7  *  This file is in the public domain.
8  *
9  */
10 
11 // ----------------------------------------------------------------------
12 
13 #include <fcntl.h>
14 #include <stdio.h>
15 #include <stddef.h>
16 #include <stdlib.h>
17 #include <string.h>
18 
19 #if defined(WIN32)
20 
21     typedef signed char     int8_t;
22     typedef signed short    int16_t;
23     typedef signed int      int32_t;
24 
25     typedef unsigned char   uint8_t;
26     typedef unsigned short  uint16_t;
27     typedef unsigned int    uint32_t;
28 
29 #else
30 
31     #include <stdint.h>
32     #include <unistd.h>
33 
34     #ifndef O_BINARY
35         #define O_BINARY 0
36     #endif
37 
38 #endif
39 
40 // ----------------------------------------------------------------------
41 #define TOKENS              \
42                             \
43     TOK(kEOF)               \
44     TOK(kEOL)               \
45     TOK(kUnknown)           \
46     TOK(kIdentifier)        \
47     TOK(kDecimalConstant)   \
48                             \
49     TOK(kEqual)             \
50     TOK(kLeftParen)         \
51     TOK(kRightParen)        \
52     TOK(kMinus)             \
53     TOK(kPlus)              \
54     TOK(kStar)              \
55     TOK(kSlash)             \
56                             \
57     TOK(kIf)                \
58     TOK(kFor)               \
59     TOK(kElse)              \
60     TOK(kGoto)              \
61     TOK(kBreak)             \
62     TOK(kWhile)             \
63     TOK(kReturn)            \
64 
65 
66 // ----------------------------------------------------------------------
67 static const char *tokenNames[] =
68 {
69     #define TOK(x) #x,
70         TOKENS
71     #undef TOK
72 };
73 
74 // ----------------------------------------------------------------------
75 class PushScanner
76 {
77 public:
78 
79     enum Token
80     {
81         #define TOK(x) x,
82             TOKENS
83         #undef TOK
84     };
85 
86 private:
87 
88     bool        eof;
89     int32_t     state;
90 
91     uint8_t     *limit;
92     uint8_t     *start;
93     uint8_t     *cursor;
94     uint8_t     *marker;
95 
96     uint8_t     *buffer;
97     uint8_t     *bufferEnd;
98 
99     uint8_t     yych;
100     uint32_t    yyaccept;
101 
102 public:
103 
104     // ----------------------------------------------------------------------
PushScanner()105     PushScanner()
106     {
107         limit = 0;
108         start = 0;
109         state = -1;
110         cursor = 0;
111         marker = 0;
112         buffer = 0;
113         eof = false;
114         bufferEnd = 0;
115     }
116 
117     // ----------------------------------------------------------------------
~PushScanner()118     ~PushScanner()
119     {
120     }
121 
122     // ----------------------------------------------------------------------
send(Token token)123     void send(
124         Token token
125     )
126     {
127         size_t tokenSize = cursor-start;
128         const char *tokenName = tokenNames[token];
129         printf(
130             "scanner is pushing out a token of type %d (%s)",
131             token,
132             tokenName
133         );
134 
135         if(token==kEOF) putchar('\n');
136         else
137         {
138             size_t tokenNameSize = strlen(tokenNames[token]);
139             size_t padSize = 20-(20<tokenNameSize ? 20 : tokenNameSize);
140             for(size_t i=0; i<padSize; ++i) putchar(' ');
141             printf(" : ---->");
142 
143             fwrite(
144                 start,
145                 tokenSize,
146                 1,
147                 stdout
148             );
149 
150             printf("<----\n");
151         }
152     }
153 
154     // ----------------------------------------------------------------------
push(const void * input,ssize_t inputSize)155     uint32_t push(
156         const void  *input,
157         ssize_t     inputSize
158     )
159     {
160         printf(
161             "scanner is receiving a new data batch of length %d\n"
162             "scanner continues with saved state = %d\n",
163             inputSize,
164             state
165         );
166 
167         /*
168          * Data source is signaling end of file when batch size
169          * is less than maxFill. This is slightly annoying because
170          * maxFill is a value that can only be known after re2c does
171          * its thing. Practically though, maxFill is never bigger than
172          * the longest keyword, so given our grammar, 32 is a safe bet.
173          */
174         uint8_t null[64];
175         const ssize_t maxFill = 32;
176         if(inputSize<maxFill)
177         {
178             eof = true;
179             input = null;
180             inputSize = sizeof(null);
181             memset(null, 0, sizeof(null));
182         }
183 
184         /*
185          * When we get here, we have a partially
186          * consumed buffer which is in the following state:
187          *                                                                last valid char        last valid buffer spot
188          *                                                                v                      v
189          * +-------------------+-------------+---------------+-------------+----------------------+
190          * ^                   ^             ^               ^             ^                      ^
191          * buffer              start         marker          cursor        limit                  bufferEnd
192          *
193          * We need to stretch the buffer and concatenate the new chunk of input to it
194          *
195          */
196         size_t used = limit-buffer;
197         size_t needed = used+inputSize;
198         size_t allocated = bufferEnd-buffer;
199         if(allocated<needed)
200         {
201             size_t limitOffset = limit-buffer;
202             size_t startOffset = start-buffer;
203             size_t markerOffset = marker-buffer;
204             size_t cursorOffset = cursor-buffer;
205 
206                 buffer = (uint8_t*)realloc(buffer, needed);
207                 bufferEnd = needed+buffer;
208 
209             marker = markerOffset + buffer;
210             cursor = cursorOffset + buffer;
211             start = buffer + startOffset;
212             limit = limitOffset + buffer;
213         }
214         memcpy(limit, input, inputSize);
215         limit += inputSize;
216 
217         // The scanner starts here
218         #define YYLIMIT         limit
219         #define YYCURSOR        cursor
220         #define YYMARKER        marker
221         #define YYCTYPE         uint8_t
222 
223         #define SKIP(x)         { start = cursor; goto yy0; }
224         #define SEND(x)         { send(x); SKIP();          }
225         #define YYFILL(n)       { goto fill;                }
226 
227         #define YYGETSTATE()    state
228         #define YYSETSTATE(x)   { state = (x);  }
229 
230     start:
231 
232 
233 #line 234 "push.c"
234 {
235 	YYCTYPE yych;
236 yy0:
237 	if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7);
238 	yych = *YYCURSOR;
239 	switch (yych) {
240 	case 0x00:	goto yy3;
241 	case '\t':
242 	case '\v':
243 	case '\f':
244 	case '\r':
245 	case ' ':	goto yy7;
246 	case '\n':	goto yy9;
247 	case '(':	goto yy11;
248 	case ')':	goto yy13;
249 	case '*':	goto yy15;
250 	case '+':	goto yy17;
251 	case '-':	goto yy19;
252 	case '/':	goto yy21;
253 	case '0':
254 	case '1':
255 	case '2':
256 	case '3':
257 	case '4':
258 	case '5':
259 	case '6':
260 	case '7':
261 	case '8':
262 	case '9':	goto yy23;
263 	case '=':	goto yy26;
264 	case 'A':
265 	case 'B':
266 	case 'C':
267 	case 'D':
268 	case 'E':
269 	case 'F':
270 	case 'G':
271 	case 'H':
272 	case 'I':
273 	case 'J':
274 	case 'K':
275 	case 'L':
276 	case 'M':
277 	case 'N':
278 	case 'O':
279 	case 'P':
280 	case 'Q':
281 	case 'R':
282 	case 'S':
283 	case 'T':
284 	case 'U':
285 	case 'V':
286 	case 'W':
287 	case 'X':
288 	case 'Y':
289 	case 'Z':
290 	case '_':
291 	case 'a':
292 	case 'c':
293 	case 'd':
294 	case 'h':
295 	case 'j':
296 	case 'k':
297 	case 'l':
298 	case 'm':
299 	case 'n':
300 	case 'o':
301 	case 'p':
302 	case 'q':
303 	case 's':
304 	case 't':
305 	case 'u':
306 	case 'v':
307 	case 'x':
308 	case 'y':
309 	case 'z':	goto yy28;
310 	case 'b':	goto yy31;
311 	case 'e':	goto yy32;
312 	case 'f':	goto yy33;
313 	case 'g':	goto yy34;
314 	case 'i':	goto yy35;
315 	case 'r':	goto yy36;
316 	case 'w':	goto yy37;
317 	default:	goto yy5;
318 	}
319 yy3:
320 	++YYCURSOR;
321 #line 260 "push.re"
322 	{ send(kEOF); return 1;  }
323 #line 324 "push.c"
324 yy5:
325 	++YYCURSOR;
326 #line 261 "push.re"
327 	{ SEND(kUnknown);        }
328 #line 329 "push.c"
329 yy7:
330 	++YYCURSOR;
331 #line 259 "push.re"
332 	{ SKIP();                }
333 #line 334 "push.c"
334 yy9:
335 	++YYCURSOR;
336 #line 258 "push.re"
337 	{ SKIP();                }
338 #line 339 "push.c"
339 yy11:
340 	++YYCURSOR;
341 #line 251 "push.re"
342 	{ SEND(kLeftParen);      }
343 #line 344 "push.c"
344 yy13:
345 	++YYCURSOR;
346 #line 252 "push.re"
347 	{ SEND(kRightParen);     }
348 #line 349 "push.c"
349 yy15:
350 	++YYCURSOR;
351 #line 255 "push.re"
352 	{ SEND(kStar);           }
353 #line 354 "push.c"
354 yy17:
355 	++YYCURSOR;
356 #line 254 "push.re"
357 	{ SEND(kPlus);           }
358 #line 359 "push.c"
359 yy19:
360 	++YYCURSOR;
361 #line 253 "push.re"
362 	{ SEND(kMinus);          }
363 #line 364 "push.c"
364 yy21:
365 	++YYCURSOR;
366 #line 256 "push.re"
367 	{ SEND(kSlash);          }
368 #line 369 "push.c"
369 yy23:
370 	++YYCURSOR;
371 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
372 	yych = *YYCURSOR;
373 	switch (yych) {
374 	case '0':
375 	case '1':
376 	case '2':
377 	case '3':
378 	case '4':
379 	case '5':
380 	case '6':
381 	case '7':
382 	case '8':
383 	case '9':	goto yy23;
384 	default:	goto yy25;
385 	}
386 yy25:
387 #line 248 "push.re"
388 	{ SEND(kDecimalConstant);}
389 #line 390 "push.c"
390 yy26:
391 	++YYCURSOR;
392 #line 250 "push.re"
393 	{ SEND(kEqual);          }
394 #line 395 "push.c"
395 yy28:
396 	++YYCURSOR;
397 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
398 	yych = *YYCURSOR;
399 yy29:
400 	switch (yych) {
401 	case '0':
402 	case '1':
403 	case '2':
404 	case '3':
405 	case '4':
406 	case '5':
407 	case '6':
408 	case '7':
409 	case '8':
410 	case '9':
411 	case 'A':
412 	case 'B':
413 	case 'C':
414 	case 'D':
415 	case 'E':
416 	case 'F':
417 	case 'G':
418 	case 'H':
419 	case 'I':
420 	case 'J':
421 	case 'K':
422 	case 'L':
423 	case 'M':
424 	case 'N':
425 	case 'O':
426 	case 'P':
427 	case 'Q':
428 	case 'R':
429 	case 'S':
430 	case 'T':
431 	case 'U':
432 	case 'V':
433 	case 'W':
434 	case 'X':
435 	case 'Y':
436 	case 'Z':
437 	case '_':
438 	case 'a':
439 	case 'b':
440 	case 'c':
441 	case 'd':
442 	case 'e':
443 	case 'f':
444 	case 'g':
445 	case 'h':
446 	case 'i':
447 	case 'j':
448 	case 'k':
449 	case 'l':
450 	case 'm':
451 	case 'n':
452 	case 'o':
453 	case 'p':
454 	case 'q':
455 	case 'r':
456 	case 's':
457 	case 't':
458 	case 'u':
459 	case 'v':
460 	case 'w':
461 	case 'x':
462 	case 'y':
463 	case 'z':	goto yy28;
464 	default:	goto yy30;
465 	}
466 yy30:
467 #line 247 "push.re"
468 	{ SEND(kIdentifier);     }
469 #line 470 "push.c"
470 yy31:
471 	yych = *++YYCURSOR;
472 	switch (yych) {
473 	case 'r':	goto yy38;
474 	default:	goto yy29;
475 	}
476 yy32:
477 	yych = *++YYCURSOR;
478 	switch (yych) {
479 	case 'l':	goto yy39;
480 	default:	goto yy29;
481 	}
482 yy33:
483 	yych = *++YYCURSOR;
484 	switch (yych) {
485 	case 'o':	goto yy40;
486 	default:	goto yy29;
487 	}
488 yy34:
489 	yych = *++YYCURSOR;
490 	switch (yych) {
491 	case 'o':	goto yy41;
492 	default:	goto yy29;
493 	}
494 yy35:
495 	yych = *++YYCURSOR;
496 	switch (yych) {
497 	case 'f':	goto yy42;
498 	default:	goto yy29;
499 	}
500 yy36:
501 	yych = *++YYCURSOR;
502 	switch (yych) {
503 	case 'e':	goto yy44;
504 	default:	goto yy29;
505 	}
506 yy37:
507 	yych = *++YYCURSOR;
508 	switch (yych) {
509 	case 'h':	goto yy45;
510 	default:	goto yy29;
511 	}
512 yy38:
513 	yych = *++YYCURSOR;
514 	switch (yych) {
515 	case 'e':	goto yy46;
516 	default:	goto yy29;
517 	}
518 yy39:
519 	yych = *++YYCURSOR;
520 	switch (yych) {
521 	case 's':	goto yy47;
522 	default:	goto yy29;
523 	}
524 yy40:
525 	yych = *++YYCURSOR;
526 	switch (yych) {
527 	case 'r':	goto yy48;
528 	default:	goto yy29;
529 	}
530 yy41:
531 	yych = *++YYCURSOR;
532 	switch (yych) {
533 	case 't':	goto yy50;
534 	default:	goto yy29;
535 	}
536 yy42:
537 	yych = *++YYCURSOR;
538 	switch (yych) {
539 	case '0':
540 	case '1':
541 	case '2':
542 	case '3':
543 	case '4':
544 	case '5':
545 	case '6':
546 	case '7':
547 	case '8':
548 	case '9':
549 	case 'A':
550 	case 'B':
551 	case 'C':
552 	case 'D':
553 	case 'E':
554 	case 'F':
555 	case 'G':
556 	case 'H':
557 	case 'I':
558 	case 'J':
559 	case 'K':
560 	case 'L':
561 	case 'M':
562 	case 'N':
563 	case 'O':
564 	case 'P':
565 	case 'Q':
566 	case 'R':
567 	case 'S':
568 	case 'T':
569 	case 'U':
570 	case 'V':
571 	case 'W':
572 	case 'X':
573 	case 'Y':
574 	case 'Z':
575 	case '_':
576 	case 'a':
577 	case 'b':
578 	case 'c':
579 	case 'd':
580 	case 'e':
581 	case 'f':
582 	case 'g':
583 	case 'h':
584 	case 'i':
585 	case 'j':
586 	case 'k':
587 	case 'l':
588 	case 'm':
589 	case 'n':
590 	case 'o':
591 	case 'p':
592 	case 'q':
593 	case 'r':
594 	case 's':
595 	case 't':
596 	case 'u':
597 	case 'v':
598 	case 'w':
599 	case 'x':
600 	case 'y':
601 	case 'z':	goto yy28;
602 	default:	goto yy43;
603 	}
604 yy43:
605 #line 240 "push.re"
606 	{ SEND(kIf);             }
607 #line 608 "push.c"
608 yy44:
609 	yych = *++YYCURSOR;
610 	switch (yych) {
611 	case 't':	goto yy51;
612 	default:	goto yy29;
613 	}
614 yy45:
615 	yych = *++YYCURSOR;
616 	switch (yych) {
617 	case 'i':	goto yy52;
618 	default:	goto yy29;
619 	}
620 yy46:
621 	yych = *++YYCURSOR;
622 	switch (yych) {
623 	case 'a':	goto yy53;
624 	default:	goto yy29;
625 	}
626 yy47:
627 	yych = *++YYCURSOR;
628 	switch (yych) {
629 	case 'e':	goto yy54;
630 	default:	goto yy29;
631 	}
632 yy48:
633 	yych = *++YYCURSOR;
634 	switch (yych) {
635 	case '0':
636 	case '1':
637 	case '2':
638 	case '3':
639 	case '4':
640 	case '5':
641 	case '6':
642 	case '7':
643 	case '8':
644 	case '9':
645 	case 'A':
646 	case 'B':
647 	case 'C':
648 	case 'D':
649 	case 'E':
650 	case 'F':
651 	case 'G':
652 	case 'H':
653 	case 'I':
654 	case 'J':
655 	case 'K':
656 	case 'L':
657 	case 'M':
658 	case 'N':
659 	case 'O':
660 	case 'P':
661 	case 'Q':
662 	case 'R':
663 	case 'S':
664 	case 'T':
665 	case 'U':
666 	case 'V':
667 	case 'W':
668 	case 'X':
669 	case 'Y':
670 	case 'Z':
671 	case '_':
672 	case 'a':
673 	case 'b':
674 	case 'c':
675 	case 'd':
676 	case 'e':
677 	case 'f':
678 	case 'g':
679 	case 'h':
680 	case 'i':
681 	case 'j':
682 	case 'k':
683 	case 'l':
684 	case 'm':
685 	case 'n':
686 	case 'o':
687 	case 'p':
688 	case 'q':
689 	case 'r':
690 	case 's':
691 	case 't':
692 	case 'u':
693 	case 'v':
694 	case 'w':
695 	case 'x':
696 	case 'y':
697 	case 'z':	goto yy28;
698 	default:	goto yy49;
699 	}
700 yy49:
701 #line 241 "push.re"
702 	{ SEND(kFor);            }
703 #line 704 "push.c"
704 yy50:
705 	yych = *++YYCURSOR;
706 	switch (yych) {
707 	case 'o':	goto yy56;
708 	default:	goto yy29;
709 	}
710 yy51:
711 	yych = *++YYCURSOR;
712 	switch (yych) {
713 	case 'u':	goto yy58;
714 	default:	goto yy29;
715 	}
716 yy52:
717 	yych = *++YYCURSOR;
718 	switch (yych) {
719 	case 'l':	goto yy59;
720 	default:	goto yy29;
721 	}
722 yy53:
723 	yych = *++YYCURSOR;
724 	switch (yych) {
725 	case 'k':	goto yy60;
726 	default:	goto yy29;
727 	}
728 yy54:
729 	yych = *++YYCURSOR;
730 	switch (yych) {
731 	case '0':
732 	case '1':
733 	case '2':
734 	case '3':
735 	case '4':
736 	case '5':
737 	case '6':
738 	case '7':
739 	case '8':
740 	case '9':
741 	case 'A':
742 	case 'B':
743 	case 'C':
744 	case 'D':
745 	case 'E':
746 	case 'F':
747 	case 'G':
748 	case 'H':
749 	case 'I':
750 	case 'J':
751 	case 'K':
752 	case 'L':
753 	case 'M':
754 	case 'N':
755 	case 'O':
756 	case 'P':
757 	case 'Q':
758 	case 'R':
759 	case 'S':
760 	case 'T':
761 	case 'U':
762 	case 'V':
763 	case 'W':
764 	case 'X':
765 	case 'Y':
766 	case 'Z':
767 	case '_':
768 	case 'a':
769 	case 'b':
770 	case 'c':
771 	case 'd':
772 	case 'e':
773 	case 'f':
774 	case 'g':
775 	case 'h':
776 	case 'i':
777 	case 'j':
778 	case 'k':
779 	case 'l':
780 	case 'm':
781 	case 'n':
782 	case 'o':
783 	case 'p':
784 	case 'q':
785 	case 'r':
786 	case 's':
787 	case 't':
788 	case 'u':
789 	case 'v':
790 	case 'w':
791 	case 'x':
792 	case 'y':
793 	case 'z':	goto yy28;
794 	default:	goto yy55;
795 	}
796 yy55:
797 #line 242 "push.re"
798 	{ SEND(kElse);           }
799 #line 800 "push.c"
800 yy56:
801 	yych = *++YYCURSOR;
802 	switch (yych) {
803 	case '0':
804 	case '1':
805 	case '2':
806 	case '3':
807 	case '4':
808 	case '5':
809 	case '6':
810 	case '7':
811 	case '8':
812 	case '9':
813 	case 'A':
814 	case 'B':
815 	case 'C':
816 	case 'D':
817 	case 'E':
818 	case 'F':
819 	case 'G':
820 	case 'H':
821 	case 'I':
822 	case 'J':
823 	case 'K':
824 	case 'L':
825 	case 'M':
826 	case 'N':
827 	case 'O':
828 	case 'P':
829 	case 'Q':
830 	case 'R':
831 	case 'S':
832 	case 'T':
833 	case 'U':
834 	case 'V':
835 	case 'W':
836 	case 'X':
837 	case 'Y':
838 	case 'Z':
839 	case '_':
840 	case 'a':
841 	case 'b':
842 	case 'c':
843 	case 'd':
844 	case 'e':
845 	case 'f':
846 	case 'g':
847 	case 'h':
848 	case 'i':
849 	case 'j':
850 	case 'k':
851 	case 'l':
852 	case 'm':
853 	case 'n':
854 	case 'o':
855 	case 'p':
856 	case 'q':
857 	case 'r':
858 	case 's':
859 	case 't':
860 	case 'u':
861 	case 'v':
862 	case 'w':
863 	case 'x':
864 	case 'y':
865 	case 'z':	goto yy28;
866 	default:	goto yy57;
867 	}
868 yy57:
869 #line 243 "push.re"
870 	{ SEND(kGoto);           }
871 #line 872 "push.c"
872 yy58:
873 	yych = *++YYCURSOR;
874 	switch (yych) {
875 	case 'r':	goto yy62;
876 	default:	goto yy29;
877 	}
878 yy59:
879 	yych = *++YYCURSOR;
880 	switch (yych) {
881 	case 'e':	goto yy63;
882 	default:	goto yy29;
883 	}
884 yy60:
885 	yych = *++YYCURSOR;
886 	switch (yych) {
887 	case '0':
888 	case '1':
889 	case '2':
890 	case '3':
891 	case '4':
892 	case '5':
893 	case '6':
894 	case '7':
895 	case '8':
896 	case '9':
897 	case 'A':
898 	case 'B':
899 	case 'C':
900 	case 'D':
901 	case 'E':
902 	case 'F':
903 	case 'G':
904 	case 'H':
905 	case 'I':
906 	case 'J':
907 	case 'K':
908 	case 'L':
909 	case 'M':
910 	case 'N':
911 	case 'O':
912 	case 'P':
913 	case 'Q':
914 	case 'R':
915 	case 'S':
916 	case 'T':
917 	case 'U':
918 	case 'V':
919 	case 'W':
920 	case 'X':
921 	case 'Y':
922 	case 'Z':
923 	case '_':
924 	case 'a':
925 	case 'b':
926 	case 'c':
927 	case 'd':
928 	case 'e':
929 	case 'f':
930 	case 'g':
931 	case 'h':
932 	case 'i':
933 	case 'j':
934 	case 'k':
935 	case 'l':
936 	case 'm':
937 	case 'n':
938 	case 'o':
939 	case 'p':
940 	case 'q':
941 	case 'r':
942 	case 's':
943 	case 't':
944 	case 'u':
945 	case 'v':
946 	case 'w':
947 	case 'x':
948 	case 'y':
949 	case 'z':	goto yy28;
950 	default:	goto yy61;
951 	}
952 yy61:
953 #line 244 "push.re"
954 	{ SEND(kBreak);          }
955 #line 956 "push.c"
956 yy62:
957 	yych = *++YYCURSOR;
958 	switch (yych) {
959 	case 'n':	goto yy65;
960 	default:	goto yy29;
961 	}
962 yy63:
963 	yych = *++YYCURSOR;
964 	switch (yych) {
965 	case '0':
966 	case '1':
967 	case '2':
968 	case '3':
969 	case '4':
970 	case '5':
971 	case '6':
972 	case '7':
973 	case '8':
974 	case '9':
975 	case 'A':
976 	case 'B':
977 	case 'C':
978 	case 'D':
979 	case 'E':
980 	case 'F':
981 	case 'G':
982 	case 'H':
983 	case 'I':
984 	case 'J':
985 	case 'K':
986 	case 'L':
987 	case 'M':
988 	case 'N':
989 	case 'O':
990 	case 'P':
991 	case 'Q':
992 	case 'R':
993 	case 'S':
994 	case 'T':
995 	case 'U':
996 	case 'V':
997 	case 'W':
998 	case 'X':
999 	case 'Y':
1000 	case 'Z':
1001 	case '_':
1002 	case 'a':
1003 	case 'b':
1004 	case 'c':
1005 	case 'd':
1006 	case 'e':
1007 	case 'f':
1008 	case 'g':
1009 	case 'h':
1010 	case 'i':
1011 	case 'j':
1012 	case 'k':
1013 	case 'l':
1014 	case 'm':
1015 	case 'n':
1016 	case 'o':
1017 	case 'p':
1018 	case 'q':
1019 	case 'r':
1020 	case 's':
1021 	case 't':
1022 	case 'u':
1023 	case 'v':
1024 	case 'w':
1025 	case 'x':
1026 	case 'y':
1027 	case 'z':	goto yy28;
1028 	default:	goto yy64;
1029 	}
1030 yy64:
1031 #line 245 "push.re"
1032 	{ SEND(kWhile);          }
1033 #line 1034 "push.c"
1034 yy65:
1035 	yych = *++YYCURSOR;
1036 	switch (yych) {
1037 	case '0':
1038 	case '1':
1039 	case '2':
1040 	case '3':
1041 	case '4':
1042 	case '5':
1043 	case '6':
1044 	case '7':
1045 	case '8':
1046 	case '9':
1047 	case 'A':
1048 	case 'B':
1049 	case 'C':
1050 	case 'D':
1051 	case 'E':
1052 	case 'F':
1053 	case 'G':
1054 	case 'H':
1055 	case 'I':
1056 	case 'J':
1057 	case 'K':
1058 	case 'L':
1059 	case 'M':
1060 	case 'N':
1061 	case 'O':
1062 	case 'P':
1063 	case 'Q':
1064 	case 'R':
1065 	case 'S':
1066 	case 'T':
1067 	case 'U':
1068 	case 'V':
1069 	case 'W':
1070 	case 'X':
1071 	case 'Y':
1072 	case 'Z':
1073 	case '_':
1074 	case 'a':
1075 	case 'b':
1076 	case 'c':
1077 	case 'd':
1078 	case 'e':
1079 	case 'f':
1080 	case 'g':
1081 	case 'h':
1082 	case 'i':
1083 	case 'j':
1084 	case 'k':
1085 	case 'l':
1086 	case 'm':
1087 	case 'n':
1088 	case 'o':
1089 	case 'p':
1090 	case 'q':
1091 	case 'r':
1092 	case 's':
1093 	case 't':
1094 	case 'u':
1095 	case 'v':
1096 	case 'w':
1097 	case 'x':
1098 	case 'y':
1099 	case 'z':	goto yy28;
1100 	default:	goto yy66;
1101 	}
1102 yy66:
1103 #line 246 "push.re"
1104 	{ SEND(kReturn);         }
1105 #line 1106 "push.c"
1106 }
1107 #line 262 "push.re"
1108 
1109 
1110     fill:
1111         ssize_t unfinishedSize = cursor-start;
1112         printf(
1113             "scanner needs a refill. Exiting for now with:\n"
1114             "    saved fill state = %d\n"
1115             "    unfinished token size = %d\n",
1116             state,
1117             unfinishedSize
1118         );
1119 
1120         if(0<unfinishedSize && start<limit)
1121         {
1122             printf("    unfinished token is :");
1123             fwrite(start, 1, cursor-start, stdout);
1124             putchar('\n');
1125         }
1126         putchar('\n');
1127 
1128         /*
1129          * Once we get here, we can get rid of
1130          * everything before start and after limit.
1131          */
1132         if(eof==true) goto start;
1133         if(buffer<start)
1134         {
1135             size_t startOffset = start-buffer;
1136             memmove(buffer, start, limit-start);
1137             marker -= startOffset;
1138             cursor -= startOffset;
1139             limit -= startOffset;
1140             start -= startOffset;
1141         }
1142         return 0;
1143     }
1144 };
1145 
1146 // ----------------------------------------------------------------------
main(int argc,char ** argv)1147 int main(
1148     int     argc,
1149     char    **argv
1150 )
1151 {
1152     // Parse cmd line
1153     int input = 0;
1154     if(1<argc)
1155     {
1156         input = open(argv[1], O_RDONLY | O_BINARY);
1157         if(input<0)
1158         {
1159             fprintf(
1160                 stderr,
1161                 "could not open file %s\n",
1162                 argv[1]
1163             );
1164             exit(1);
1165         }
1166     }
1167 
1168     /*
1169      * Tokenize input file by pushing batches
1170      * of data one by one into the scanner.
1171      */
1172     const size_t batchSize = 256;
1173     uint8_t buffer[batchSize];
1174     PushScanner scanner;
1175     while(1)
1176     {
1177         ssize_t n = read(input, buffer, batchSize);
1178         scanner.push(buffer, n);
1179         if(n<batchSize) break;
1180     }
1181     scanner.push(0, -1);
1182     close(input);
1183 
1184     // Done
1185     return 0;
1186 }
1187 
1188 push.re:238:22: warning: escape has no effect: '\h' [-Wuseless-escape]
1189