Files
strawberry/3rdparty/qjson/src/json_scanner.yy
2018-02-27 18:06:05 +01:00

262 lines
8.0 KiB
Plaintext

/* This file is part of QJson
*
* Copyright (C) 2013 Silvio Moioli <silvio@moioli.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110yy::json_parser::token::INVALID301, USA.
*/
/* Flex output settings */
%option 8bit c++ full warn
%option noyywrap nounistd
%option noinput nounput noyy_push_state noyy_pop_state noyy_top_state noyy_scan_buffer noyy_scan_bytes noyy_scan_string noyyget_extra noyyset_extra noyyget_leng noyyget_text noyyget_lineno noyyset_lineno noyyget_in noyyset_in noyyget_out noyyset_out noyyget_lval noyyset_lval noyyget_lloc noyyset_lloc noyyget_debug noyyset_debug
%option yyclass="JSonScanner"
%option outfile="json_scanner.cc"
%{
#include "json_scanner.h"
#include "json_parser.hh"
#if defined(_WIN32) && !defined(__MINGW32__)
#define strtoll _strtoi64
#define strtoull _strtoui64
#endif
#define YY_USER_INIT if(m_allowSpecialNumbers) { \
BEGIN(ALLOW_SPECIAL_NUMBERS); \
}
%}
/* Exclusive subscanners for strings and escaped hex sequences */
%x QUOTMARK_OPEN HEX_OPEN
/* Extra-JSON rules active iff m_allowSpecialNumbers is true */
%s ALLOW_SPECIAL_NUMBERS
%%
/* Whitespace */
[\v\f\t ]+ {
m_yylloc->columns(yyleng);
}
[\r\n]+ {
m_yylloc->lines(yyleng);
}
/* Special values */
true {
m_yylloc->columns(yyleng);
*m_yylval = QVariant(true);
return yy::json_parser::token::TRUE_VAL;
}
false {
m_yylloc->columns(yyleng);
*m_yylval = QVariant(false);
return yy::json_parser::token::FALSE_VAL;
}
null {
m_yylloc->columns(yyleng);
*m_yylval = QVariant();
return yy::json_parser::token::NULL_VAL;
}
/* Numbers */
[0-9] |
[1-9][0-9]+ {
m_yylloc->columns(yyleng);
*m_yylval = QVariant(strtoull(yytext, NULL, 10));
if (errno == ERANGE) {
qCritical() << "Number is out of range: " << yytext;
return yy::json_parser::token::INVALID;
}
return yy::json_parser::token::NUMBER;
}
-[0-9] |
-[1-9][0-9]+ {
m_yylloc->columns(yyleng);
*m_yylval = QVariant(strtoll(yytext, NULL, 10));
if (errno == ERANGE) {
qCritical() << "Number is out of range: " << yytext;
return yy::json_parser::token::INVALID;
}
return yy::json_parser::token::NUMBER;
}
-?(([0-9])|([1-9][0-9]+))(\.[0-9]+)?([Ee][+\-]?[0-9]+)? {
m_yylloc->columns(yyleng);
bool ok;
*m_yylval = QVariant(m_C_locale.toDouble(QLatin1String(yytext),&ok));
if (!ok) {
qCritical() << "Number is out of range: " << yytext;
return yy::json_parser::token::INVALID;
}
return yy::json_parser::token::NUMBER;
}
/* Strings */
\" {
m_yylloc->columns(yyleng);
BEGIN(QUOTMARK_OPEN);
}
<QUOTMARK_OPEN>{
\\\" {
m_currentString.append(QLatin1String("\""));
}
\\\\ {
m_currentString.append(QLatin1String("\\"));
}
\\\/ {
m_currentString.append(QLatin1String("/"));
}
\\b {
m_currentString.append(QLatin1String("\b"));
}
\\f {
m_currentString.append(QLatin1String("\f"));
}
\\n {
m_currentString.append(QLatin1String("\n"));
}
\\r {
m_currentString.append(QLatin1String("\r"));
}
\\t {
m_currentString.append(QLatin1String("\t"));
}
\\u {
BEGIN(HEX_OPEN);
}
[^\"\\]+ {
m_currentString.append(QString::fromUtf8(yytext));
}
\\ {
// ignore
}
\" {
m_yylloc->columns(yyleng);
*m_yylval = QVariant(m_currentString);
m_currentString.clear();
BEGIN(INITIAL);
return yy::json_parser::token::STRING;
}
<<EOF>> {
qCritical() << "Unterminated string";
m_yylloc->columns(yyleng);
return yy::json_parser::token::INVALID;
}
}
<HEX_OPEN>{
[0-9A-Fa-f]{4} {
QString hexDigits = QString::fromUtf8(yytext, yyleng);
bool ok;
ushort hexDigit1 = hexDigits.left(2).toShort(&ok, 16);
ushort hexDigit2 = hexDigits.right(2).toShort(&ok, 16);
m_currentString.append(QChar(hexDigit2, hexDigit1));
BEGIN(QUOTMARK_OPEN);
}
.|\n {
qCritical() << "Invalid hex string";
m_yylloc->columns(yyleng);
*m_yylval = QVariant(QLatin1String(""));
BEGIN(QUOTMARK_OPEN);
return yy::json_parser::token::INVALID;
}
}
/* "Compound type" related tokens */
: {
m_yylloc->columns(yyleng);
return yy::json_parser::token::COLON;
}
, {
m_yylloc->columns(yyleng);
return yy::json_parser::token::COMMA;
}
\[ {
m_yylloc->columns(yyleng);
return yy::json_parser::token::SQUARE_BRACKET_OPEN;
}
\] {
m_yylloc->columns(yyleng);
return yy::json_parser::token::SQUARE_BRACKET_CLOSE;
}
\{ {
m_yylloc->columns(yyleng);
return yy::json_parser::token::CURLY_BRACKET_OPEN;
}
\} {
m_yylloc->columns(yyleng);
return yy::json_parser::token::CURLY_BRACKET_CLOSE;
}
/* Extra-JSON numbers */
<ALLOW_SPECIAL_NUMBERS>{
(?i:nan) {
m_yylloc->columns(yyleng);
*m_yylval = QVariant(std::numeric_limits<double>::quiet_NaN());
return yy::json_parser::token::NUMBER;
}
[Ii]nfinity {
m_yylloc->columns(yyleng);
*m_yylval = QVariant(std::numeric_limits<double>::infinity());
return yy::json_parser::token::NUMBER;
}
-[Ii]nfinity {
m_yylloc->columns(yyleng);
*m_yylval = QVariant(-std::numeric_limits<double>::infinity());
return yy::json_parser::token::NUMBER;
}
}
/* If all else fails */
. {
m_yylloc->columns(yyleng);
return yy::json_parser::token::INVALID;
}
<<EOF>> return yy::json_parser::token::END;