From 4f94d30fe48381d7f2d5d752ea8c2901c6e55ac6 Mon Sep 17 00:00:00 2001 From: Ulya Trofimovich Date: Mon, 29 Jul 2019 16:14:16 +0100 Subject: [PATCH] Added old (unused) example files as they are synced from master anyway. --- src/examples/01_recognizing_integers.i.re | 38 +++++++++ src/examples/02_recognizing_strings.i.re | 47 +++++++++++ src/examples/03_arbitrary_large_input.i.re | 78 ++++++++++++++++++ src/examples/08_ipv4.i--tags.re | 32 ++++++++ src/examples/18_push_model.if.re | 95 ++++++++++++++++++++++ 5 files changed, 290 insertions(+) create mode 100644 src/examples/01_recognizing_integers.i.re create mode 100644 src/examples/02_recognizing_strings.i.re create mode 100644 src/examples/03_arbitrary_large_input.i.re create mode 100644 src/examples/08_ipv4.i--tags.re create mode 100644 src/examples/18_push_model.if.re diff --git a/src/examples/01_recognizing_integers.i.re b/src/examples/01_recognizing_integers.i.re new file mode 100644 index 00000000..47c1320a --- /dev/null +++ b/src/examples/01_recognizing_integers.i.re @@ -0,0 +1,38 @@ +#include + +enum num_t { ERR, BIN, OCT, DEC, HEX }; + +static num_t lex(const char *YYCURSOR) +{ + const char *YYMARKER; + /*!re2c + re2c:define:YYCTYPE = char; + re2c:yyfill:enable = 0; + + end = "\x00"; + bin = '0b' [01]+; + oct = "0" [0-7]*; + dec = [1-9][0-9]*; + hex = '0x' [0-9a-fA-F]+; + + * { return ERR; } + bin end { return BIN; } + oct end { return OCT; } + dec end { return DEC; } + hex end { return HEX; } + */ +} + +int main(int argc, char **argv) +{ + for (int i = 1; i < argc; ++i) { + switch (lex(argv[i])) { + case ERR: printf("error\n"); break; + case BIN: printf("binary\n"); break; + case OCT: printf("octal\n"); break; + case DEC: printf("decimal\n"); break; + case HEX: printf("hexadecimal\n"); break; + } + } + return 0; +} diff --git a/src/examples/02_recognizing_strings.i.re b/src/examples/02_recognizing_strings.i.re new file mode 100644 index 00000000..ec9d6830 --- /dev/null +++ b/src/examples/02_recognizing_strings.i.re @@ -0,0 +1,47 @@ +#include +#include + +/*!max:re2c*/ + +struct input_t { + size_t len; + char *str; + + input_t(const char *s) + : len(strlen(s)) + , str(new char[len + YYMAXFILL]) + { + memcpy(str, s, len); + memset(str + len, 'a', YYMAXFILL); + } + ~input_t() + { + delete[]str; + } +}; + +static bool lex(const input_t & input) +{ + const char *YYCURSOR = input.str; + const char *const YYLIMIT = input.str + input.len + YYMAXFILL; + /*!re2c + re2c:define:YYCTYPE = char; + re2c:define:YYFILL = "return false;"; + re2c:define:YYFILL:naked = 1; + + sstr = "'" [^']* "'"; + dstr = "\"" [^"]* "\""; + + * { return false; } + (sstr | dstr) { return YYLIMIT - YYCURSOR == YYMAXFILL; } + */ +} + +int main(int argc, char **argv) +{ + for (int i = 1; i < argc; ++i) { + input_t arg(argv[i]); + printf("%s: %s\n", lex(arg) ? "str" : "err", argv[i]); + } + return 0; +} diff --git a/src/examples/03_arbitrary_large_input.i.re b/src/examples/03_arbitrary_large_input.i.re new file mode 100644 index 00000000..506ca41f --- /dev/null +++ b/src/examples/03_arbitrary_large_input.i.re @@ -0,0 +1,78 @@ +#include +#include + +/*!max:re2c*/ +static const size_t SIZE = 16; + +struct input_t { + char buf[SIZE + YYMAXFILL]; + char *lim; + char *cur; + char *tok; + bool eof; + + input_t() + : buf() + , lim(buf + SIZE) + , cur(lim) + , tok(lim) + , eof(false) + {} + bool fill(size_t need) + { + if (eof) { + return false; + } + const size_t free = tok - buf; + if (free < need) { + return false; + } + memmove(buf, tok, lim - tok); + lim -= free; + cur -= free; + tok -= free; + lim += fread(lim, 1, free, stdin); + if (lim < buf + SIZE) { + eof = true; + memset(lim, 0, YYMAXFILL); + lim += YYMAXFILL; + } + return true; + } +}; + +static bool lex(input_t & in, unsigned int &count) +{ + for (count = 0;;) { + in.tok = in.cur; + /*!re2c + re2c:define:YYCTYPE = char; + re2c:define:YYCURSOR = in.cur; + re2c:define:YYLIMIT = in.lim; + re2c:define:YYFILL = "if (!in.fill(@@)) return false;"; + re2c:define:YYFILL:naked = 1; + + end = "\x00"; + wsp = [\n]+; + num = [0-9]+; + + * { return false; } + end { return YYMAXFILL == in.lim - in.tok; } + wsp { continue; } + num { ++count; continue; } + */ + } +} + +int main() +{ + input_t in; + unsigned int count; + if (lex(in, count)) { + printf("glorious %u numbers!\n", count); + } else { + printf("error\n"); + } + + return 0; +} diff --git a/src/examples/08_ipv4.i--tags.re b/src/examples/08_ipv4.i--tags.re new file mode 100644 index 00000000..c9e5c19d --- /dev/null +++ b/src/examples/08_ipv4.i--tags.re @@ -0,0 +1,32 @@ +#include + +static int lex(const char *YYCURSOR) +{ + const char *YYMARKER, *o1, *o2, *o3, *o4; + /*!stags:re2c format = 'const char *@@;'; */ + /*!re2c + re2c:define:YYCTYPE = char; + re2c:yyfill:enable = 0; + + end = "\x00"; + oct = [0-9]{1,3}; + dot = "."; + + * { printf("error\n"); return 1; } + + @o1 oct dot @o2 oct dot @o3 oct dot @o4 oct { + printf("parsed: %.*s, %.*s, %.*s, %*s!\n", + (int)(o2 - o1 - 1), o1, + (int)(o3 - o2 - 1), o2, + (int)(o4 - o3 - 1), o3, + (int)(YYCURSOR - o4), o4); + return 0; + } + */ +} + +int main(int argc, char **argv) +{ + for (int i = 1; i < argc; ++i) lex(argv[i]); + return 0; +} diff --git a/src/examples/18_push_model.if.re b/src/examples/18_push_model.if.re new file mode 100644 index 00000000..2f136730 --- /dev/null +++ b/src/examples/18_push_model.if.re @@ -0,0 +1,95 @@ +#include +#include + +/*!max:re2c*/ +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) + /*!getstate:re2c*/ +loop: + in.tok = in.cur; + /*!re2c + re2c:define:YYCTYPE = char; + re2c:define:YYCURSOR = in.cur; + re2c:define:YYLIMIT = in.lim; + re2c:variable:yych = in.yych; + + * { return FAIL; } + [\x00] { return OK; } + [\n ]+ { goto loop; } + [a-zA-Z]+ { ++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; +} -- 2.40.0