]> git.cworth.org Git - apitrace/blob - thirdparty/qjson/json_parser.yy
Bundle QJSON sources.
[apitrace] / thirdparty / qjson / json_parser.yy
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 }