1 /* This file is part of QJSon
3 * Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License version 2.1, as published by the Free Software Foundation.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
23 %define "parser_class_name" "json_parser"
27 #include "json_scanner.h"
28 #include "qjson_debug.h"
30 #include <QtCore/QByteArray>
31 #include <QtCore/QMap>
32 #include <QtCore/QString>
33 #include <QtCore/QVariant>
43 #define YYERROR_VERBOSE 1
46 %parse-param { QJson::ParserPrivate* driver }
47 %lex-param { QJson::ParserPrivate* driver }
54 %token END 0 "end of file"
56 %token CURLY_BRACKET_OPEN 1 "{"
57 %token CURLY_BRACKET_CLOSE 2 "}"
58 %token SQUARE_BRACKET_OPEN 3 "["
59 %token SQUARE_BRACKET_CLOSE 4 "]"
65 %token DIGIT 9 "digit"
66 %token E 10 "exponential"
67 %token TRUE_VAL 11 "true"
68 %token FALSE_VAL 12 "false"
69 %token NULL_VAL 13 "null"
70 %token QUOTMARKOPEN 14 "open quotation mark"
71 %token QUOTMARKCLOSE 15 "close quotation mark"
73 %token STRING 16 "string"
74 %token INFINITY_VAL 17 "Infinity"
75 %token NAN_VAL 18 "NaN"
77 // define the initial token
85 driver->m_result = $1;
86 qjsonDebug() << "json_parser - parsing finished";
89 data: value { $$ = $1; }
92 qCritical()<< "json_parser - syntax error found, "
93 << "forcing abort, Line" << @$.begin.line << "Column" << @$.begin.column;
98 object: CURLY_BRACKET_OPEN members CURLY_BRACKET_CLOSE { $$ = $2; };
100 members: /* empty */ { $$ = QVariant (QVariantMap()); }
102 QVariantMap members = $2.toMap();
103 $2 = QVariant(); // Allow reuse of map
104 $$ = QVariant(members.unite ($1.toMap()));
107 r_members: /* empty */ { $$ = QVariant (QVariantMap()); }
108 | COMMA pair r_members {
109 QVariantMap members = $3.toMap();
110 $3 = QVariant(); // Allow reuse of map
111 $$ = QVariant(members.unite ($2.toMap()));
114 pair: string COLON value {
116 pair.insert ($1.toString(), QVariant($3));
117 $$ = QVariant (pair);
120 array: SQUARE_BRACKET_OPEN values SQUARE_BRACKET_CLOSE { $$ = $2; };
122 values: /* empty */ { $$ = QVariant (QVariantList()); }
124 QVariantList members = $2.toList();
125 $2 = QVariant(); // Allow reuse of list
126 members.prepend ($1);
127 $$ = QVariant(members);
130 r_values: /* empty */ { $$ = QVariant (QVariantList()); }
131 | COMMA value r_values {
132 QVariantList members = $3.toList();
133 $3 = QVariant(); // Allow reuse of list
134 members.prepend ($2);
135 $$ = QVariant(members);
138 value: string { $$ = $1; }
139 | special_or_number { $$ = $1; }
140 | object { $$ = $1; }
142 | TRUE_VAL { $$ = QVariant (true); }
143 | FALSE_VAL { $$ = QVariant (false); }
145 QVariant null_variant;
149 special_or_number: MINUS INFINITY_VAL { $$ = QVariant(QVariant::Double); $$.setValue( -std::numeric_limits<double>::infinity() ); }
150 | INFINITY_VAL { $$ = QVariant(QVariant::Double); $$.setValue( std::numeric_limits<double>::infinity() ); }
151 | NAN_VAL { $$ = QVariant(QVariant::Double); $$.setValue( std::numeric_limits<double>::quiet_NaN() ); }
155 if ($1.toByteArray().startsWith('-')) {
156 $$ = QVariant (QVariant::LongLong);
157 $$.setValue($1.toLongLong());
160 $$ = QVariant (QVariant::ULongLong);
161 $$.setValue($1.toULongLong());
165 const QByteArray value = $1.toByteArray() + $2.toByteArray();
166 $$ = QVariant(QVariant::Double);
167 $$.setValue(value.toDouble());
169 | int exp { $$ = QVariant ($1.toByteArray() + $2.toByteArray()); }
171 const QByteArray value = $1.toByteArray() + $2.toByteArray() + $3.toByteArray();
172 $$ = QVariant (value);
175 int: DIGIT digits { $$ = QVariant ($1.toByteArray() + $2.toByteArray()); }
176 | MINUS DIGIT digits { $$ = QVariant (QByteArray("-") + $2.toByteArray() + $3.toByteArray()); };
178 digits: /* empty */ { $$ = QVariant (QByteArray("")); }
180 $$ = QVariant($1.toByteArray() + $2.toByteArray());
184 $$ = QVariant(QByteArray(".") + $2.toByteArray());
187 exp: E digits { $$ = QVariant($1.toByteArray() + $2.toByteArray()); };
189 string: QUOTMARKOPEN string_arg QUOTMARKCLOSE { $$ = $2; };
191 string_arg: /*empty */ { $$ = QVariant (QString(QLatin1String(""))); }
198 int yy::yylex(YYSTYPE *yylval, yy::location *yylloc, QJson::ParserPrivate* driver)
200 JSonScanner* scanner = driver->m_scanner;
202 int ret = scanner->yylex(yylval, yylloc);
204 qjsonDebug() << "json_parser::yylex - calling scanner yylval==|"
205 << yylval->toByteArray() << "|, ret==|" << QString::number(ret) << "|";
210 void yy::json_parser::error (const yy::location& yyloc,
211 const std::string& error)
213 /*qjsonDebug() << yyloc.begin.line;
214 qjsonDebug() << yyloc.begin.column;
215 qjsonDebug() << yyloc.end.line;
216 qjsonDebug() << yyloc.end.column;*/
217 qjsonDebug() << "json_parser::error [line" << yyloc.end.line << "] -" << error.c_str() ;
218 driver->setError(QString::fromLatin1(error.c_str()), yyloc.end.line);