Files
cantata/3rdparty/qjson/json_parser.yy
2013-04-22 19:49:13 +00:00

163 lines
4.2 KiB
Plaintext

/* This file is part of QJSon
*
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
* 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 02110-1301, USA.
*/
%skeleton "lalr1.cc"
%defines
%define "parser_class_name" "json_parser"
%code requires{
#include "parser_p.h"
#include "json_scanner.h"
#include "qjson_debug.h"
#include <QtCore/QByteArray>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QVariant>
#include <limits>
class JSonScanner;
namespace QJson {
class Parser;
}
#define YYERROR_VERBOSE 1
Q_DECLARE_METATYPE(QVector<QVariant>*)
Q_DECLARE_METATYPE(QVariantMap*)
}
%parse-param { QJson::ParserPrivate* driver }
%lex-param { QJson::ParserPrivate* driver }
%locations
%debug
%error-verbose
%token END 0 "end of file"
%token CURLY_BRACKET_OPEN 1 "{"
%token CURLY_BRACKET_CLOSE 2 "}"
%token SQUARE_BRACKET_OPEN 3 "["
%token SQUARE_BRACKET_CLOSE 4 "]"
%token COLON 5 ":"
%token COMMA 6 ","
%token NUMBER 7 "number"
%token TRUE_VAL 8 "true"
%token FALSE_VAL 9 "false"
%token NULL_VAL 10 "null"
%token STRING 11 "string"
%token INVALID 12 "invalid"
// define the initial token
%start start
%%
// grammar rules
start: data {
driver->m_result = $1;
qjsonDebug() << "json_parser - parsing finished";
};
data: value { $$ = $1; }
| error
{
qCritical()<< "json_parser - syntax error found, "
<< "forcing abort, Line" << @$.begin.line << "Column" << @$.begin.column;
YYABORT;
}
| END;
object: CURLY_BRACKET_OPEN CURLY_BRACKET_CLOSE {
$$ = QVariant(QVariantMap());
}
| CURLY_BRACKET_OPEN members CURLY_BRACKET_CLOSE {
QVariantMap* map = $2.value<QVariantMap*>();
$$ = QVariant(*map);
delete map;
};
members: STRING COLON value {
QVariantMap* pair = new QVariantMap();
pair->insert($1.toString(), $3);
$$.setValue<QVariantMap* >(pair);
}
| members COMMA STRING COLON value {
$$.value<QVariantMap*>()->insert($3.toString(), $5);
};
array: SQUARE_BRACKET_OPEN SQUARE_BRACKET_CLOSE {
$$ = QVariant(QVariantList());
}
| SQUARE_BRACKET_OPEN values SQUARE_BRACKET_CLOSE {
QVector<QVariant>* list = $2.value<QVector<QVariant>* >();
$$ = QVariant(list->toList());
delete list;
};
values: value {
QVector<QVariant>* list = new QVector<QVariant>(1);
list->replace(0, $1);
$$.setValue(list);
}
| values COMMA value {
$$.value<QVector<QVariant>* >()->append($3);
};
value: STRING
| NUMBER
| TRUE_VAL
| FALSE_VAL
| NULL_VAL
| object
| array;
%%
int yy::yylex(YYSTYPE *yylval, yy::location *yylloc, QJson::ParserPrivate* driver)
{
JSonScanner* scanner = driver->m_scanner;
yylval->clear();
int ret = scanner->yylex(yylval, yylloc);
qjsonDebug() << "json_parser::yylex - calling scanner yylval==|"
<< yylval->toByteArray() << "|, ret==|" << QString::number(ret) << "|";
return ret;
}
void yy::json_parser::error (const yy::location& yyloc, const std::string& error)
{
/*qjsonDebug() << yyloc.begin.line;
qjsonDebug() << yyloc.begin.column;
qjsonDebug() << yyloc.end.line;
qjsonDebug() << yyloc.end.column;*/
qjsonDebug() << "json_parser::error [line" << yyloc.end.line << "] -" << error.c_str() ;
driver->setError(QString::fromLatin1(error.c_str()), yyloc.end.line);
}