smf/smfservermodule/util/qjson/src/json_parser.yy
changeset 10 1d94eb8df9c2
parent 9 b85b0c039c14
equal deleted inserted replaced
9:b85b0c039c14 10:1d94eb8df9c2
     1 /* This file is part of QJSon
       
     2   *
       
     3   * Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
       
     4   *
       
     5   * This library is free software; you can redistribute it and/or
       
     6   * modify it under the terms of the GNU Library General Public
       
     7   * License as published by the Free Software Foundation; either
       
     8   * version 2 of the License, or (at your option) any later version.
       
     9   *
       
    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   * Library General Public License for more details.
       
    14   *
       
    15   * You should have received a copy of the GNU Library 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.
       
    19   */
       
    20 
       
    21 %skeleton "lalr1.cc"
       
    22 %defines
       
    23 %define "parser_class_name" "json_parser"
       
    24 
       
    25 %{
       
    26   #include "parser_p.h"
       
    27   #include "json_scanner.h"
       
    28   #include "qjson_debug.h"
       
    29 
       
    30   #include <QtCore/QByteArray>
       
    31   #include <QtCore/QMap>
       
    32   #include <QtCore/QString>
       
    33   #include <QtCore/QVariant>
       
    34 
       
    35   class JSonScanner;
       
    36 
       
    37   namespace QJson {
       
    38     class Parser;
       
    39   }
       
    40 
       
    41   #define YYERROR_VERBOSE 1
       
    42 %}
       
    43 
       
    44 %parse-param { QJson::ParserPrivate* driver }
       
    45 %lex-param { QJson::ParserPrivate* driver }
       
    46 
       
    47 %locations
       
    48 
       
    49 %debug
       
    50 %error-verbose
       
    51 
       
    52 %token END 0 "end of file"
       
    53 
       
    54 %token CURLY_BRACKET_OPEN 1 "{"
       
    55 %token CURLY_BRACKET_CLOSE 2 "}"
       
    56 %token SQUARE_BRACKET_OPEN 3 "["
       
    57 %token SQUARE_BRACKET_CLOSE 4 "]"
       
    58 
       
    59 %token COLON 5 ":"
       
    60 %token COMMA 6 ","
       
    61 %token MINUS 7 "-"
       
    62 %token DOT 8 "."
       
    63 %token DIGIT 9 "digit"
       
    64 %token E 10 "exponential"
       
    65 %token TRUE_VAL 11 "true"
       
    66 %token FALSE_VAL 12 "false"
       
    67 %token NULL_VAL 13 "null"
       
    68 %token QUOTMARKOPEN 14 "open quotation mark"
       
    69 %token QUOTMARKCLOSE 15 "close quotation mark"
       
    70 
       
    71 %token STRING 16 "string"
       
    72 
       
    73 // define the initial token
       
    74 %start start
       
    75 
       
    76 %%
       
    77 
       
    78 // grammar rules
       
    79 
       
    80 start: data {
       
    81               driver->m_result = $1;
       
    82               qjsonDebug() << "json_parser - parsing finished";
       
    83             };
       
    84 
       
    85 data: object {$$ = $1; }
       
    86       | array {$$ = $1; }
       
    87       | error
       
    88           {
       
    89             qCritical()<< "json_parser - syntax error found, "
       
    90                     << "forcing abort";
       
    91             YYABORT;
       
    92           }
       
    93       | END;
       
    94 
       
    95 object: CURLY_BRACKET_OPEN members CURLY_BRACKET_CLOSE { $$ = $2; };
       
    96 
       
    97 members: /* empty */ { $$ = QVariant (QVariantMap()); }
       
    98         | pair r_members {
       
    99             QVariantMap members = $2.toMap();
       
   100             $2 = QVariant(); // Allow reuse of map
       
   101             $$ = QVariant(members.unite ($1.toMap()));
       
   102           };
       
   103 
       
   104 r_members: /* empty */ { $$ = QVariant (QVariantMap()); }
       
   105         | COMMA pair r_members {
       
   106           QVariantMap members = $3.toMap();
       
   107           $3 = QVariant(); // Allow reuse of map
       
   108           $$ = QVariant(members.unite ($2.toMap()));
       
   109           };
       
   110 
       
   111 pair:   string COLON value {
       
   112             QVariantMap pair;
       
   113             pair.insert ($1.toString(), QVariant($3));
       
   114             $$ = QVariant (pair);
       
   115           };
       
   116 
       
   117 array: SQUARE_BRACKET_OPEN values SQUARE_BRACKET_CLOSE { $$ = $2; };
       
   118 
       
   119 values: /* empty */ { $$ = QVariant (QVariantList()); }
       
   120         | value r_values {
       
   121           QVariantList members = $2.toList();
       
   122           $2 = QVariant(); // Allow reuse of list
       
   123           members.prepend ($1);
       
   124           $$ = QVariant(members);
       
   125         };
       
   126 
       
   127 r_values: /* empty */ { $$ = QVariant (QVariantList()); }
       
   128           | COMMA value r_values {
       
   129             QVariantList members = $3.toList();
       
   130             $3 = QVariant(); // Allow reuse of list
       
   131             members.prepend ($2);
       
   132             $$ = QVariant(members);
       
   133           };
       
   134 
       
   135 value: string { $$ = $1; }
       
   136         | number { $$ = $1; }
       
   137         | object { $$ = $1; }
       
   138         | array { $$ = $1; }
       
   139         | TRUE_VAL { $$ = QVariant (true); }
       
   140         | FALSE_VAL { $$ = QVariant (false); }
       
   141         | NULL_VAL {
       
   142           QVariant null_variant;
       
   143           $$ = null_variant;
       
   144         };
       
   145 
       
   146 number: int {
       
   147             if ($1.toByteArray().startsWith('-')) {
       
   148               $$ = QVariant (QVariant::LongLong);
       
   149               $$.setValue($1.toLongLong());
       
   150             }
       
   151             else {
       
   152               $$ = QVariant (QVariant::ULongLong);
       
   153               $$.setValue($1.toULongLong());
       
   154             }
       
   155           }
       
   156         | int fract {
       
   157             const QByteArray value = $1.toByteArray() + $2.toByteArray();
       
   158             $$ = QVariant(QVariant::Double);
       
   159             $$.setValue(value.toDouble());
       
   160           }
       
   161         | int exp { $$ = QVariant ($1.toByteArray() + $2.toByteArray()); }
       
   162         | int fract exp {
       
   163             const QByteArray value = $1.toByteArray() + $2.toByteArray() + $3.toByteArray();
       
   164             $$ = QVariant (value);
       
   165           };
       
   166 
       
   167 int:  DIGIT digits { $$ = QVariant ($1.toByteArray() + $2.toByteArray()); }
       
   168       | MINUS DIGIT digits { $$ = QVariant (QByteArray("-") + $2.toByteArray() + $3.toByteArray()); };
       
   169 
       
   170 digits: /* empty */ { $$ = QVariant (QByteArray("")); }
       
   171         | DIGIT digits {
       
   172           $$ = QVariant($1.toByteArray() + $2.toByteArray());
       
   173         };
       
   174 
       
   175 fract: DOT digits {
       
   176           $$ = QVariant(QByteArray(".") + $2.toByteArray());
       
   177         };
       
   178 
       
   179 exp: E digits { $$ = QVariant($1.toByteArray() + $2.toByteArray()); };
       
   180 
       
   181 string: QUOTMARKOPEN string_arg QUOTMARKCLOSE { $$ = $2; };
       
   182 
       
   183 string_arg: /*empty */ { $$ = QVariant (QString(QLatin1String(""))); }
       
   184             | STRING {
       
   185                 $$ = $1;
       
   186               };
       
   187 
       
   188 %%
       
   189 
       
   190 int yy::yylex(YYSTYPE *yylval, yy::location *yylloc, QJson::ParserPrivate* driver)
       
   191 {
       
   192   JSonScanner* scanner = driver->m_scanner;
       
   193   yylval->clear();
       
   194   int ret = scanner->yylex(yylval, yylloc);
       
   195 
       
   196   qjsonDebug() << "json_parser::yylex - calling scanner yylval==|"
       
   197            << yylval->toByteArray() << "|, ret==|" << QString::number(ret) << "|";
       
   198   
       
   199   return ret;
       
   200 }
       
   201 
       
   202 void yy::json_parser::error (const yy::location& yyloc,
       
   203                                  const std::string& error)
       
   204 {
       
   205   /*qjsonDebug() << yyloc.begin.line;
       
   206   qjsonDebug() << yyloc.begin.column;
       
   207   qjsonDebug() << yyloc.end.line;
       
   208   qjsonDebug() << yyloc.end.column;*/
       
   209   qjsonDebug() << "json_parser::error [line" << yyloc.end.line << "] -" << error.c_str() ;
       
   210   driver->setError(QString::fromLatin1(error.c_str()), yyloc.end.line);
       
   211 }