/* This file is part of QJson * * Copyright (C) 2013 Silvio Moioli * * 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); } { \\\" { 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; } <> { qCritical() << "Unterminated string"; m_yylloc->columns(yyleng); return yy::json_parser::token::INVALID; } } { [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 */ { (?i:nan) { m_yylloc->columns(yyleng); *m_yylval = QVariant(std::numeric_limits::quiet_NaN()); return yy::json_parser::token::NUMBER; } [Ii]nfinity { m_yylloc->columns(yyleng); *m_yylval = QVariant(std::numeric_limits::infinity()); return yy::json_parser::token::NUMBER; } -[Ii]nfinity { m_yylloc->columns(yyleng); *m_yylval = QVariant(-std::numeric_limits::infinity()); return yy::json_parser::token::NUMBER; } } /* If all else fails */ . { m_yylloc->columns(yyleng); return yy::json_parser::token::INVALID; } <> return yy::json_parser::token::END;