avoid recursion in the scanner
diff --git a/src/json.hpp b/src/json.hpp
index 44c867c..1311080 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -7393,400 +7393,402 @@
         */
         token_type scan() noexcept
         {
-            // pointer for backtracking information
-            m_marker = nullptr;
-
-            // remember the begin of the token
-            m_start = m_cursor;
-            assert(m_start != nullptr);
-
-
+            while (true)
             {
-                lexer_char_t yych;
-                unsigned int yyaccept = 0;
-                static const unsigned char yybm[] =
+                // pointer for backtracking information
+                m_marker = nullptr;
+
+                // remember the begin of the token
+                m_start = m_cursor;
+                assert(m_start != nullptr);
+
+
                 {
-                    0,   0,   0,   0,   0,   0,   0,   0,
-                    0,  32,  32,   0,   0,  32,   0,   0,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    160, 128,   0, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    192, 192, 192, 192, 192, 192, 192, 192,
-                    192, 192, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128,   0, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                    128, 128, 128, 128, 128, 128, 128, 128,
-                };
-                if ((m_limit - m_cursor) < 5)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yybm[0 + yych] & 32)
-                {
-                    goto basic_json_parser_6;
-                }
-                if (yych <= '\\')
-                {
-                    if (yych <= '-')
+                    lexer_char_t yych;
+                    unsigned int yyaccept = 0;
+                    static const unsigned char yybm[] =
                     {
-                        if (yych <= '"')
+                        0,   0,   0,   0,   0,   0,   0,   0,
+                        0,  32,  32,   0,   0,  32,   0,   0,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        160, 128,   0, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        192, 192, 192, 192, 192, 192, 192, 192,
+                        192, 192, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128,   0, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                        128, 128, 128, 128, 128, 128, 128, 128,
+                    };
+                    if ((m_limit - m_cursor) < 5)
+                    {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yybm[0 + yych] & 32)
+                    {
+                        goto basic_json_parser_6;
+                    }
+                    if (yych <= '\\')
+                    {
+                        if (yych <= '-')
                         {
-                            if (yych <= 0x00)
+                            if (yych <= '"')
                             {
-                                goto basic_json_parser_2;
+                                if (yych <= 0x00)
+                                {
+                                    goto basic_json_parser_2;
+                                }
+                                if (yych <= '!')
+                                {
+                                    goto basic_json_parser_4;
+                                }
+                                goto basic_json_parser_9;
                             }
-                            if (yych <= '!')
+                            else
                             {
-                                goto basic_json_parser_4;
+                                if (yych <= '+')
+                                {
+                                    goto basic_json_parser_4;
+                                }
+                                if (yych <= ',')
+                                {
+                                    goto basic_json_parser_10;
+                                }
+                                goto basic_json_parser_12;
                             }
-                            goto basic_json_parser_9;
                         }
                         else
                         {
-                            if (yych <= '+')
+                            if (yych <= '9')
                             {
+                                if (yych <= '/')
+                                {
+                                    goto basic_json_parser_4;
+                                }
+                                if (yych <= '0')
+                                {
+                                    goto basic_json_parser_13;
+                                }
+                                goto basic_json_parser_15;
+                            }
+                            else
+                            {
+                                if (yych <= ':')
+                                {
+                                    goto basic_json_parser_17;
+                                }
+                                if (yych == '[')
+                                {
+                                    goto basic_json_parser_19;
+                                }
                                 goto basic_json_parser_4;
                             }
-                            if (yych <= ',')
-                            {
-                                goto basic_json_parser_10;
-                            }
-                            goto basic_json_parser_12;
                         }
                     }
                     else
                     {
-                        if (yych <= '9')
+                        if (yych <= 't')
                         {
-                            if (yych <= '/')
+                            if (yych <= 'f')
                             {
-                                goto basic_json_parser_4;
+                                if (yych <= ']')
+                                {
+                                    goto basic_json_parser_21;
+                                }
+                                if (yych <= 'e')
+                                {
+                                    goto basic_json_parser_4;
+                                }
+                                goto basic_json_parser_23;
                             }
-                            if (yych <= '0')
+                            else
                             {
-                                goto basic_json_parser_13;
+                                if (yych == 'n')
+                                {
+                                    goto basic_json_parser_24;
+                                }
+                                if (yych <= 's')
+                                {
+                                    goto basic_json_parser_4;
+                                }
+                                goto basic_json_parser_25;
                             }
-                            goto basic_json_parser_15;
                         }
                         else
                         {
-                            if (yych <= ':')
+                            if (yych <= '|')
                             {
-                                goto basic_json_parser_17;
-                            }
-                            if (yych == '[')
-                            {
-                                goto basic_json_parser_19;
-                            }
-                            goto basic_json_parser_4;
-                        }
-                    }
-                }
-                else
-                {
-                    if (yych <= 't')
-                    {
-                        if (yych <= 'f')
-                        {
-                            if (yych <= ']')
-                            {
-                                goto basic_json_parser_21;
-                            }
-                            if (yych <= 'e')
-                            {
+                                if (yych == '{')
+                                {
+                                    goto basic_json_parser_26;
+                                }
                                 goto basic_json_parser_4;
                             }
-                            goto basic_json_parser_23;
-                        }
-                        else
-                        {
-                            if (yych == 'n')
+                            else
                             {
-                                goto basic_json_parser_24;
-                            }
-                            if (yych <= 's')
-                            {
+                                if (yych <= '}')
+                                {
+                                    goto basic_json_parser_28;
+                                }
+                                if (yych == 0xEF)
+                                {
+                                    goto basic_json_parser_30;
+                                }
                                 goto basic_json_parser_4;
                             }
-                            goto basic_json_parser_25;
                         }
                     }
-                    else
-                    {
-                        if (yych <= '|')
-                        {
-                            if (yych == '{')
-                            {
-                                goto basic_json_parser_26;
-                            }
-                            goto basic_json_parser_4;
-                        }
-                        else
-                        {
-                            if (yych <= '}')
-                            {
-                                goto basic_json_parser_28;
-                            }
-                            if (yych == 0xEF)
-                            {
-                                goto basic_json_parser_30;
-                            }
-                            goto basic_json_parser_4;
-                        }
-                    }
-                }
 basic_json_parser_2:
-                ++m_cursor;
-                {
-                    return token_type::end_of_input;
-                }
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::end_of_input;
+                        break;
+                    }
 basic_json_parser_4:
-                ++m_cursor;
+                    ++m_cursor;
 basic_json_parser_5:
-                {
-                    return token_type::parse_error;
-                }
+                    {
+                        last_token_type = token_type::parse_error;
+                        break;
+                    }
 basic_json_parser_6:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yybm[0 + yych] & 32)
-                {
-                    goto basic_json_parser_6;
-                }
-                {
-                    return scan();
-                }
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
+                    {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yybm[0 + yych] & 32)
+                    {
+                        goto basic_json_parser_6;
+                    }
+                    {
+                        continue;
+                    }
 basic_json_parser_9:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych <= 0x0F)
-                {
-                    goto basic_json_parser_5;
-                }
-                goto basic_json_parser_32;
+                    yyaccept = 0;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych <= 0x0F)
+                    {
+                        goto basic_json_parser_5;
+                    }
+                    goto basic_json_parser_32;
 basic_json_parser_10:
-                ++m_cursor;
-                {
-                    return token_type::value_separator;
-                }
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::value_separator;
+                        break;
+                    }
 basic_json_parser_12:
-                yych = *++m_cursor;
-                if (yych <= '/')
-                {
-                    goto basic_json_parser_5;
-                }
-                if (yych <= '0')
-                {
-                    goto basic_json_parser_13;
-                }
-                if (yych <= '9')
-                {
-                    goto basic_json_parser_15;
-                }
-                goto basic_json_parser_5;
-basic_json_parser_13:
-                yyaccept = 1;
-                yych = *(m_marker = ++m_cursor);
-                if (yych <= 'D')
-                {
-                    if (yych == '.')
-                    {
-                        goto basic_json_parser_37;
-                    }
-                }
-                else
-                {
-                    if (yych <= 'E')
-                    {
-                        goto basic_json_parser_38;
-                    }
-                    if (yych == 'e')
-                    {
-                        goto basic_json_parser_38;
-                    }
-                }
-basic_json_parser_14:
-                {
-                    return token_type::value_number;
-                }
-basic_json_parser_15:
-                yyaccept = 1;
-                m_marker = ++m_cursor;
-                if ((m_limit - m_cursor) < 3)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yybm[0 + yych] & 64)
-                {
-                    goto basic_json_parser_15;
-                }
-                if (yych <= 'D')
-                {
-                    if (yych == '.')
-                    {
-                        goto basic_json_parser_37;
-                    }
-                    goto basic_json_parser_14;
-                }
-                else
-                {
-                    if (yych <= 'E')
-                    {
-                        goto basic_json_parser_38;
-                    }
-                    if (yych == 'e')
-                    {
-                        goto basic_json_parser_38;
-                    }
-                    goto basic_json_parser_14;
-                }
-basic_json_parser_17:
-                ++m_cursor;
-                {
-                    return token_type::name_separator;
-                }
-basic_json_parser_19:
-                ++m_cursor;
-                {
-                    return token_type::begin_array;
-                }
-basic_json_parser_21:
-                ++m_cursor;
-                {
-                    return token_type::end_array;
-                }
-basic_json_parser_23:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych == 'a')
-                {
-                    goto basic_json_parser_39;
-                }
-                goto basic_json_parser_5;
-basic_json_parser_24:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych == 'u')
-                {
-                    goto basic_json_parser_40;
-                }
-                goto basic_json_parser_5;
-basic_json_parser_25:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych == 'r')
-                {
-                    goto basic_json_parser_41;
-                }
-                goto basic_json_parser_5;
-basic_json_parser_26:
-                ++m_cursor;
-                {
-                    return token_type::begin_object;
-                }
-basic_json_parser_28:
-                ++m_cursor;
-                {
-                    return token_type::end_object;
-                }
-basic_json_parser_30:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych == 0xBB)
-                {
-                    goto basic_json_parser_42;
-                }
-                goto basic_json_parser_5;
-basic_json_parser_31:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-basic_json_parser_32:
-                if (yybm[0 + yych] & 128)
-                {
-                    goto basic_json_parser_31;
-                }
-                if (yych <= 0x0F)
-                {
-                    goto basic_json_parser_33;
-                }
-                if (yych <= '"')
-                {
-                    goto basic_json_parser_34;
-                }
-                goto basic_json_parser_36;
-basic_json_parser_33:
-                m_cursor = m_marker;
-                if (yyaccept == 0)
-                {
-                    goto basic_json_parser_5;
-                }
-                else
-                {
-                    goto basic_json_parser_14;
-                }
-basic_json_parser_34:
-                ++m_cursor;
-                {
-                    return token_type::value_string;
-                }
-basic_json_parser_36:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= 'e')
-                {
+                    yych = *++m_cursor;
                     if (yych <= '/')
                     {
-                        if (yych == '"')
+                        goto basic_json_parser_5;
+                    }
+                    if (yych <= '0')
+                    {
+                        goto basic_json_parser_13;
+                    }
+                    if (yych <= '9')
+                    {
+                        goto basic_json_parser_15;
+                    }
+                    goto basic_json_parser_5;
+basic_json_parser_13:
+                    yyaccept = 1;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych <= 'D')
+                    {
+                        if (yych == '.')
                         {
-                            goto basic_json_parser_31;
+                            goto basic_json_parser_37;
                         }
-                        if (yych <= '.')
-                        {
-                            goto basic_json_parser_33;
-                        }
-                        goto basic_json_parser_31;
                     }
                     else
                     {
-                        if (yych <= '\\')
+                        if (yych <= 'E')
                         {
-                            if (yych <= '[')
+                            goto basic_json_parser_38;
+                        }
+                        if (yych == 'e')
+                        {
+                            goto basic_json_parser_38;
+                        }
+                    }
+basic_json_parser_14:
+                    {
+                        last_token_type = token_type::value_number;
+                        break;
+                    }
+basic_json_parser_15:
+                    yyaccept = 1;
+                    m_marker = ++m_cursor;
+                    if ((m_limit - m_cursor) < 3)
+                    {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yybm[0 + yych] & 64)
+                    {
+                        goto basic_json_parser_15;
+                    }
+                    if (yych <= 'D')
+                    {
+                        if (yych == '.')
+                        {
+                            goto basic_json_parser_37;
+                        }
+                        goto basic_json_parser_14;
+                    }
+                    else
+                    {
+                        if (yych <= 'E')
+                        {
+                            goto basic_json_parser_38;
+                        }
+                        if (yych == 'e')
+                        {
+                            goto basic_json_parser_38;
+                        }
+                        goto basic_json_parser_14;
+                    }
+basic_json_parser_17:
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::name_separator;
+                        break;
+                    }
+basic_json_parser_19:
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::begin_array;
+                        break;
+                    }
+basic_json_parser_21:
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::end_array;
+                        break;
+                    }
+basic_json_parser_23:
+                    yyaccept = 0;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych == 'a')
+                    {
+                        goto basic_json_parser_39;
+                    }
+                    goto basic_json_parser_5;
+basic_json_parser_24:
+                    yyaccept = 0;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych == 'u')
+                    {
+                        goto basic_json_parser_40;
+                    }
+                    goto basic_json_parser_5;
+basic_json_parser_25:
+                    yyaccept = 0;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych == 'r')
+                    {
+                        goto basic_json_parser_41;
+                    }
+                    goto basic_json_parser_5;
+basic_json_parser_26:
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::begin_object;
+                        break;
+                    }
+basic_json_parser_28:
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::end_object;
+                        break;
+                    }
+basic_json_parser_30:
+                    yyaccept = 0;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych == 0xBB)
+                    {
+                        goto basic_json_parser_42;
+                    }
+                    goto basic_json_parser_5;
+basic_json_parser_31:
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
+                    {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+basic_json_parser_32:
+                    if (yybm[0 + yych] & 128)
+                    {
+                        goto basic_json_parser_31;
+                    }
+                    if (yych <= 0x0F)
+                    {
+                        goto basic_json_parser_33;
+                    }
+                    if (yych <= '"')
+                    {
+                        goto basic_json_parser_34;
+                    }
+                    goto basic_json_parser_36;
+basic_json_parser_33:
+                    m_cursor = m_marker;
+                    if (yyaccept == 0)
+                    {
+                        goto basic_json_parser_5;
+                    }
+                    else
+                    {
+                        goto basic_json_parser_14;
+                    }
+basic_json_parser_34:
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::value_string;
+                        break;
+                    }
+basic_json_parser_36:
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
+                    {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yych <= 'e')
+                    {
+                        if (yych <= '/')
+                        {
+                            if (yych == '"')
+                            {
+                                goto basic_json_parser_31;
+                            }
+                            if (yych <= '.')
                             {
                                 goto basic_json_parser_33;
                             }
@@ -7794,33 +7796,33 @@
                         }
                         else
                         {
-                            if (yych == 'b')
+                            if (yych <= '\\')
                             {
+                                if (yych <= '[')
+                                {
+                                    goto basic_json_parser_33;
+                                }
                                 goto basic_json_parser_31;
                             }
-                            goto basic_json_parser_33;
+                            else
+                            {
+                                if (yych == 'b')
+                                {
+                                    goto basic_json_parser_31;
+                                }
+                                goto basic_json_parser_33;
+                            }
                         }
                     }
-                }
-                else
-                {
-                    if (yych <= 'q')
-                    {
-                        if (yych <= 'f')
-                        {
-                            goto basic_json_parser_31;
-                        }
-                        if (yych == 'n')
-                        {
-                            goto basic_json_parser_31;
-                        }
-                        goto basic_json_parser_33;
-                    }
                     else
                     {
-                        if (yych <= 's')
+                        if (yych <= 'q')
                         {
-                            if (yych <= 'r')
+                            if (yych <= 'f')
+                            {
+                                goto basic_json_parser_31;
+                            }
+                            if (yych == 'n')
                             {
                                 goto basic_json_parser_31;
                             }
@@ -7828,331 +7830,347 @@
                         }
                         else
                         {
-                            if (yych <= 't')
+                            if (yych <= 's')
                             {
-                                goto basic_json_parser_31;
+                                if (yych <= 'r')
+                                {
+                                    goto basic_json_parser_31;
+                                }
+                                goto basic_json_parser_33;
                             }
-                            if (yych <= 'u')
+                            else
                             {
-                                goto basic_json_parser_43;
+                                if (yych <= 't')
+                                {
+                                    goto basic_json_parser_31;
+                                }
+                                if (yych <= 'u')
+                                {
+                                    goto basic_json_parser_43;
+                                }
+                                goto basic_json_parser_33;
                             }
-                            goto basic_json_parser_33;
                         }
                     }
-                }
 basic_json_parser_37:
-                yych = *++m_cursor;
-                if (yych <= '/')
-                {
+                    yych = *++m_cursor;
+                    if (yych <= '/')
+                    {
+                        goto basic_json_parser_33;
+                    }
+                    if (yych <= '9')
+                    {
+                        goto basic_json_parser_44;
+                    }
                     goto basic_json_parser_33;
-                }
-                if (yych <= '9')
-                {
-                    goto basic_json_parser_44;
-                }
-                goto basic_json_parser_33;
 basic_json_parser_38:
-                yych = *++m_cursor;
-                if (yych <= ',')
-                {
-                    if (yych == '+')
+                    yych = *++m_cursor;
+                    if (yych <= ',')
                     {
-                        goto basic_json_parser_46;
-                    }
-                    goto basic_json_parser_33;
-                }
-                else
-                {
-                    if (yych <= '-')
-                    {
-                        goto basic_json_parser_46;
-                    }
-                    if (yych <= '/')
-                    {
+                        if (yych == '+')
+                        {
+                            goto basic_json_parser_46;
+                        }
                         goto basic_json_parser_33;
                     }
-                    if (yych <= '9')
+                    else
                     {
-                        goto basic_json_parser_47;
+                        if (yych <= '-')
+                        {
+                            goto basic_json_parser_46;
+                        }
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= '9')
+                        {
+                            goto basic_json_parser_47;
+                        }
+                        goto basic_json_parser_33;
                     }
-                    goto basic_json_parser_33;
-                }
 basic_json_parser_39:
-                yych = *++m_cursor;
-                if (yych == 'l')
-                {
-                    goto basic_json_parser_49;
-                }
-                goto basic_json_parser_33;
+                    yych = *++m_cursor;
+                    if (yych == 'l')
+                    {
+                        goto basic_json_parser_49;
+                    }
+                    goto basic_json_parser_33;
 basic_json_parser_40:
-                yych = *++m_cursor;
-                if (yych == 'l')
-                {
-                    goto basic_json_parser_50;
-                }
-                goto basic_json_parser_33;
+                    yych = *++m_cursor;
+                    if (yych == 'l')
+                    {
+                        goto basic_json_parser_50;
+                    }
+                    goto basic_json_parser_33;
 basic_json_parser_41:
-                yych = *++m_cursor;
-                if (yych == 'u')
-                {
-                    goto basic_json_parser_51;
-                }
-                goto basic_json_parser_33;
+                    yych = *++m_cursor;
+                    if (yych == 'u')
+                    {
+                        goto basic_json_parser_51;
+                    }
+                    goto basic_json_parser_33;
 basic_json_parser_42:
-                yych = *++m_cursor;
-                if (yych == 0xBF)
-                {
-                    goto basic_json_parser_52;
-                }
-                goto basic_json_parser_33;
+                    yych = *++m_cursor;
+                    if (yych == 0xBF)
+                    {
+                        goto basic_json_parser_52;
+                    }
+                    goto basic_json_parser_33;
 basic_json_parser_43:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
+                    {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yych <= '@')
+                    {
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= '9')
+                        {
+                            goto basic_json_parser_54;
+                        }
+                        goto basic_json_parser_33;
+                    }
+                    else
+                    {
+                        if (yych <= 'F')
+                        {
+                            goto basic_json_parser_54;
+                        }
+                        if (yych <= '`')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= 'f')
+                        {
+                            goto basic_json_parser_54;
+                        }
+                        goto basic_json_parser_33;
+                    }
+basic_json_parser_44:
+                    yyaccept = 1;
+                    m_marker = ++m_cursor;
+                    if ((m_limit - m_cursor) < 3)
+                    {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yych <= 'D')
+                    {
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_14;
+                        }
+                        if (yych <= '9')
+                        {
+                            goto basic_json_parser_44;
+                        }
+                        goto basic_json_parser_14;
+                    }
+                    else
+                    {
+                        if (yych <= 'E')
+                        {
+                            goto basic_json_parser_38;
+                        }
+                        if (yych == 'e')
+                        {
+                            goto basic_json_parser_38;
+                        }
+                        goto basic_json_parser_14;
+                    }
+basic_json_parser_46:
+                    yych = *++m_cursor;
                     if (yych <= '/')
                     {
                         goto basic_json_parser_33;
                     }
-                    if (yych <= '9')
-                    {
-                        goto basic_json_parser_54;
-                    }
-                    goto basic_json_parser_33;
-                }
-                else
-                {
-                    if (yych <= 'F')
-                    {
-                        goto basic_json_parser_54;
-                    }
-                    if (yych <= '`')
+                    if (yych >= ':')
                     {
                         goto basic_json_parser_33;
                     }
-                    if (yych <= 'f')
+basic_json_parser_47:
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
                     {
-                        goto basic_json_parser_54;
+                        yyfill();    // LCOV_EXCL_LINE;
                     }
-                    goto basic_json_parser_33;
-                }
-basic_json_parser_44:
-                yyaccept = 1;
-                m_marker = ++m_cursor;
-                if ((m_limit - m_cursor) < 3)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= 'D')
-                {
+                    yych = *m_cursor;
                     if (yych <= '/')
                     {
                         goto basic_json_parser_14;
                     }
                     if (yych <= '9')
                     {
-                        goto basic_json_parser_44;
+                        goto basic_json_parser_47;
                     }
                     goto basic_json_parser_14;
-                }
-                else
-                {
-                    if (yych <= 'E')
+basic_json_parser_49:
+                    yych = *++m_cursor;
+                    if (yych == 's')
                     {
-                        goto basic_json_parser_38;
+                        goto basic_json_parser_55;
                     }
+                    goto basic_json_parser_33;
+basic_json_parser_50:
+                    yych = *++m_cursor;
+                    if (yych == 'l')
+                    {
+                        goto basic_json_parser_56;
+                    }
+                    goto basic_json_parser_33;
+basic_json_parser_51:
+                    yych = *++m_cursor;
                     if (yych == 'e')
                     {
-                        goto basic_json_parser_38;
+                        goto basic_json_parser_58;
                     }
-                    goto basic_json_parser_14;
-                }
-basic_json_parser_46:
-                yych = *++m_cursor;
-                if (yych <= '/')
-                {
                     goto basic_json_parser_33;
-                }
-                if (yych >= ':')
-                {
-                    goto basic_json_parser_33;
-                }
-basic_json_parser_47:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= '/')
-                {
-                    goto basic_json_parser_14;
-                }
-                if (yych <= '9')
-                {
-                    goto basic_json_parser_47;
-                }
-                goto basic_json_parser_14;
-basic_json_parser_49:
-                yych = *++m_cursor;
-                if (yych == 's')
-                {
-                    goto basic_json_parser_55;
-                }
-                goto basic_json_parser_33;
-basic_json_parser_50:
-                yych = *++m_cursor;
-                if (yych == 'l')
-                {
-                    goto basic_json_parser_56;
-                }
-                goto basic_json_parser_33;
-basic_json_parser_51:
-                yych = *++m_cursor;
-                if (yych == 'e')
-                {
-                    goto basic_json_parser_58;
-                }
-                goto basic_json_parser_33;
 basic_json_parser_52:
-                ++m_cursor;
-                {
-                    return scan();
-                }
+                    ++m_cursor;
+                    {
+                        continue;
+                    }
 basic_json_parser_54:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
-                    if (yych <= '/')
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
                     {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yych <= '@')
+                    {
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= '9')
+                        {
+                            goto basic_json_parser_60;
+                        }
                         goto basic_json_parser_33;
                     }
-                    if (yych <= '9')
+                    else
                     {
-                        goto basic_json_parser_60;
-                    }
-                    goto basic_json_parser_33;
-                }
-                else
-                {
-                    if (yych <= 'F')
-                    {
-                        goto basic_json_parser_60;
-                    }
-                    if (yych <= '`')
-                    {
+                        if (yych <= 'F')
+                        {
+                            goto basic_json_parser_60;
+                        }
+                        if (yych <= '`')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= 'f')
+                        {
+                            goto basic_json_parser_60;
+                        }
                         goto basic_json_parser_33;
                     }
-                    if (yych <= 'f')
-                    {
-                        goto basic_json_parser_60;
-                    }
-                    goto basic_json_parser_33;
-                }
 basic_json_parser_55:
-                yych = *++m_cursor;
-                if (yych == 'e')
-                {
-                    goto basic_json_parser_61;
-                }
-                goto basic_json_parser_33;
+                    yych = *++m_cursor;
+                    if (yych == 'e')
+                    {
+                        goto basic_json_parser_61;
+                    }
+                    goto basic_json_parser_33;
 basic_json_parser_56:
-                ++m_cursor;
-                {
-                    return token_type::literal_null;
-                }
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::literal_null;
+                        break;
+                    }
 basic_json_parser_58:
-                ++m_cursor;
-                {
-                    return token_type::literal_true;
-                }
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::literal_true;
+                        break;
+                    }
 basic_json_parser_60:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
-                    if (yych <= '/')
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
                     {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yych <= '@')
+                    {
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= '9')
+                        {
+                            goto basic_json_parser_63;
+                        }
                         goto basic_json_parser_33;
                     }
-                    if (yych <= '9')
+                    else
                     {
-                        goto basic_json_parser_63;
-                    }
-                    goto basic_json_parser_33;
-                }
-                else
-                {
-                    if (yych <= 'F')
-                    {
-                        goto basic_json_parser_63;
-                    }
-                    if (yych <= '`')
-                    {
+                        if (yych <= 'F')
+                        {
+                            goto basic_json_parser_63;
+                        }
+                        if (yych <= '`')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= 'f')
+                        {
+                            goto basic_json_parser_63;
+                        }
                         goto basic_json_parser_33;
                     }
-                    if (yych <= 'f')
-                    {
-                        goto basic_json_parser_63;
-                    }
-                    goto basic_json_parser_33;
-                }
 basic_json_parser_61:
-                ++m_cursor;
-                {
-                    return token_type::literal_false;
-                }
+                    ++m_cursor;
+                    {
+                        last_token_type = token_type::literal_false;
+                        break;
+                    }
 basic_json_parser_63:
-                ++m_cursor;
-                if (m_limit <= m_cursor)
-                {
-                    yyfill();    // LCOV_EXCL_LINE;
-                }
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
-                    if (yych <= '/')
+                    ++m_cursor;
+                    if (m_limit <= m_cursor)
                     {
+                        yyfill();    // LCOV_EXCL_LINE;
+                    }
+                    yych = *m_cursor;
+                    if (yych <= '@')
+                    {
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= '9')
+                        {
+                            goto basic_json_parser_31;
+                        }
                         goto basic_json_parser_33;
                     }
-                    if (yych <= '9')
+                    else
                     {
-                        goto basic_json_parser_31;
-                    }
-                    goto basic_json_parser_33;
-                }
-                else
-                {
-                    if (yych <= 'F')
-                    {
-                        goto basic_json_parser_31;
-                    }
-                    if (yych <= '`')
-                    {
+                        if (yych <= 'F')
+                        {
+                            goto basic_json_parser_31;
+                        }
+                        if (yych <= '`')
+                        {
+                            goto basic_json_parser_33;
+                        }
+                        if (yych <= 'f')
+                        {
+                            goto basic_json_parser_31;
+                        }
                         goto basic_json_parser_33;
                     }
-                    if (yych <= 'f')
-                    {
-                        goto basic_json_parser_31;
-                    }
-                    goto basic_json_parser_33;
                 }
+
             }
 
+            return last_token_type;
         }
 
         /// append data from the stream to the internal buffer
@@ -8500,6 +8518,8 @@
         const lexer_char_t* m_cursor = nullptr;
         /// pointer to the end of the buffer
         const lexer_char_t* m_limit = nullptr;
+        /// the last token type
+        token_type last_token_type = token_type::end_of_input;
     };
 
     /*!
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index dffce54..a65e41b 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -7393,76 +7393,81 @@
         */
         token_type scan() noexcept
         {
-            // pointer for backtracking information
-            m_marker = nullptr;
+            while (true)
+            {
+                // pointer for backtracking information
+                m_marker = nullptr;
 
-            // remember the begin of the token
-            m_start = m_cursor;
-            assert(m_start != nullptr);
+                // remember the begin of the token
+                m_start = m_cursor;
+                assert(m_start != nullptr);
 
-            /*!re2c
-                re2c:define:YYCTYPE   = lexer_char_t;
-                re2c:define:YYCURSOR  = m_cursor;
-                re2c:define:YYLIMIT   = m_limit;
-                re2c:define:YYMARKER  = m_marker;
-                re2c:define:YYFILL    = "yyfill(); // LCOV_EXCL_LINE";
-                re2c:yyfill:parameter = 0;
-                re2c:indent:string    = "    ";
-                re2c:indent:top       = 1;
-                re2c:labelprefix      = "basic_json_parser_";
+                /*!re2c
+                    re2c:define:YYCTYPE   = lexer_char_t;
+                    re2c:define:YYCURSOR  = m_cursor;
+                    re2c:define:YYLIMIT   = m_limit;
+                    re2c:define:YYMARKER  = m_marker;
+                    re2c:define:YYFILL    = "yyfill(); // LCOV_EXCL_LINE";
+                    re2c:yyfill:parameter = 0;
+                    re2c:indent:string    = "    ";
+                    re2c:indent:top       = 1;
+                    re2c:labelprefix      = "basic_json_parser_";
 
-                // ignore whitespace
-                ws = [ \t\n\r]+;
-                ws   { return scan(); }
+                    // ignore whitespace
+                    ws = [ \t\n\r]+;
+                    ws   { continue; }
 
-                // ignore byte-order-mark
-                bom = "\xEF\xBB\xBF";
-                bom   { return scan(); }
+                    // ignore byte-order-mark
+                    bom = "\xEF\xBB\xBF";
+                    bom   { continue; }
 
-                // structural characters
-                "[" { return token_type::begin_array; }
-                "]" { return token_type::end_array; }
-                "{" { return token_type::begin_object; }
-                "}" { return token_type::end_object; }
-                "," { return token_type::value_separator; }
-                ":" { return token_type::name_separator; }
+                    // structural characters
+                    "[" { last_token_type = token_type::begin_array; break; }
+                    "]" { last_token_type = token_type::end_array; break; }
+                    "{" { last_token_type = token_type::begin_object; break; }
+                    "}" { last_token_type = token_type::end_object; break; }
+                    "," { last_token_type = token_type::value_separator; break; }
+                    ":" { last_token_type = token_type::name_separator; break; }
 
-                // literal names
-                "null"  { return token_type::literal_null; }
-                "true"  { return token_type::literal_true; }
-                "false" { return token_type::literal_false; }
+                    // literal names
+                    "null"  { last_token_type = token_type::literal_null; break; }
+                    "true"  { last_token_type = token_type::literal_true; break; }
+                    "false" { last_token_type = token_type::literal_false; break; }
 
-                // number
-                decimal_point = [.];
-                digit         = [0-9];
-                digit_1_9     = [1-9];
-                e             = [eE];
-                minus         = [-];
-                plus          = [+];
-                zero          = [0];
-                exp           = e (minus|plus)? digit+;
-                frac          = decimal_point digit+;
-                int           = (zero|digit_1_9 digit*);
-                number        = minus? int frac? exp?;
-                number        { return token_type::value_number; }
+                    // number
+                    decimal_point = [.];
+                    digit         = [0-9];
+                    digit_1_9     = [1-9];
+                    e             = [eE];
+                    minus         = [-];
+                    plus          = [+];
+                    zero          = [0];
+                    exp           = e (minus|plus)? digit+;
+                    frac          = decimal_point digit+;
+                    int           = (zero|digit_1_9 digit*);
+                    number        = minus? int frac? exp?;
+                    number        { last_token_type = token_type::value_number; break; }
 
-                // string
-                quotation_mark  = ["];
-                escape          = [\\];
-                unescaped       = [^"\\\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F];
-                single_escaped  = ["\\/bfnrt];
-                unicode_escaped = [u][0-9a-fA-F]{4};
-                escaped         = escape (single_escaped | unicode_escaped);
-                char            = unescaped | escaped;
-                string          = quotation_mark char* quotation_mark;
-                string          { return token_type::value_string; }
+                    // string
+                    quotation_mark  = ["];
+                    escape          = [\\];
+                    unescaped       = [^"\\\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F];
+                    single_escaped  = ["\\/bfnrt];
+                    unicode_escaped = [u][0-9a-fA-F]{4};
+                    escaped         = escape (single_escaped | unicode_escaped);
+                    char            = unescaped | escaped;
+                    string          = quotation_mark char* quotation_mark;
+                    string          { last_token_type = token_type::value_string; break; }
 
-                // end of file
-                '\000'         { return token_type::end_of_input; }
+                    // end of file
+                    '\000'         { last_token_type = token_type::end_of_input; break; }
 
-                // anything else is an error
-                .              { return token_type::parse_error; }
-            */
+                    // anything else is an error
+                    .              { last_token_type = token_type::parse_error; break; }
+                */
+            }
+
+            return last_token_type;
         }
 
         /// append data from the stream to the internal buffer
@@ -7810,6 +7815,8 @@
         const lexer_char_t* m_cursor = nullptr;
         /// pointer to the end of the buffer
         const lexer_char_t* m_limit = nullptr;
+        /// the last token type
+        token_type last_token_type = token_type::end_of_input;
     };
 
     /*!