]> granicus.if.org Git - re2c/commitdiff
Multiple small fixes in examples.
authorUlya Trofimovich <skvadrik@gmail.com>
Wed, 4 Nov 2015 13:13:10 +0000 (13:13 +0000)
committerUlya Trofimovich <skvadrik@gmail.com>
Wed, 4 Nov 2015 13:13:10 +0000 (13:13 +0000)
src/examples.rst
src/examples/01_recognizing_integers.re
src/examples/02_recognizing_strings.re
src/examples/03_arbitrary_large_input.re
src/examples/06_braille.re
src/examples/07_c++98.re

index a5b7fd7d11bbe7d82df26f74a005ce800cb59a85..e0ce9162a169808212648e49ac7de895665929ca 100644 (file)
@@ -3,7 +3,13 @@
 Recognizing integers: the sentinel method
 -----------------------------------------
 
-This program simply loops over its commad-line arguments
+This example is very simple, yet practical.
+We assume that the input is small (fits in one continuous piece of memory).
+We also assume that some characters never occur in well-formed input (but may occur in ill-formed input).
+This is often the case in simple real-world tasks like parsing program options,
+converting strings to numbers, determining binary file type based on magic in the first few bytes,
+efficiently switching on a string and many others.
+Our example program simply loops over its commad-line arguments
 and tries to match each argument against one of the four patterns:
 binary, octal, decimal and hexadecimal integer literals.
 The numbers are not *parsed* (their numeric value is not retrieved), they are merely *recognized*.
@@ -16,18 +22,20 @@ The numbers are not *parsed* (their numeric value is not retrieved), they are me
 
 A couple of things should be noted:
 
-* Default case (when none of the patterns matched) is handled properly (line 17).
+* Default case (when none of the rules matched) is handled properly with ``*`` rule (line 16).
+  **Never forget to handle default case, otherwise control flow in lexer will be undefined for some input strings.**
+  Use [-Wundefined-control-flow] re2c warning: it will warn you about unhandled default case and
+  show input patterns that are not covered by the rules.
 
-* Check for the end of input is disabled (line 9).
-  In this case we can use ``NULL`` character as a sentinel:
-  all arguments are ``NULL``-terminated and none of the rules matches ``NULL`` in the middle.
+* We use the *sentinel* method to stop at the end of input (``re2c:yyfill:enable = 0;`` at line 8).
+  Sentinel is a special character that can never occur in well-formed input.
+  It is appended to the end of input and serves as a stop signal for the lexer.
+  In out case sentinel is ``NULL``: all arguments are ``NULL``-terminated and none of the rules matches ``NULL`` in the middle.
   Lexer will inevitably stop when it sees ``NULL``.
-  It's a common practice to use ``re2c:yyfill:enable = 0;``
-  in cases when input character set is restricted and one special
-  character can be chosen to indicate the end of input.
-  **But do make sure that the sentinel character is not allowed in the middle of a rule!**
+  Note that we make no assumptions about the input, it may contain any characters.
+  **But do make sure that the sentinel character is not allowed in the middle of a rule.**
 
-* ``YYMARKER`` (line 6) is needed because rules overlap:
+* ``YYMARKER`` (line 5) is needed because rules overlap:
   it backups input position of the longest successful match.
   Say, we have overlapping rules ``"a"`` and ``"abc"`` and input string ``"abd"``:
   by the time ``"a"`` matches there's still a chance to match ``"abc"``,
@@ -44,7 +52,7 @@ Generate, compile and run:
     $ g++ -o example example.cc
     $ ./example 0 12345678901234567890 0xAbcDEf 0x00 007 0B0 0b110101010 0x 0b ? ""
     oct: 0
-    dec: 1234567890
+    dec: 12345678901234567890
     hex: 0xAbcDEf
     hex: 0x00
     oct: 007
@@ -55,31 +63,32 @@ Generate, compile and run:
     err: ?
     err: 
 
+
 .. _Recognizing strings: the need for YYMAXFILL:
 
 Recognizing strings: the need for YYMAXFILL
 -------------------------------------------
 
 This example is about recognizing strings.
-Our strings are very simple: they are single-quoted and may contain any character in range ``[0 - 0xFF]``, except sinle quotes ``'``.
-Yet this time (unlike the previous example, `Recognizing integers: the sentinel method`_)
-we cannot use ``NULL`` or any other character as a sentinel:
-input strings like ``'aha\0ha'\0`` are perfectly valid,
-but incorrect input like ``'aha\0`` is also possible and shouldn't crash lexer.
-
-By default re2c generates explicit checks for the end of input,
-so we must simply omit ``re2c:yyfill:enable = 0;`` configuration.
-A naive approach is to check on each character (before advancing input position), but it's very slow.
+Strings (in generic sense) are different from other kinds of lexemes: they can contain *arbitrary* characters.
+It makes them a way more difficult to lex: unlike the previous example (`Recognizing integers: the sentinel method`_),
+we cannot use sentinel character to stop at the end of input.
+Suppose, for example, that our strings may be single or double-quoted
+and may contain any character in range ``[0 - 0xFF]`` except quotes of the appropriate type.
+This time we cannot use ``NULL`` as a sentinel: input strings like ``"aha\0ha"`` are perfectly valid,
+but ill-formed strings like ``"aha\0`` are also possible and shouldn't crash lexer.
+Any other character cannot be used for the same reason
+(including quotes: each type of strings can contain quotes of the opposite type).
+
+By default re2c-generated lexers use the following approach to check for the end of input:
+they assume that ``YYLIMIT`` is a pointer to the end of input and check by simply comparing ``YYCURSOR`` and ``YYLIMIT``.
+The obvious way is to check on each input character (before advancing to the next character), but it's very slow.
 Instead, re2c inserts checks only at certain points in the generated program.
-Each check ensures that there is enough input to proceed until the next checkpoint.
-If the check fails, lexer calls ``YYFILL``:
+Each check ensures that there is enough input to proceed until the next check.
+If the check fails, lexer calls ``YYFILL(n)``, which can either supply at least ``n`` characters or stop:
 
     ``if ((YYLIMIT - YYCURSOR) < n) YYFILL(n);``
 
-``YYLIMIT`` must point at the end of input (so that ``YYLIMIT[-1]`` is the last input character).
-``YYFILL(n)`` can either supply at least ``n`` more input characters or stop
-(see example `Arbitrary large input and YYFILL`_ for details about ``YYFILL`` implementation).
-
 For those interested in the internal re2c algorithm used to determine checkpoints,
 here is a quote from the original paper
 `"RE2C: a more versatile scanner generator" <1994_bumbulis_cowan_re2c_a_more_versatile_scanner_generator.pdf>`_
@@ -106,13 +115,20 @@ The length of padding depends on the maximal argument to ``YYFILL``
 Notes:
 
 * ``/*!max:re2c*/`` (line 4) tells re2c to generate ``#define YYMAXFILL n``.
+
 * Input string is padded with ``YYMAXFILL`` characters ``'a'`` (line 15).
-  Sequence of ``'a'`` does not form a valid lexeme suffix (but padding like ``"\0`` would cause false match on incorrect input like ``"aha``).
-* ``YYLIMIT`` points to the end of padding (line 26).
-* ``YYFILL`` returns an error (line 30): if the input was correct, lexer should have stopped
+  Sequence of ``'a'`` does not form a valid lexeme or lexeme suffix
+  (but padding with quotes would cause false match on ill-formed input like ``"aha``).
+
+* ``YYLIMIT`` points at the end of padding (line 26).
+
+* ``YYFILL`` returns an error (line 29): if the input was correct, lexer should have stopped
   at the beginning of padding.
-* Lexer should consume *all* input characters (line 37).
-* We have to use ``re2c:define:YYFILL:naked = 1;`` (line 31)
+
+* If the rule matched (line 36), we ensure that lexer consumed *all* input characters
+  and stopped exactly at the beginning of padding.
+
+* We have to use ``re2c:define:YYFILL:naked = 1;`` (line 30)
   in order to suppress passing parameter to ``YYFILL``.
   (It was an unfortunate idea to make ``YYFILL`` a call expression by default:
   ``YYFILL`` has to stop the lexer eventually, that's why it has to be a macro and not a function.
@@ -124,6 +140,14 @@ Generate, compile and run:
 
     $ re2c -o example.cc 02_recognizing_strings.re
     $ g++ -o example example.cc
+    $ ./example '"a momentary"' '""' '"lap"se"' '"of' '"' '"rea""son"' ''
+    str: "a momentary"
+    str: ""
+    err: "lap"se"
+    err: "of
+    err: "
+    err: "rea""son"
+    err: 
     $ ./example "'a momentary'" "''" "'lap'se'" "'of" "'" "'rea''son'" ""
     str: 'a momentary'
     str: ''
@@ -133,23 +157,26 @@ Generate, compile and run:
     err: 'rea''son'
     err: 
 
+
 .. _Arbitrary large input and YYFILL:
 
 Arbitrary large input and YYFILL
 --------------------------------
 
-Suppose that for some reason the whole input cannot be mapped in memory:
-either it is very big or its size cannot be determined in advance.
-The usual thing to do in such case is to allocate a buffer
-and process input in chunks that fit into buffer.
-For that we will need ``YYFILL``.
+In this example we make the following assumptions:
 
-See the previous example (`Recognizing strings: the need for YYMAXFILL`_)
+1. Input cannot be mapped in memory at once (it is very large, its size cannot be determined in advance, etc.).
+
+The usual thing to do in such case is to allocate a buffer and lex input in chunks that fit into buffer.
+re2c allows us to refill buffer using ``YYFILL``: see example `Recognizing strings: the need for YYMAXFILL`_
 for details about program points and conditions that trigger ``YYFILL`` invocation.
+Currently re2c provides no way to combine ``YYFILL`` with the sentinel method:
+we have to enable ``YYLIMIT``-based checks for the end of input and pad input with ``YYMAXFILL`` fake characters.
+This may be changed in later versions of re2c.
+
 The idea of ``YYFILL`` is fairly simple: lexer is stuck upon the fact that
 ``(YYLIMIT - YYCURSOR) < n`` and ``YYFILL`` must either invert this condition or stop lexing.
 Disaster will happen if ``YYFILL`` fails to provide at least ``n`` characters, yet resumes lexing.
-
 Technically ``YYFILL`` must somehow "extend" input for at least ``n`` characters:
 after ``YYFILL`` all input pointers must point to exact same characters,
 except ``YYLIMIT``: it must be advanced at least ``n`` positions.
@@ -196,17 +223,16 @@ Which part of input can be discarded?
 The answer is, all input up to the leftmost meaningful pointer.
 Intuitively it seems that it must be ``YYMARKER``: it backups input position of the latest match,
 so it's always less than or equal to ``YYCURSOR``.
-However, ``YYMARKER`` usage depends on the input:
+However, ``YYMARKER`` is not always used and even when it is, its usage depends on the input:
 not all control flow paths in lexer ever initialize it.
 Thus for some inputs ``YYMARKER`` is meaningless
 and should be used with care.
-
 In practice input rarely consists of one giant lexeme: it is usually a sequence of small lexemes.
 In that case lexer runs in a loop and it is convenient to have a special "lexeme start" pointer.
 It can be used as boundary in ``YYFILL``.
 
-Our example program will lex a file with strings (probably separated by whitespaces)
-and count the total number of strings:
+Our example program reads ``stdin`` in chunks of 16 bytes (in real word buffer size is usually ~4Kb)
+and tries to lex numbers separated by newlines.
 
 `[03_arbitrary_large_input.re] <examples/03_arbitrary_large_input.re>`_
 
@@ -216,26 +242,23 @@ and count the total number of strings:
 
 Notes:
 
-* ``YYMAXFILL`` bytes at the end of buffer are reserved for padding (line 9).
+* ``YYMAXFILL`` bytes at the end of buffer are reserved for padding.
   This memory is unused most of the time, but ``YYMAXFILL`` is usually negligably small compared to buffer size.
 
-* There is only one successsful way out (line 71):
-  lexer must recognize a standalone end of input lexeme ``'a'`` right at the beginning of padding.
-  Unlike the sentinel method, ``'a'`` in the middle of a rule is not recognized as end of input.
-  Standalone ``'a'`` in input (not in padding) is a lexing error.
-  ``YYFILL`` failure is also a lexing error: if the input was correct,
-  lexer should have stopped at the beginning of padding.
+* There is only one successsful way out (line 60): lexer must recognize a standalone
+  "end of input" lexeme (``NULL``) exactly at the beginning of padding.
+  ``YYFILL`` failure is an error: if the input was correct, lexer should have already stopped.
 
 * ``YYFILL`` may fail for two reasons:
-  either there is no more input (line 30),
-  or lexeme is too big: it occupies the whole buffer and nothing can be discarded (line 35).
-  We treat both cases as error, but a real-world program might handle them differently
-  (e.g. resize buffer in the second case).
+  either there is no more input (line 23),
+  or lexeme is too long: it occupies the whole buffer and nothing can be discarded (line 27).
+  We treat both cases in the same way (as error), but a real-world program might handle them differently
+  (resize buffer, cut long lexeme in two, etc.).
 
-* ``@@`` in ``YYFILL`` definition (line 63) is a formal parameter: re2c substitutes it with the actual argument to ``YYFILL``.
+* ``@@`` in ``YYFILL`` definition (line 52) is a formal parameter: re2c substitutes it with the actual argument to ``YYFILL``.
 
-* There is a special ``tok`` pointer: it points at the beginning of lexeme (line 57)
-  and serves as a boundary in ``YYFILL`` (line 33).
+* There is a special ``tok`` pointer: it points at the beginning of lexeme (line 47)
+  and serves as a boundary in ``YYFILL``.
 
 Generate, compile and run:
 
@@ -243,14 +266,23 @@ Generate, compile and run:
 
     $ re2c -o example.cc 03_arbitrary_large_input.re
     $ g++ -o example example.cc
-    $ cat > input.txt
-    "a""momentary"
-     "lap\"se"      "o\\f"
-    
-        "rea""son"
-     ""
-    $ ./example input.txt
-    glorious 7 strings!
+    $ ./example
+    0
+    11
+    222
+    3333
+    44444
+    555555
+    6666666
+    77777777
+    888888888
+    9999999999
+    glorious 10 numbers!
+    $ seq 123456789 | ./example
+    glorious 123456789 numbers!
+    $ seq 123456789 | wc -l
+    123456789
+
 
 .. _Parsing integers (multiple re2c blocks):
 
@@ -398,12 +430,12 @@ and are much harder to implement.
 Notes:
 
 * Reuse mode is enabled with ``-r`` option.
-* In reuse mode re2c expects a single ``/*!rules:re2c ... */`` block (line 49)
-  followed by multiple ``/*!use:re2c ... */`` blocks (lines 140, 157 and 176).
+* In reuse mode re2c expects a single ``/*!rules:re2c ... */`` block
+  followed by multiple ``/*!use:re2c ... */`` blocks.
   All blocks can have their own configurations, definitions and rules.
 * Encoding can be enabled either with command-line option or with configuration.
 * Each encoding needs an appropriate code unit type (``YYCTYPE``).
-* We use conditions to switch between numeric and normal modes (lines 76 and 104).
+* We use conditions to switch between numeric and normal modes.
 
 Generate, compile and run:
 
index 73642b7e67a3471a30ed1ce35ae4f77089af5916..8a388f8473e654518426327fc7b596643f7df8f4 100644 (file)
@@ -1,8 +1,7 @@
 #include <stdio.h>
 
-static const char *lex(const char *input)
+static const char *lex(const char *YYCURSOR)
 {
-    const char *YYCURSOR = input;
     const char *YYMARKER;
     /*!re2c
         re2c:define:YYCTYPE = char;
@@ -11,7 +10,7 @@ static const char *lex(const char *input)
         end = "\x00";
         bin = '0b' [01]+;
         oct = "0" [0-7]*;
-        dec = [1-9][0-9];
+        dec = [1-9][0-9]*;
         hex = '0x' [0-9a-fA-F]+;
 
         *       { return "err"; }
index 764543a57a25023080abfcb7c44dd928d10d9ce6..ec9d68305f337adf68f4c1c09107885507d4f713 100644 (file)
@@ -8,7 +8,7 @@ struct input_t {
     char *str;
 
     input_t(const char *s)
-        : len(strlen(s) + 1)
+        : len(strlen(s))
         , str(new char[len + YYMAXFILL])
     {
         memcpy(str, s, len);
@@ -20,21 +20,20 @@ struct input_t {
     }
 };
 
-static const char *lex(const input_t & input)
+static bool lex(const input_t & input)
 {
     const char *YYCURSOR = input.str;
     const char *const YYLIMIT = input.str + input.len + YYMAXFILL;
-    const char *YYMARKER;
     /*!re2c
         re2c:define:YYCTYPE = char;
-        re2c:define:YYFILL = "return \"err\";";
+        re2c:define:YYFILL = "return false;";
         re2c:define:YYFILL:naked = 1;
 
-        end = "\x00";
-        str = "'" [^']* "'";
+        sstr = "'"  [^']* "'";
+        dstr = "\"" [^"]* "\"";
 
-        *       { return "err"; }
-        str end { return YYLIMIT - YYCURSOR == YYMAXFILL ? "str" : "err"; }
+        *             { return false; }
+        (sstr | dstr) { return YYLIMIT - YYCURSOR == YYMAXFILL; }
     */
 }
 
@@ -42,7 +41,7 @@ int main(int argc, char **argv)
 {
     for (int i = 1; i < argc; ++i) {
         input_t arg(argv[i]);
-        printf("%s: %s\n", lex(arg), arg.str);
+        printf("%s: %s\n", lex(arg) ? "str" : "err", argv[i]);
     }
     return 0;
 }
index c3d8b562001de2d848b98712ae3f6a6e2ee75249..506ca41f827b4859e96740ce1a7541e531406dd8 100644 (file)
-#include <limits.h>
 #include <stdio.h>
 #include <string.h>
 
 /*!max:re2c*/
-static const size_t SIZE = 1024;
+static const size_t SIZE = 16;
 
 struct input_t {
     char buf[SIZE + YYMAXFILL];
     char *lim;
     char *cur;
-    char *mar;
     char *tok;
     bool eof;
 
-    FILE *const file;
-
-    input_t(FILE *f)
+    input_t()
         : buf()
         , lim(buf + SIZE)
         , cur(lim)
-        , mar(lim)
         , tok(lim)
         , eof(false)
-        , file(f)
     {}
     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;
-        mar -= free;
         tok -= free;
-        lim += fread(lim, 1, free, file);
+        lim += fread(lim, 1, free, stdin);
         if (lim < buf + SIZE) {
             eof = true;
-            memset(lim, 'a', YYMAXFILL);
+            memset(lim, 0, YYMAXFILL);
             lim += YYMAXFILL;
         }
         return true;
     }
 };
 
-static int lex(input_t & input)
+static bool lex(input_t & in, unsigned int &count)
 {
-    int count = 0;
-    for (;;) {
-        input.tok = input.cur;
+    for (count = 0;;) {
+        in.tok = in.cur;
         /*!re2c
             re2c:define:YYCTYPE = char;
-            re2c:define:YYCURSOR = input.cur;
-            re2c:define:YYMARKER = input.mar;
-            re2c:define:YYLIMIT = input.lim;
-            re2c:define:YYFILL = "if (!input.fill(@@)) return -1;";
+            re2c:define:YYCURSOR = in.cur;
+            re2c:define:YYLIMIT = in.lim;
+            re2c:define:YYFILL = "if (!in.fill(@@)) return false;";
             re2c:define:YYFILL:naked = 1;
 
-            end = "a";
-            str = "\"" ([^"\\] | "\\" ["\\])* "\"";
-            wsp = [ \t\n\r]+;
+            end = "\x00";
+            wsp = [\n]+;
+            num = [0-9]+;
 
-            *   { return -1; }
-            end { return (input.lim - input.tok == YYMAXFILL) ? count : -1; }
+            *   { return false; }
+            end { return YYMAXFILL == in.lim - in.tok; }
             wsp { continue; }
-            str {
-                if (count == INT_MAX) {
-                    return -2;
-                }
-                ++count;
-                continue;
-            }
+            num { ++count; continue; }
         */
     }
 }
 
-int main(int argc, char **argv)
+int main()
 {
-    if (argc != 2) {
-        printf ("usage: ./example <filename>\n");
-        return 1;
-    }
-
-    FILE *file = fopen(argv[1], "rb");
-    if (!file) {
-        printf("error: cannot open file: %s\n", argv[1]);
-        return 1;
-    }
-
-    input_t input(file);
-    const int count = lex(input);
-    switch (count) {
-        case -1: printf("lexing error\n"); break;
-        case -2: printf("lines overflow\n"); break;
-        default: printf("glorious %d strings!\n", count); break;
+    input_t in;
+    unsigned int count;
+    if (lex(in, count)) {
+        printf("glorious %u numbers!\n", count);
+    } else {
+        printf("error\n");
     }
 
-    fclose(file);
     return 0;
 }
index 9e7a9b8714443c9adb6fb22552652fbe88babbd1..5fa429eb046c28733086ce96a4d9ff9924f73eb5 100644 (file)
@@ -1,24 +1,19 @@
 #include <ctype.h>
 #include <stdio.h>
-#include <string.h>
-
-/*!max:re2c*/
 
 template<typename char_t>
 struct input_t {
     size_t len;
     char_t *str;
 
-    input_t(FILE *f)
-        : len(0)
-        , str(new char_t[len + YYMAXFILL])
+    input_t(FILE *f) : len(0), str(NULL)
     {
         fseek(f, 0, SEEK_END);
         len = ftell(f) / sizeof(char_t);
         fseek(f, 0, SEEK_SET);
-        str = new char_t[len + YYMAXFILL];
+        str = new char_t[len + 1];
         fread(str, sizeof(char_t), len, f);
-        memset(str + len, 0, YYMAXFILL);
+        str[len] = 0;
     }
     ~input_t()
     {
@@ -47,6 +42,7 @@ struct out_t {
 };
 
 /*!rules:re2c
+    re2c:yyfill:enable = 0;
 
     // letters
     l = "\u2830";
@@ -71,7 +67,7 @@ struct out_t {
     fcp = "\u2820"; fsp = "\u2800" | "\x20"; fnl = "\n" | "\n\r";
 
     <*> *      { out.err(); return; }
-    <*> "\x00" { if (YYLIMIT - YYCURSOR != YYMAXFILL - 1) out.err(); return; }
+    <*> "\x00" { if (YYCURSOR != in.str + in.len + 1) out.err(); return; }
 
     <*> l :=> l
     <l> la { out.prt('a'); goto yyc_l; }
@@ -130,17 +126,14 @@ struct out_t {
 
 /*!types:re2c*/
 
-static void lex_utf8(const iutf8_t & input)
+static void lex_utf8(const iutf8_t & in)
 {
-    const unsigned char *YYCURSOR = input.str;
-    const unsigned char *const YYLIMIT = input.str + input.len + YYMAXFILL;
+    const unsigned char *YYCURSOR = in.str;
     const unsigned char *YYMARKER;
     int c = yycl;
     out_t out;
     /*!use:re2c
         re2c:define:YYCTYPE = "unsigned char";
-        re2c:define:YYFILL = "{ out.err(); return; }";
-        re2c:define:YYFILL:naked = 1;
         re2c:define:YYGETCONDITION = "c";
         re2c:define:YYGETCONDITION:naked = 1;
         re2c:define:YYSETCONDITION = "c = @@;";
@@ -148,16 +141,13 @@ static void lex_utf8(const iutf8_t & input)
     */
 }
 
-static void lex_utf16(const iutf16_t & input)
+static void lex_utf16(const iutf16_t & in)
 {
-    const unsigned short *YYCURSOR = input.str;
-    const unsigned short *const YYLIMIT = input.str + input.len + YYMAXFILL;
+    const unsigned short *YYCURSOR = in.str;
     int c = yycl;
     out_t out;
     /*!use:re2c
         re2c:define:YYCTYPE = "unsigned int";
-        re2c:define:YYFILL = "{ out.err(); return; }";
-        re2c:define:YYFILL:naked = 1;
         re2c:define:YYGETCONDITION = "c";
         re2c:define:YYGETCONDITION:naked = 1;
         re2c:define:YYSETCONDITION = "c = @@;";
@@ -167,16 +157,13 @@ static void lex_utf16(const iutf16_t & input)
     */
 }
 
-static void lex_utf32(const iutf32_t & input)
+static void lex_utf32(const iutf32_t & in)
 {
-    const unsigned int *YYCURSOR = input.str;
-    const unsigned int *const YYLIMIT = input.str + input.len + YYMAXFILL;
+    const unsigned int *YYCURSOR = in.str;
     int c = yycl;
     out_t out;
     /*!use:re2c
         re2c:define:YYCTYPE = "unsigned int";
-        re2c:define:YYFILL = "{ out.err(); return; }";
-        re2c:define:YYFILL:naked = 1;
         re2c:define:YYGETCONDITION = "c";
         re2c:define:YYGETCONDITION:naked = 1;
         re2c:define:YYSETCONDITION = "c = @@;";
@@ -186,16 +173,13 @@ static void lex_utf32(const iutf32_t & input)
     */
 }
 
-static void lex_ucs2(const iucs2_t & input)
+static void lex_ucs2(const iucs2_t & in)
 {
-    const unsigned short *YYCURSOR = input.str;
-    const unsigned short *const YYLIMIT = input.str + input.len + YYMAXFILL;
+    const unsigned short *YYCURSOR = in.str;
     int c = yycl;
     out_t out;
     /*!use:re2c
         re2c:define:YYCTYPE = "unsigned int";
-        re2c:define:YYFILL = "{ out.err(); return; }";
-        re2c:define:YYFILL:naked = 1;
         re2c:define:YYGETCONDITION = "c";
         re2c:define:YYGETCONDITION:naked = 1;
         re2c:define:YYSETCONDITION = "c = @@;";
@@ -212,32 +196,32 @@ int main()
     f = fopen("06_braille.utf8.txt", "rb");
     if (f) {
         printf("utf8:\n");
-        iutf8_t input(f);
-        lex_utf8(input);
+        iutf8_t in(f);
+        lex_utf8(in);
         fclose(f);
     }
 
     f = fopen("06_braille.utf16.txt", "rb");
     if (f) {
         printf("utf16:\n");
-        iutf16_t input(f);
-        lex_utf16(input);
+        iutf16_t in(f);
+        lex_utf16(in);
         fclose(f);
     }
 
     f = fopen("06_braille.utf32.txt", "rb");
     if (f) {
         printf("utf32:\n");
-        iutf32_t input(f);
-        lex_utf32(input);
+        iutf32_t in(f);
+        lex_utf32(in);
         fclose(f);
     }
 
     f = fopen("06_braille.ucs2.txt", "rb");
     if (f) {
         printf("ucs2:\n");
-        iucs2_t input(f);
-        lex_ucs2(input);
+        iucs2_t in(f);
+        lex_ucs2(in);
         fclose(f);
     }
 
index 6b79f019e1082d734f99287980026e03f5519d17..36a685ba761710366ad5b65ccbaae999bb45b646 100644 (file)
@@ -30,12 +30,10 @@ struct input_t {
         if (eof) {
             return false;
         }
-
         const size_t free = tok - buf;
         if (free < need) {
             return false;
         }
-
         memmove(buf, tok, lim - tok);
         lim -= free;
         cur -= free;