avoid recursion in the scanner

This commit is contained in:
Niels 2016-07-19 22:10:27 +02:00
parent b64367e2f7
commit 2478be807c
2 changed files with 705 additions and 678 deletions

File diff suppressed because it is too large Load diff

View file

@ -7393,76 +7393,81 @@ class basic_json
*/ */
token_type scan() noexcept token_type scan() noexcept
{ {
// pointer for backtracking information while (true)
m_marker = nullptr; {
// pointer for backtracking information
m_marker = nullptr;
// remember the begin of the token // remember the begin of the token
m_start = m_cursor; m_start = m_cursor;
assert(m_start != nullptr); assert(m_start != nullptr);
/*!re2c /*!re2c
re2c:define:YYCTYPE = lexer_char_t; re2c:define:YYCTYPE = lexer_char_t;
re2c:define:YYCURSOR = m_cursor; re2c:define:YYCURSOR = m_cursor;
re2c:define:YYLIMIT = m_limit; re2c:define:YYLIMIT = m_limit;
re2c:define:YYMARKER = m_marker; re2c:define:YYMARKER = m_marker;
re2c:define:YYFILL = "yyfill(); // LCOV_EXCL_LINE"; re2c:define:YYFILL = "yyfill(); // LCOV_EXCL_LINE";
re2c:yyfill:parameter = 0; re2c:yyfill:parameter = 0;
re2c:indent:string = " "; re2c:indent:string = " ";
re2c:indent:top = 1; re2c:indent:top = 1;
re2c:labelprefix = "basic_json_parser_"; re2c:labelprefix = "basic_json_parser_";
// ignore whitespace // ignore whitespace
ws = [ \t\n\r]+; ws = [ \t\n\r]+;
ws { return scan(); } ws { continue; }
// ignore byte-order-mark // ignore byte-order-mark
bom = "\xEF\xBB\xBF"; bom = "\xEF\xBB\xBF";
bom { return scan(); } bom { continue; }
// structural characters // structural characters
"[" { return token_type::begin_array; } "[" { last_token_type = token_type::begin_array; break; }
"]" { return token_type::end_array; } "]" { last_token_type = token_type::end_array; break; }
"{" { return token_type::begin_object; } "{" { last_token_type = token_type::begin_object; break; }
"}" { return token_type::end_object; } "}" { last_token_type = token_type::end_object; break; }
"," { return token_type::value_separator; } "," { last_token_type = token_type::value_separator; break; }
":" { return token_type::name_separator; } ":" { last_token_type = token_type::name_separator; break; }
// literal names // literal names
"null" { return token_type::literal_null; } "null" { last_token_type = token_type::literal_null; break; }
"true" { return token_type::literal_true; } "true" { last_token_type = token_type::literal_true; break; }
"false" { return token_type::literal_false; } "false" { last_token_type = token_type::literal_false; break; }
// number // number
decimal_point = [.]; decimal_point = [.];
digit = [0-9]; digit = [0-9];
digit_1_9 = [1-9]; digit_1_9 = [1-9];
e = [eE]; e = [eE];
minus = [-]; minus = [-];
plus = [+]; plus = [+];
zero = [0]; zero = [0];
exp = e (minus|plus)? digit+; exp = e (minus|plus)? digit+;
frac = decimal_point digit+; frac = decimal_point digit+;
int = (zero|digit_1_9 digit*); int = (zero|digit_1_9 digit*);
number = minus? int frac? exp?; number = minus? int frac? exp?;
number { return token_type::value_number; } number { last_token_type = token_type::value_number; break; }
// string // string
quotation_mark = ["]; quotation_mark = ["];
escape = [\\]; escape = [\\];
unescaped = [^"\\\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F]; unescaped = [^"\\\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F];
single_escaped = ["\\/bfnrt]; single_escaped = ["\\/bfnrt];
unicode_escaped = [u][0-9a-fA-F]{4}; unicode_escaped = [u][0-9a-fA-F]{4};
escaped = escape (single_escaped | unicode_escaped); escaped = escape (single_escaped | unicode_escaped);
char = unescaped | escaped; char = unescaped | escaped;
string = quotation_mark char* quotation_mark; string = quotation_mark char* quotation_mark;
string { return token_type::value_string; } string { last_token_type = token_type::value_string; break; }
// end of file // end of file
'\000' { return token_type::end_of_input; } '\000' { last_token_type = token_type::end_of_input; break; }
// anything else is an error // anything else is an error
. { return token_type::parse_error; } . { last_token_type = token_type::parse_error; break; }
*/ */
}
return last_token_type;
} }
/// append data from the stream to the internal buffer /// append data from the stream to the internal buffer
@ -7810,6 +7815,8 @@ class basic_json
const lexer_char_t* m_cursor = nullptr; const lexer_char_t* m_cursor = nullptr;
/// pointer to the end of the buffer /// pointer to the end of the buffer
const lexer_char_t* m_limit = nullptr; const lexer_char_t* m_limit = nullptr;
/// the last token type
token_type last_token_type = token_type::end_of_input;
}; };
/*! /*!