File: //proc/597785/root/usr/share/doc/re2c/examples/18_push_model.if.c
/* Generated by re2c */
#include <stdio.h>
#include <string.h>
#define YYMAXFILL 1
static const size_t SIZE = 4096;
struct input_t {
char buf[SIZE + YYMAXFILL];
char *lim;
char *cur;
char *tok;
int state;
unsigned need;
unsigned yyaccept;
char yych;
input_t()
: buf()
, lim(buf + SIZE)
, cur(lim)
, tok(lim)
, state(-1)
, need(0)
, yyaccept(0)
, yych(0)
{}
bool fill()
{
const size_t free = tok - buf;
if (free < need) return false;
memmove(buf, tok, buf - tok + SIZE);
lim -= free;
cur -= free;
tok -= free;
lim += fread(lim, 1, free, stdin);
if (lim < buf + SIZE) {
memset(lim, 0, YYMAXFILL);
lim += YYMAXFILL;
}
return true;
}
};
enum status_t { OK, FAIL, NEED_MORE_INPUT };
static status_t lex(input_t &in, unsigned &words)
{
# define YYGETSTATE() in.state
# define YYSETSTATE(s) in.state = s
# define YYFILL(n) do { in.need = n; return NEED_MORE_INPUT; } while (0)
switch (YYGETSTATE()) {
default: goto yy0;
case 0: goto yyFillLabel0;
case 1: goto yyFillLabel1;
case 2: goto yyFillLabel2;
}
loop:
in.tok = in.cur;
yy0:
YYSETSTATE(0);
if (in.lim <= in.cur) YYFILL(1);
yyFillLabel0:
in.yych = *in.cur;
switch (in.yych) {
case 0x00: goto yy2;
case '\n':
case ' ': goto yy6;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z': goto yy9;
default: goto yy4;
}
yy2:
++in.cur;
{ return OK; }
yy4:
++in.cur;
{ return FAIL; }
yy6:
++in.cur;
YYSETSTATE(1);
if (in.lim <= in.cur) YYFILL(1);
yyFillLabel1:
in.yych = *in.cur;
switch (in.yych) {
case '\n':
case ' ': goto yy6;
default: goto yy8;
}
yy8:
{ goto loop; }
yy9:
++in.cur;
YYSETSTATE(2);
if (in.lim <= in.cur) YYFILL(1);
yyFillLabel2:
in.yych = *in.cur;
switch (in.yych) {
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z': goto yy9;
default: goto yy11;
}
yy11:
{ ++words; goto loop; }
}
int main()
{
input_t in;
unsigned words = 0;
while (true) {
const status_t st = lex(in, words);
// end of input: print result
if (st == OK) {
printf("\nword count: %u\n", words);
break;
// unexpected error: abort
} else if (st == FAIL) {
printf("\nerror\n");
return 1;
// get more input and continue
} else if (!in.fill()) {
printf("\nsmall buffer\n");
return 2;
}
}
return 0;
}