From 6ef3cb51a4d49d24fe94f255643f8932b1545f4f Mon Sep 17 00:00:00 2001
From: Niels <niels.lohmann@gmail.com>
Date: Sat, 14 Feb 2015 17:34:06 +0100
Subject: [PATCH] some reorganization

---
 src/json.hpp      | 1207 ++++++++++++++++++++++-----------------------
 src/json.hpp.re2c |  130 ++---
 test/unit.cpp     |   18 +
 3 files changed, 687 insertions(+), 668 deletions(-)

diff --git a/src/json.hpp b/src/json.hpp
index 9ac648c0..077f605e 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -2516,722 +2516,724 @@ class basic_json
             // pointer for backtracking information
             const char* m_marker = nullptr;
 
-            // remember the begin of the token
-            m_start = m_cursor;
-
-
+            while (true)
             {
-                char yych;
-                unsigned int yyaccept = 0;
-                static const unsigned char yybm[] =
-                {
-                    0,  64,  64,  64,  64,  64,  64,  64,
-                    64,  96,  96,  64,  64,  96,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    96,  64,   0,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    192, 192, 192, 192, 192, 192, 192, 192,
-                    192, 192,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,   0,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                    64,  64,  64,  64,  64,  64,  64,  64,
-                };
+                // remember the begin of the token
+                m_start = m_cursor;
+
 
-                yych = *m_cursor;
-                if (yych <= '9')
                 {
-                    if (yych <= ' ')
+                    char yych;
+                    unsigned int yyaccept = 0;
+                    static const unsigned char yybm[] =
                     {
-                        if (yych <= '\n')
+                        0,  64,  64,  64,  64,  64,  64,  64,
+                        64,  96,  96,  64,  64,  96,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        96,  64,   0,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        192, 192, 192, 192, 192, 192, 192, 192,
+                        192, 192,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,   0,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                        64,  64,  64,  64,  64,  64,  64,  64,
+                    };
+
+                    yych = *m_cursor;
+                    if (yych <= '9')
+                    {
+                        if (yych <= ' ')
                         {
-                            if (yych <= 0x00)
+                            if (yych <= '\n')
                             {
-                                goto json_parser_27;
+                                if (yych <= 0x00)
+                                {
+                                    goto basic_json_parser_27;
+                                }
+                                if (yych <= 0x08)
+                                {
+                                    goto basic_json_parser_29;
+                                }
+                                if (yych >= '\n')
+                                {
+                                    goto basic_json_parser_4;
+                                }
                             }
-                            if (yych <= 0x08)
+                            else
                             {
-                                goto json_parser_29;
+                                if (yych == '\r')
+                                {
+                                    goto basic_json_parser_2;
+                                }
+                                if (yych <= 0x1F)
+                                {
+                                    goto basic_json_parser_29;
+                                }
                             }
-                            if (yych <= '\t')
-                            {
-                                goto json_parser_3;
-                            }
-                            goto json_parser_4;
                         }
                         else
                         {
-                            if (yych == '\r')
+                            if (yych <= ',')
                             {
-                                goto json_parser_3;
+                                if (yych == '"')
+                                {
+                                    goto basic_json_parser_26;
+                                }
+                                if (yych <= '+')
+                                {
+                                    goto basic_json_parser_29;
+                                }
+                                goto basic_json_parser_14;
                             }
-                            if (yych <= 0x1F)
+                            else
                             {
-                                goto json_parser_29;
+                                if (yych <= '-')
+                                {
+                                    goto basic_json_parser_22;
+                                }
+                                if (yych <= '/')
+                                {
+                                    goto basic_json_parser_29;
+                                }
+                                if (yych <= '0')
+                                {
+                                    goto basic_json_parser_23;
+                                }
+                                goto basic_json_parser_25;
                             }
-                            goto json_parser_3;
                         }
                     }
                     else
                     {
-                        if (yych <= ',')
+                        if (yych <= 'm')
+                        {
+                            if (yych <= '\\')
+                            {
+                                if (yych <= ':')
+                                {
+                                    goto basic_json_parser_16;
+                                }
+                                if (yych == '[')
+                                {
+                                    goto basic_json_parser_6;
+                                }
+                                goto basic_json_parser_29;
+                            }
+                            else
+                            {
+                                if (yych <= ']')
+                                {
+                                    goto basic_json_parser_8;
+                                }
+                                if (yych == 'f')
+                                {
+                                    goto basic_json_parser_21;
+                                }
+                                goto basic_json_parser_29;
+                            }
+                        }
+                        else
+                        {
+                            if (yych <= 'z')
+                            {
+                                if (yych <= 'n')
+                                {
+                                    goto basic_json_parser_18;
+                                }
+                                if (yych == 't')
+                                {
+                                    goto basic_json_parser_20;
+                                }
+                                goto basic_json_parser_29;
+                            }
+                            else
+                            {
+                                if (yych <= '{')
+                                {
+                                    goto basic_json_parser_10;
+                                }
+                                if (yych == '}')
+                                {
+                                    goto basic_json_parser_12;
+                                }
+                                goto basic_json_parser_29;
+                            }
+                        }
+                    }
+basic_json_parser_2:
+                    ++m_cursor;
+                    yych = *m_cursor;
+                    goto basic_json_parser_5;
+basic_json_parser_3:
+                    {
+                        continue;
+                    }
+basic_json_parser_4:
+                    ++m_cursor;
+                    yych = *m_cursor;
+basic_json_parser_5:
+                    if (yybm[0 + yych] & 32)
+                    {
+                        goto basic_json_parser_4;
+                    }
+                    goto basic_json_parser_3;
+basic_json_parser_6:
+                    ++m_cursor;
+                    {
+                        return token_type::begin_array;
+                    }
+basic_json_parser_8:
+                    ++m_cursor;
+                    {
+                        return token_type::end_array;
+                    }
+basic_json_parser_10:
+                    ++m_cursor;
+                    {
+                        return token_type::begin_object;
+                    }
+basic_json_parser_12:
+                    ++m_cursor;
+                    {
+                        return token_type::end_object;
+                    }
+basic_json_parser_14:
+                    ++m_cursor;
+                    {
+                        return token_type::value_separator;
+                    }
+basic_json_parser_16:
+                    ++m_cursor;
+                    {
+                        return token_type::name_separator;
+                    }
+basic_json_parser_18:
+                    yyaccept = 0;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych == 'u')
+                    {
+                        goto basic_json_parser_59;
+                    }
+basic_json_parser_19:
+                    {
+                        return token_type::parse_error;
+                    }
+basic_json_parser_20:
+                    yyaccept = 0;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych == 'r')
+                    {
+                        goto basic_json_parser_55;
+                    }
+                    goto basic_json_parser_19;
+basic_json_parser_21:
+                    yyaccept = 0;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych == 'a')
+                    {
+                        goto basic_json_parser_50;
+                    }
+                    goto basic_json_parser_19;
+basic_json_parser_22:
+                    yych = *++m_cursor;
+                    if (yych <= '/')
+                    {
+                        goto basic_json_parser_19;
+                    }
+                    if (yych <= '0')
+                    {
+                        goto basic_json_parser_49;
+                    }
+                    if (yych <= '9')
+                    {
+                        goto basic_json_parser_40;
+                    }
+                    goto basic_json_parser_19;
+basic_json_parser_23:
+                    yyaccept = 1;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych <= 'D')
+                    {
+                        if (yych == '.')
+                        {
+                            goto basic_json_parser_42;
+                        }
+                    }
+                    else
+                    {
+                        if (yych <= 'E')
+                        {
+                            goto basic_json_parser_43;
+                        }
+                        if (yych == 'e')
+                        {
+                            goto basic_json_parser_43;
+                        }
+                    }
+basic_json_parser_24:
+                    {
+                        return token_type::value_number;
+                    }
+basic_json_parser_25:
+                    yyaccept = 1;
+                    yych = *(m_marker = ++m_cursor);
+                    goto basic_json_parser_41;
+basic_json_parser_26:
+                    yyaccept = 0;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych <= 0x00)
+                    {
+                        goto basic_json_parser_19;
+                    }
+                    goto basic_json_parser_31;
+basic_json_parser_27:
+                    ++m_cursor;
+                    {
+                        return token_type::end_of_input;
+                    }
+basic_json_parser_29:
+                    yych = *++m_cursor;
+                    goto basic_json_parser_19;
+basic_json_parser_30:
+                    ++m_cursor;
+                    yych = *m_cursor;
+basic_json_parser_31:
+                    if (yybm[0 + yych] & 64)
+                    {
+                        goto basic_json_parser_30;
+                    }
+                    if (yych <= 0x00)
+                    {
+                        goto basic_json_parser_32;
+                    }
+                    if (yych <= '"')
+                    {
+                        goto basic_json_parser_34;
+                    }
+                    goto basic_json_parser_33;
+basic_json_parser_32:
+                    m_cursor = m_marker;
+                    if (yyaccept == 0)
+                    {
+                        goto basic_json_parser_19;
+                    }
+                    else
+                    {
+                        goto basic_json_parser_24;
+                    }
+basic_json_parser_33:
+                    ++m_cursor;
+                    yych = *m_cursor;
+                    if (yych <= 'e')
+                    {
+                        if (yych <= '/')
                         {
                             if (yych == '"')
                             {
-                                goto json_parser_26;
+                                goto basic_json_parser_30;
                             }
-                            if (yych <= '+')
+                            if (yych <= '.')
                             {
-                                goto json_parser_29;
+                                goto basic_json_parser_32;
                             }
-                            goto json_parser_14;
+                            goto basic_json_parser_30;
                         }
                         else
                         {
-                            if (yych <= '-')
+                            if (yych <= '\\')
                             {
-                                goto json_parser_22;
+                                if (yych <= '[')
+                                {
+                                    goto basic_json_parser_32;
+                                }
+                                goto basic_json_parser_30;
                             }
-                            if (yych <= '/')
+                            else
                             {
-                                goto json_parser_29;
+                                if (yych == 'b')
+                                {
+                                    goto basic_json_parser_30;
+                                }
+                                goto basic_json_parser_32;
                             }
-                            if (yych <= '0')
-                            {
-                                goto json_parser_23;
-                            }
-                            goto json_parser_25;
-                        }
-                    }
-                }
-                else
-                {
-                    if (yych <= 'm')
-                    {
-                        if (yych <= '\\')
-                        {
-                            if (yych <= ':')
-                            {
-                                goto json_parser_16;
-                            }
-                            if (yych == '[')
-                            {
-                                goto json_parser_6;
-                            }
-                            goto json_parser_29;
-                        }
-                        else
-                        {
-                            if (yych <= ']')
-                            {
-                                goto json_parser_8;
-                            }
-                            if (yych == 'f')
-                            {
-                                goto json_parser_21;
-                            }
-                            goto json_parser_29;
                         }
                     }
                     else
                     {
-                        if (yych <= 'z')
+                        if (yych <= 'q')
                         {
-                            if (yych <= 'n')
+                            if (yych <= 'f')
                             {
-                                goto json_parser_18;
+                                goto basic_json_parser_30;
                             }
-                            if (yych == 't')
+                            if (yych == 'n')
                             {
-                                goto json_parser_20;
+                                goto basic_json_parser_30;
                             }
-                            goto json_parser_29;
+                            goto basic_json_parser_32;
                         }
                         else
                         {
-                            if (yych <= '{')
+                            if (yych <= 's')
                             {
-                                goto json_parser_10;
+                                if (yych <= 'r')
+                                {
+                                    goto basic_json_parser_30;
+                                }
+                                goto basic_json_parser_32;
                             }
-                            if (yych == '}')
+                            else
                             {
-                                goto json_parser_12;
+                                if (yych <= 't')
+                                {
+                                    goto basic_json_parser_30;
+                                }
+                                if (yych <= 'u')
+                                {
+                                    goto basic_json_parser_36;
+                                }
+                                goto basic_json_parser_32;
                             }
-                            goto json_parser_29;
                         }
                     }
-                }
-json_parser_2:
-                {
-                    return scan();
-                }
-json_parser_3:
-                yych = *++m_cursor;
-                goto json_parser_5;
-json_parser_4:
-                ++m_cursor;
-                yych = *m_cursor;
-json_parser_5:
-                if (yybm[0 + yych] & 32)
-                {
-                    goto json_parser_4;
-                }
-                goto json_parser_2;
-json_parser_6:
-                ++m_cursor;
-                {
-                    return token_type::begin_array;
-                }
-json_parser_8:
-                ++m_cursor;
-                {
-                    return token_type::end_array;
-                }
-json_parser_10:
-                ++m_cursor;
-                {
-                    return token_type::begin_object;
-                }
-json_parser_12:
-                ++m_cursor;
-                {
-                    return token_type::end_object;
-                }
-json_parser_14:
-                ++m_cursor;
-                {
-                    return token_type::value_separator;
-                }
-json_parser_16:
-                ++m_cursor;
-                {
-                    return token_type::name_separator;
-                }
-json_parser_18:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych == 'u')
-                {
-                    goto json_parser_59;
-                }
-json_parser_19:
-                {
-                    return token_type::parse_error;
-                }
-json_parser_20:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych == 'r')
-                {
-                    goto json_parser_55;
-                }
-                goto json_parser_19;
-json_parser_21:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych == 'a')
-                {
-                    goto json_parser_50;
-                }
-                goto json_parser_19;
-json_parser_22:
-                yych = *++m_cursor;
-                if (yych <= '/')
-                {
-                    goto json_parser_19;
-                }
-                if (yych <= '0')
-                {
-                    goto json_parser_49;
-                }
-                if (yych <= '9')
-                {
-                    goto json_parser_40;
-                }
-                goto json_parser_19;
-json_parser_23:
-                yyaccept = 1;
-                yych = *(m_marker = ++m_cursor);
-                if (yych <= 'D')
-                {
-                    if (yych == '.')
+basic_json_parser_34:
+                    ++m_cursor;
                     {
-                        goto json_parser_42;
+                        return token_type::value_string;
                     }
-                }
-                else
-                {
-                    if (yych <= 'E')
+basic_json_parser_36:
+                    ++m_cursor;
+                    yych = *m_cursor;
+                    if (yych <= '@')
                     {
-                        goto json_parser_43;
-                    }
-                    if (yych == 'e')
-                    {
-                        goto json_parser_43;
-                    }
-                }
-json_parser_24:
-                {
-                    return token_type::value_number;
-                }
-json_parser_25:
-                yyaccept = 1;
-                yych = *(m_marker = ++m_cursor);
-                goto json_parser_41;
-json_parser_26:
-                yyaccept = 0;
-                yych = *(m_marker = ++m_cursor);
-                if (yych <= 0x00)
-                {
-                    goto json_parser_19;
-                }
-                goto json_parser_31;
-json_parser_27:
-                ++m_cursor;
-                {
-                    return token_type::end_of_input;
-                }
-json_parser_29:
-                yych = *++m_cursor;
-                goto json_parser_19;
-json_parser_30:
-                ++m_cursor;
-                yych = *m_cursor;
-json_parser_31:
-                if (yybm[0 + yych] & 64)
-                {
-                    goto json_parser_30;
-                }
-                if (yych <= 0x00)
-                {
-                    goto json_parser_32;
-                }
-                if (yych <= '"')
-                {
-                    goto json_parser_34;
-                }
-                goto json_parser_33;
-json_parser_32:
-                m_cursor = m_marker;
-                if (yyaccept == 0)
-                {
-                    goto json_parser_19;
-                }
-                else
-                {
-                    goto json_parser_24;
-                }
-json_parser_33:
-                ++m_cursor;
-                yych = *m_cursor;
-                if (yych <= 'e')
-                {
-                    if (yych <= '/')
-                    {
-                        if (yych == '"')
+                        if (yych <= '/')
                         {
-                            goto json_parser_30;
+                            goto basic_json_parser_32;
                         }
-                        if (yych <= '.')
+                        if (yych >= ':')
                         {
-                            goto json_parser_32;
+                            goto basic_json_parser_32;
                         }
-                        goto json_parser_30;
                     }
                     else
                     {
-                        if (yych <= '\\')
+                        if (yych <= 'F')
                         {
-                            if (yych <= '[')
-                            {
-                                goto json_parser_32;
-                            }
-                            goto json_parser_30;
+                            goto basic_json_parser_37;
                         }
-                        else
+                        if (yych <= '`')
                         {
-                            if (yych == 'b')
-                            {
-                                goto json_parser_30;
-                            }
-                            goto json_parser_32;
+                            goto basic_json_parser_32;
+                        }
+                        if (yych >= 'g')
+                        {
+                            goto basic_json_parser_32;
                         }
                     }
-                }
-                else
-                {
-                    if (yych <= 'q')
+basic_json_parser_37:
+                    ++m_cursor;
+                    yych = *m_cursor;
+                    if (yych <= '@')
                     {
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_32;
+                        }
+                        if (yych >= ':')
+                        {
+                            goto basic_json_parser_32;
+                        }
+                    }
+                    else
+                    {
+                        if (yych <= 'F')
+                        {
+                            goto basic_json_parser_38;
+                        }
+                        if (yych <= '`')
+                        {
+                            goto basic_json_parser_32;
+                        }
+                        if (yych >= 'g')
+                        {
+                            goto basic_json_parser_32;
+                        }
+                    }
+basic_json_parser_38:
+                    ++m_cursor;
+                    yych = *m_cursor;
+                    if (yych <= '@')
+                    {
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_32;
+                        }
+                        if (yych >= ':')
+                        {
+                            goto basic_json_parser_32;
+                        }
+                    }
+                    else
+                    {
+                        if (yych <= 'F')
+                        {
+                            goto basic_json_parser_39;
+                        }
+                        if (yych <= '`')
+                        {
+                            goto basic_json_parser_32;
+                        }
+                        if (yych >= 'g')
+                        {
+                            goto basic_json_parser_32;
+                        }
+                    }
+basic_json_parser_39:
+                    ++m_cursor;
+                    yych = *m_cursor;
+                    if (yych <= '@')
+                    {
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_32;
+                        }
+                        if (yych <= '9')
+                        {
+                            goto basic_json_parser_30;
+                        }
+                        goto basic_json_parser_32;
+                    }
+                    else
+                    {
+                        if (yych <= 'F')
+                        {
+                            goto basic_json_parser_30;
+                        }
+                        if (yych <= '`')
+                        {
+                            goto basic_json_parser_32;
+                        }
                         if (yych <= 'f')
                         {
-                            goto json_parser_30;
+                            goto basic_json_parser_30;
                         }
-                        if (yych == 'n')
+                        goto basic_json_parser_32;
+                    }
+basic_json_parser_40:
+                    yyaccept = 1;
+                    m_marker = ++m_cursor;
+                    yych = *m_cursor;
+basic_json_parser_41:
+                    if (yybm[0 + yych] & 128)
+                    {
+                        goto basic_json_parser_40;
+                    }
+                    if (yych <= 'D')
+                    {
+                        if (yych != '.')
                         {
-                            goto json_parser_30;
+                            goto basic_json_parser_24;
                         }
-                        goto json_parser_32;
                     }
                     else
                     {
-                        if (yych <= 's')
+                        if (yych <= 'E')
                         {
-                            if (yych <= 'r')
-                            {
-                                goto json_parser_30;
-                            }
-                            goto json_parser_32;
+                            goto basic_json_parser_43;
                         }
-                        else
+                        if (yych == 'e')
                         {
-                            if (yych <= 't')
-                            {
-                                goto json_parser_30;
-                            }
-                            if (yych <= 'u')
-                            {
-                                goto json_parser_36;
-                            }
-                            goto json_parser_32;
+                            goto basic_json_parser_43;
+                        }
+                        goto basic_json_parser_24;
+                    }
+basic_json_parser_42:
+                    yych = *++m_cursor;
+                    if (yych <= '/')
+                    {
+                        goto basic_json_parser_32;
+                    }
+                    if (yych <= '9')
+                    {
+                        goto basic_json_parser_47;
+                    }
+                    goto basic_json_parser_32;
+basic_json_parser_43:
+                    yych = *++m_cursor;
+                    if (yych <= ',')
+                    {
+                        if (yych != '+')
+                        {
+                            goto basic_json_parser_32;
                         }
                     }
-                }
-json_parser_34:
-                ++m_cursor;
-                {
-                    return token_type::value_string;
-                }
-json_parser_36:
-                ++m_cursor;
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
+                    else
+                    {
+                        if (yych <= '-')
+                        {
+                            goto basic_json_parser_44;
+                        }
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_32;
+                        }
+                        if (yych <= '9')
+                        {
+                            goto basic_json_parser_45;
+                        }
+                        goto basic_json_parser_32;
+                    }
+basic_json_parser_44:
+                    yych = *++m_cursor;
                     if (yych <= '/')
                     {
-                        goto json_parser_32;
+                        goto basic_json_parser_32;
                     }
                     if (yych >= ':')
                     {
-                        goto json_parser_32;
+                        goto basic_json_parser_32;
                     }
-                }
-                else
-                {
-                    if (yych <= 'F')
-                    {
-                        goto json_parser_37;
-                    }
-                    if (yych <= '`')
-                    {
-                        goto json_parser_32;
-                    }
-                    if (yych >= 'g')
-                    {
-                        goto json_parser_32;
-                    }
-                }
-json_parser_37:
-                ++m_cursor;
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
+basic_json_parser_45:
+                    ++m_cursor;
+                    yych = *m_cursor;
                     if (yych <= '/')
                     {
-                        goto json_parser_32;
-                    }
-                    if (yych >= ':')
-                    {
-                        goto json_parser_32;
-                    }
-                }
-                else
-                {
-                    if (yych <= 'F')
-                    {
-                        goto json_parser_38;
-                    }
-                    if (yych <= '`')
-                    {
-                        goto json_parser_32;
-                    }
-                    if (yych >= 'g')
-                    {
-                        goto json_parser_32;
-                    }
-                }
-json_parser_38:
-                ++m_cursor;
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
-                    if (yych <= '/')
-                    {
-                        goto json_parser_32;
-                    }
-                    if (yych >= ':')
-                    {
-                        goto json_parser_32;
-                    }
-                }
-                else
-                {
-                    if (yych <= 'F')
-                    {
-                        goto json_parser_39;
-                    }
-                    if (yych <= '`')
-                    {
-                        goto json_parser_32;
-                    }
-                    if (yych >= 'g')
-                    {
-                        goto json_parser_32;
-                    }
-                }
-json_parser_39:
-                ++m_cursor;
-                yych = *m_cursor;
-                if (yych <= '@')
-                {
-                    if (yych <= '/')
-                    {
-                        goto json_parser_32;
+                        goto basic_json_parser_24;
                     }
                     if (yych <= '9')
                     {
-                        goto json_parser_30;
+                        goto basic_json_parser_45;
                     }
-                    goto json_parser_32;
-                }
-                else
-                {
-                    if (yych <= 'F')
+                    goto basic_json_parser_24;
+basic_json_parser_47:
+                    yyaccept = 1;
+                    m_marker = ++m_cursor;
+                    yych = *m_cursor;
+                    if (yych <= 'D')
                     {
-                        goto json_parser_30;
+                        if (yych <= '/')
+                        {
+                            goto basic_json_parser_24;
+                        }
+                        if (yych <= '9')
+                        {
+                            goto basic_json_parser_47;
+                        }
+                        goto basic_json_parser_24;
                     }
-                    if (yych <= '`')
+                    else
                     {
-                        goto json_parser_32;
+                        if (yych <= 'E')
+                        {
+                            goto basic_json_parser_43;
+                        }
+                        if (yych == 'e')
+                        {
+                            goto basic_json_parser_43;
+                        }
+                        goto basic_json_parser_24;
                     }
-                    if (yych <= 'f')
+basic_json_parser_49:
+                    yyaccept = 1;
+                    yych = *(m_marker = ++m_cursor);
+                    if (yych <= 'D')
                     {
-                        goto json_parser_30;
+                        if (yych == '.')
+                        {
+                            goto basic_json_parser_42;
+                        }
+                        goto basic_json_parser_24;
                     }
-                    goto json_parser_32;
-                }
-json_parser_40:
-                yyaccept = 1;
-                m_marker = ++m_cursor;
-                yych = *m_cursor;
-json_parser_41:
-                if (yybm[0 + yych] & 128)
-                {
-                    goto json_parser_40;
-                }
-                if (yych <= 'D')
-                {
-                    if (yych != '.')
+                    else
                     {
-                        goto json_parser_24;
+                        if (yych <= 'E')
+                        {
+                            goto basic_json_parser_43;
+                        }
+                        if (yych == 'e')
+                        {
+                            goto basic_json_parser_43;
+                        }
+                        goto basic_json_parser_24;
                     }
-                }
-                else
-                {
-                    if (yych <= 'E')
+basic_json_parser_50:
+                    yych = *++m_cursor;
+                    if (yych != 'l')
                     {
-                        goto json_parser_43;
+                        goto basic_json_parser_32;
                     }
-                    if (yych == 'e')
+                    yych = *++m_cursor;
+                    if (yych != 's')
                     {
-                        goto json_parser_43;
+                        goto basic_json_parser_32;
                     }
-                    goto json_parser_24;
-                }
-json_parser_42:
-                yych = *++m_cursor;
-                if (yych <= '/')
-                {
-                    goto json_parser_32;
-                }
-                if (yych <= '9')
-                {
-                    goto json_parser_47;
-                }
-                goto json_parser_32;
-json_parser_43:
-                yych = *++m_cursor;
-                if (yych <= ',')
-                {
-                    if (yych != '+')
+                    yych = *++m_cursor;
+                    if (yych != 'e')
                     {
-                        goto json_parser_32;
+                        goto basic_json_parser_32;
                     }
-                }
-                else
-                {
-                    if (yych <= '-')
+                    ++m_cursor;
                     {
-                        goto json_parser_44;
+                        return token_type::literal_false;
                     }
-                    if (yych <= '/')
+basic_json_parser_55:
+                    yych = *++m_cursor;
+                    if (yych != 'u')
                     {
-                        goto json_parser_32;
+                        goto basic_json_parser_32;
                     }
-                    if (yych <= '9')
+                    yych = *++m_cursor;
+                    if (yych != 'e')
                     {
-                        goto json_parser_45;
+                        goto basic_json_parser_32;
                     }
-                    goto json_parser_32;
-                }
-json_parser_44:
-                yych = *++m_cursor;
-                if (yych <= '/')
-                {
-                    goto json_parser_32;
-                }
-                if (yych >= ':')
-                {
-                    goto json_parser_32;
-                }
-json_parser_45:
-                ++m_cursor;
-                yych = *m_cursor;
-                if (yych <= '/')
-                {
-                    goto json_parser_24;
-                }
-                if (yych <= '9')
-                {
-                    goto json_parser_45;
-                }
-                goto json_parser_24;
-json_parser_47:
-                yyaccept = 1;
-                m_marker = ++m_cursor;
-                yych = *m_cursor;
-                if (yych <= 'D')
-                {
-                    if (yych <= '/')
+                    ++m_cursor;
                     {
-                        goto json_parser_24;
+                        return token_type::literal_true;
                     }
-                    if (yych <= '9')
+basic_json_parser_59:
+                    yych = *++m_cursor;
+                    if (yych != 'l')
                     {
-                        goto json_parser_47;
+                        goto basic_json_parser_32;
                     }
-                    goto json_parser_24;
-                }
-                else
-                {
-                    if (yych <= 'E')
+                    yych = *++m_cursor;
+                    if (yych != 'l')
                     {
-                        goto json_parser_43;
+                        goto basic_json_parser_32;
                     }
-                    if (yych == 'e')
+                    ++m_cursor;
                     {
-                        goto json_parser_43;
+                        return token_type::literal_null;
                     }
-                    goto json_parser_24;
                 }
-json_parser_49:
-                yyaccept = 1;
-                yych = *(m_marker = ++m_cursor);
-                if (yych <= 'D')
-                {
-                    if (yych == '.')
-                    {
-                        goto json_parser_42;
-                    }
-                    goto json_parser_24;
-                }
-                else
-                {
-                    if (yych <= 'E')
-                    {
-                        goto json_parser_43;
-                    }
-                    if (yych == 'e')
-                    {
-                        goto json_parser_43;
-                    }
-                    goto json_parser_24;
-                }
-json_parser_50:
-                yych = *++m_cursor;
-                if (yych != 'l')
-                {
-                    goto json_parser_32;
-                }
-                yych = *++m_cursor;
-                if (yych != 's')
-                {
-                    goto json_parser_32;
-                }
-                yych = *++m_cursor;
-                if (yych != 'e')
-                {
-                    goto json_parser_32;
-                }
-                ++m_cursor;
-                {
-                    return token_type::literal_false;
-                }
-json_parser_55:
-                yych = *++m_cursor;
-                if (yych != 'u')
-                {
-                    goto json_parser_32;
-                }
-                yych = *++m_cursor;
-                if (yych != 'e')
-                {
-                    goto json_parser_32;
-                }
-                ++m_cursor;
-                {
-                    return token_type::literal_true;
-                }
-json_parser_59:
-                yych = *++m_cursor;
-                if (yych != 'l')
-                {
-                    goto json_parser_32;
-                }
-                yych = *++m_cursor;
-                if (yych != 'l')
-                {
-                    goto json_parser_32;
-                }
-                ++m_cursor;
-                {
-                    return token_type::literal_null;
-                }
-            }
 
+            }
         }
 
-        inline std::string get_string_value() const
+        inline std::string get_token() const
         {
             return std::string(m_start, static_cast<size_t>(m_cursor - m_start));
         }
@@ -3266,15 +3268,9 @@ json_parser_59:
             char* endptr;
             const auto float_val = std::strtod(reinterpret_cast<const char*>(m_start), &endptr);
 
-            // check if strtod read beyond the end of the lexem
-            if (endptr != m_cursor)
-            {
-                return NAN;
-            }
-            else
-            {
-                return float_val;
-            }
+            // return float_val if the whole number was translated and NAN
+            // otherwise
+            return (endptr == m_cursor) ? float_val : NAN;
         }
 
       private:
@@ -3441,10 +3437,12 @@ json_parser_59:
                 {
                     auto float_val = m_lexer.get_number();
 
+                    // NAN is returned if token could not be translated
+                    // completely
                     if (std::isnan(float_val))
                     {
                         throw std::invalid_argument(std::string("parse error - ") +
-                                                    m_lexer.get_string_value() + " is not a number");
+                                                    m_lexer.get_token() + " is not a number");
                     }
 
                     get_token();
@@ -3466,7 +3464,7 @@ json_parser_59:
                 default:
                 {
                     std::string error_msg = "parse error - unexpected \'";
-                    error_msg += m_lexer.get_string_value();
+                    error_msg += m_lexer.get_token();
                     error_msg += "\' (";
                     error_msg += lexer::token_type_name(last_token) + ")";
                     throw std::invalid_argument(error_msg);
@@ -3486,7 +3484,7 @@ json_parser_59:
             if (t != last_token)
             {
                 std::string error_msg = "parse error - unexpected \'";
-                error_msg += m_lexer.get_string_value();
+                error_msg += m_lexer.get_token();
                 error_msg += "\' (" + lexer::token_type_name(last_token);
                 error_msg += "); expected " + lexer::token_type_name(t);
                 throw std::invalid_argument(error_msg);
@@ -3498,6 +3496,7 @@ json_parser_59:
         std::string m_buffer;
         /// the type of the last read token
         typename lexer::token_type last_token = lexer::token_type::uninitialized;
+        /// the lexer
         lexer m_lexer;
     };
 };
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index f59985eb..3ac3a4c0 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -2516,68 +2516,73 @@ class basic_json
             // pointer for backtracking information
             const char* m_marker = nullptr;
 
-            // remember the begin of the token
-            m_start = m_cursor;
+            while (true)
+            {
+                // remember the begin of the token
+                m_start = m_cursor;
 
-            /*!re2c
-                re2c:define:YYCTYPE     = char;
-                re2c:define:YYCURSOR    = m_cursor;
-                re2c:define:YYLIMIT     = m_limit;
-                re2c:define:YYMARKER    = m_marker;
-                re2c:indent:string      = "    ";
-                re2c:indent:top         = 1;
-                re2c:labelprefix        = "json_parser_";
-                re2c:yyfill:enable      = 0;
+                /*!re2c
+                    re2c:define:YYCTYPE  = char;
+                    re2c:define:YYCURSOR = m_cursor;
+                    re2c:define:YYLIMIT  = m_limit;
+                    re2c:define:YYMARKER = m_marker;
+                    re2c:indent:string   = "    ";
+                    re2c:indent:top      = 1;
+                    re2c:labelprefix     = "basic_json_parser_";
+                    re2c:yyfill:enable   = 0;
 
-                // whitespace
-                ws = [ \t\n\r]*;
-                ws   { return scan(); }
+                    // whitespace
+                    ws = [ \t\n\r]+;
+                    ws   { 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
+                    "[" { 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; }
 
-                // literal names
-                "null"  { return token_type::literal_null; }
-                "true"  { return token_type::literal_true; }
-                "false" { return token_type::literal_false; }
+                    // literal names
+                    "null"  { return token_type::literal_null; }
+                    "true"  { return token_type::literal_true; }
+                    "false" { return token_type::literal_false; }
 
-                // 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        { return token_type::value_number; }
 
-                // string
-                quotation_mark = [\"];
-                escape         = [\\];
-                unescaped      = [^\"\\\000];
-                escaped        = escape ([\"\\/bfnrt] | [u][0-9a-fA-F]{4});
-                char           = unescaped | escaped;
-                string         = quotation_mark char* quotation_mark;
-                string         { return token_type::value_string; }
+                    // string
+                    quotation_mark  = [\"];
+                    escape          = [\\];
+                    unescaped       = [^\"\\\000];
+                    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; }
 
-                // end of file
-                '\000'         { return token_type::end_of_input; }
+                    // end of file
+                    '\000'         { return token_type::end_of_input; }
 
-                // anything else is an error
-                .              { return token_type::parse_error; }
-             */
+                    // anything else is an error
+                    .              { return token_type::parse_error; }
+                 */
+            }
         }
 
-        inline std::string get_string_value() const
+        inline std::string get_token() const
         {
             return std::string(m_start, static_cast<size_t>(m_cursor - m_start));
         }
@@ -2612,15 +2617,9 @@ class basic_json
             char* endptr;
             const auto float_val = std::strtod(reinterpret_cast<const char*>(m_start), &endptr);
 
-            // check if strtod read beyond the end of the lexem
-            if (endptr != m_cursor)
-            {
-                return NAN;
-            }
-            else
-            {
-                return float_val;
-            }
+            // return float_val if the whole number was translated and NAN
+            // otherwise
+            return (endptr == m_cursor) ? float_val : NAN;
         }
 
       private:
@@ -2787,10 +2786,12 @@ class basic_json
                 {
                     auto float_val = m_lexer.get_number();
 
+                    // NAN is returned if token could not be translated
+                    // completely
                     if (std::isnan(float_val))
                     {
                         throw std::invalid_argument(std::string("parse error - ") +
-                                                    m_lexer.get_string_value() + " is not a number");
+                                                    m_lexer.get_token() + " is not a number");
                     }
 
                     get_token();
@@ -2812,7 +2813,7 @@ class basic_json
                 default:
                 {
                     std::string error_msg = "parse error - unexpected \'";
-                    error_msg += m_lexer.get_string_value();
+                    error_msg += m_lexer.get_token();
                     error_msg += "\' (";
                     error_msg += lexer::token_type_name(last_token) + ")";
                     throw std::invalid_argument(error_msg);
@@ -2832,7 +2833,7 @@ class basic_json
             if (t != last_token)
             {
                 std::string error_msg = "parse error - unexpected \'";
-                error_msg += m_lexer.get_string_value();
+                error_msg += m_lexer.get_token();
                 error_msg += "\' (" + lexer::token_type_name(last_token);
                 error_msg += "); expected " + lexer::token_type_name(t);
                 throw std::invalid_argument(error_msg);
@@ -2844,6 +2845,7 @@ class basic_json
         std::string m_buffer;
         /// the type of the last read token
         typename lexer::token_type last_token = lexer::token_type::uninitialized;
+        /// the lexer
         lexer m_lexer;
     };
 };
diff --git a/test/unit.cpp b/test/unit.cpp
index 57501554..e85cf1f0 100644
--- a/test/unit.cpp
+++ b/test/unit.cpp
@@ -3630,6 +3630,8 @@ TEST_CASE("capacity")
             {
                 CHECK(std::distance(j.begin(), j.end()) == j.size());
                 CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
+                CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
+                CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
             }
         }
 
@@ -3648,6 +3650,8 @@ TEST_CASE("capacity")
             {
                 CHECK(std::distance(j.begin(), j.end()) == j.size());
                 CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
+                CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
+                CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
             }
         }
 
@@ -3668,6 +3672,8 @@ TEST_CASE("capacity")
                 {
                     CHECK(std::distance(j.begin(), j.end()) == j.size());
                     CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
+                    CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
+                    CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
                 }
             }
 
@@ -3686,6 +3692,8 @@ TEST_CASE("capacity")
                 {
                     CHECK(std::distance(j.begin(), j.end()) == j.size());
                     CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
+                    CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
+                    CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
                 }
             }
         }
@@ -3707,6 +3715,8 @@ TEST_CASE("capacity")
                 {
                     CHECK(std::distance(j.begin(), j.end()) == j.size());
                     CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
+                    CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
+                    CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
                 }
             }
 
@@ -3725,6 +3735,8 @@ TEST_CASE("capacity")
                 {
                     CHECK(std::distance(j.begin(), j.end()) == j.size());
                     CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
+                    CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
+                    CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
                 }
             }
         }
@@ -3744,6 +3756,8 @@ TEST_CASE("capacity")
             {
                 CHECK(std::distance(j.begin(), j.end()) == j.size());
                 CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
+                CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
+                CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
             }
         }
 
@@ -3762,6 +3776,8 @@ TEST_CASE("capacity")
             {
                 CHECK(std::distance(j.begin(), j.end()) == j.size());
                 CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
+                CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
+                CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
             }
         }
 
@@ -3780,6 +3796,8 @@ TEST_CASE("capacity")
             {
                 CHECK(std::distance(j.begin(), j.end()) == j.size());
                 CHECK(std::distance(j_const.begin(), j_const.end()) == j_const.size());
+                CHECK(std::distance(j.rbegin(), j.rend()) == j.size());
+                CHECK(std::distance(j_const.crbegin(), j_const.crend()) == j_const.size());
             }
         }
     }