1 /* Copyright (C) 2021 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
21 // To rebuild QLParser.tab.cc and QLParser.tab.hh, use bison 3.6 or newer:
22 // cd gprofng/src && bison QLParser.yy
24 // For "api.parser.class"
35 #include "DbeSession.h"
36 #include "Expression.h"
45 static QL::Parser::symbol_type yylex (QL::Result &result);
48 processName (std::string str)
50 const char *name = str.c_str();
51 int propID = dbeSession->getPropIdByName (name);
52 if (propID != PROP_NONE)
53 return new Expression (Expression::OP_NAME,
54 new Expression (Expression::OP_NUM, (uint64_t) propID));
56 // If a name is not statically known try user defined objects
57 Expression *expr = dbeSession->findObjDefByName (name);
61 throw Parser::syntax_error ("Name not found");
67 %define api.namespace {QL}
68 // in Bison 3.3, use %define api.parser.class {Parser} instead parser_class_name
69 %define parser_class_name {Parser}
70 %define api.token.constructor
71 %define api.value.type variant
72 // Later: api.value.automove
73 %define api.token.prefix {L_}
75 %param {QL::Result &result}
85 %token <uint64_t> NUM FNAME JGROUP JPARENT QSTR
86 %token <std::string> NAME
88 %nonassoc IN SOME ORDR
114 %type <Expression *> exp term
116 // %destructor { delete $$; } <Expression *>;
120 S: /* empty */ { result.out = new Expression (Expression::OP_NUM, (uint64_t) 1); }
121 | exp { result.out = $1; }
123 exp: exp DEG exp { $$ = new Expression (Expression::OP_DEG, $1, $3); } /* dead? */
124 | exp MUL exp { $$ = new Expression (Expression::OP_MUL, $1, $3); }
125 | exp DIV exp { $$ = new Expression (Expression::OP_DIV, $1, $3); }
126 | exp REM exp { $$ = new Expression (Expression::OP_REM, $1, $3); }
127 | exp ADD exp { $$ = new Expression (Expression::OP_ADD, $1, $3); }
128 | exp MINUS exp { $$ = new Expression (Expression::OP_MINUS, $1, $3); }
129 | exp LS exp { $$ = new Expression (Expression::OP_LS, $1, $3); }
130 | exp RS exp { $$ = new Expression (Expression::OP_RS, $1, $3); }
131 | exp LT exp { $$ = new Expression (Expression::OP_LT, $1, $3); }
132 | exp LE exp { $$ = new Expression (Expression::OP_LE, $1, $3); }
133 | exp GT exp { $$ = new Expression (Expression::OP_GT, $1, $3); }
134 | exp GE exp { $$ = new Expression (Expression::OP_GE, $1, $3); }
135 | exp EQ exp { $$ = new Expression (Expression::OP_EQ, $1, $3); }
136 | exp NE exp { $$ = new Expression (Expression::OP_NE, $1, $3); }
137 | exp BITAND exp { $$ = new Expression (Expression::OP_BITAND, $1, $3); }
138 | exp BITXOR exp { $$ = new Expression (Expression::OP_BITXOR, $1, $3); }
139 | exp BITOR exp { $$ = new Expression (Expression::OP_BITOR, $1, $3); }
140 | exp AND exp { $$ = new Expression (Expression::OP_AND, $1, $3); }
141 | exp OR exp { $$ = new Expression (Expression::OP_OR, $1, $3); }
142 | exp NEQV exp { $$ = new Expression (Expression::OP_NEQV, $1, $3); } /* dead? */
143 | exp EQV exp { $$ = new Expression (Expression::OP_EQV, $1, $3); } /* dead? */
144 | exp QWE exp COLON exp
146 $$ = new Expression (Expression::OP_QWE, $1,
147 new Expression (Expression::OP_COLON, $3, $5));
149 | exp COMMA exp { $$ = new Expression (Expression::OP_COMMA, $1, $3); }
150 | exp IN exp { $$ = new Expression (Expression::OP_IN, $1, $3); }
151 | exp SOME IN exp { $$ = new Expression (Expression::OP_SOMEIN, $1, $4); }
152 | exp ORDR IN exp { $$ = new Expression (Expression::OP_ORDRIN, $1, $4); }
157 $$ = new Expression (Expression::OP_MINUS,
158 new Expression (Expression::OP_NUM, (uint64_t) 0), $2);
160 | NOT term { $$ = new Expression (Expression::OP_NOT, $2); }
161 | BITNOT term { $$ = new Expression (Expression::OP_BITNOT, $2); }
162 | LPAR exp RPAR { $$ = $2; }
163 | FNAME LPAR QSTR RPAR
165 $$ = new Expression (Expression::OP_FUNC,
166 new Expression (Expression::OP_NUM, $1),
167 new Expression (Expression::OP_NUM, $3));
169 | HASPROP LPAR NAME RPAR
171 $$ = new Expression (Expression::OP_HASPROP,
172 new Expression (Expression::OP_NUM, processName($3)));
174 | JGROUP LPAR QSTR RPAR
176 $$ = new Expression (Expression::OP_JAVA,
177 new Expression (Expression::OP_NUM, $1),
178 new Expression (Expression::OP_NUM, $3));
180 | JPARENT LPAR QSTR RPAR
182 $$ = new Expression (Expression::OP_JAVA,
183 new Expression (Expression::OP_NUM, $1),
184 new Expression (Expression::OP_NUM, $3));
186 | FILEIOVFD LPAR QSTR RPAR
188 $$ = new Expression (Expression::OP_FILE,
189 new Expression (Expression::OP_NUM, (uint64_t) 0),
190 new Expression (Expression::OP_NUM, $3));
192 | NUM { $$ = new Expression (Expression::OP_NUM, $1); }
193 | NAME { $$ = processName($1); }
199 static Parser::symbol_type
200 unget_ret (std::istream &in, char c, Parser::symbol_type tok)
206 static Parser::symbol_type
207 yylex (QL::Result &result)
213 c = result.in.get ();
214 while (result.in && (c == ' ' || c == '\t'));
216 return Parser::make_YYEOF ();
221 case '\n': return Parser::make_YYEOF ();
222 case '(': return Parser::make_LPAR () ;
223 case ')': return Parser::make_RPAR ();
224 case ',': return Parser::make_COMMA ();
225 case '%': return Parser::make_REM ();
226 case '/': return Parser::make_DIV ();
227 case '*': return Parser::make_MUL ();
228 case '-': return Parser::make_MINUS ();
229 case '+': return Parser::make_ADD ();
230 case '~': return Parser::make_BITNOT ();
231 case '^': return Parser::make_BITXOR ();
232 case '?': return Parser::make_QWE ();
233 case ':': return Parser::make_COLON ();
235 c = result.in.get ();
237 return Parser::make_OR ();
239 return unget_ret (result.in, c, Parser::make_BITOR ());
241 c = result.in.get ();
243 return Parser::make_AND ();
245 return unget_ret (result.in, c, Parser::make_BITAND ());
247 c = result.in.get ();
249 return Parser::make_NE ();
251 return unget_ret (result.in, c, Parser::make_NOT ());
253 c = result.in.get ();
255 return Parser::make_EQ ();
257 throw Parser::syntax_error ("Syntax error after =");
259 c = result.in.get ();
261 return Parser::make_LE ();
263 return Parser::make_LS ();
265 return unget_ret (result.in, c, Parser::make_LT ());
267 c = result.in.get ();
269 return Parser::make_GE ();
271 return Parser::make_RS ();
273 return unget_ret (result.in, c, Parser::make_GT ());
277 char *str = (char *) malloc (maxsz);
282 c = result.in.get ();
286 throw Parser::syntax_error ("Unclosed \"");
293 // XXX omazur: need new string type
294 return Parser::make_QSTR ((uint64_t) str);
298 throw Parser::syntax_error ("Multiline strings are not supported");
300 if (ptr - str >= maxsz)
302 size_t len = ptr - str;
303 maxsz = maxsz > 8192 ? maxsz + 8192 : maxsz * 2;
304 char *new_s = (char *) realloc (str, maxsz);
316 c = result.in.get ();
320 c = result.in.get ();
323 else if (c >= '1' && c <='9')
334 case '0': case '1': case '2': case '3':
335 case '4': case '5': case '6': case '7':
342 case 'a': case 'b': case 'c':
343 case 'd': case 'e': case 'f':
345 digit = c - 'a' + 10;
347 case 'A': case 'B': case 'C':
348 case 'D': case 'E': case 'F':
350 digit = c - 'A' + 10;
355 result.in.putback (c);
358 lval = lval * base + digit;
359 c = result.in.get ();
361 return Parser::make_NUM (lval);
364 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
366 char name[32]; // omazur XXX: accept any length
368 for (size_t i = 1; i < sizeof (name); i++)
370 c = result.in.get ();
371 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
372 (c >= '0' && c <= '9') || (c == '_'))
377 result.in.putback (c);
382 if (strcasecmp (name, NTXT ("IN")) == 0)
383 return Parser::make_IN ();
384 else if (strcasecmp (name, NTXT ("SOME")) == 0)
385 return Parser::make_SOME ();
386 else if (strcasecmp (name, NTXT ("ORDERED")) == 0)
387 return Parser::make_ORDR ();
388 else if (strcasecmp (name, NTXT ("TRUE")) == 0)
389 return Parser::make_NUM ((uint64_t) 1);
390 else if (strcasecmp (name, NTXT ("FALSE")) == 0)
391 return Parser::make_NUM ((uint64_t) 0);
392 else if (strcasecmp (name, NTXT ("FNAME")) == 0)
393 return Parser::make_FNAME (Expression::FUNC_FNAME);
394 else if (strcasecmp (name, NTXT ("HAS_PROP")) == 0)
395 return Parser::make_HASPROP ();
396 else if (strcasecmp (name, NTXT ("JGROUP")) == 0)
397 return Parser::make_JGROUP (Expression::JAVA_JGROUP);
398 else if (strcasecmp (name, NTXT ("JPARENT")) == 0 )
399 return Parser::make_JPARENT (Expression::JAVA_JPARENT);
400 else if (strcasecmp (name, NTXT ("DNAME")) == 0)
401 return Parser::make_FNAME (Expression::FUNC_DNAME);
402 else if (strcasecmp (name, NTXT ("FILEIOVFD")) == 0 )
403 return Parser::make_FILEIOVFD ();
405 std::string nm = std::string (name);
406 return Parser::make_NAME (nm);
409 throw Parser::syntax_error ("Syntax error");
413 Parser::error (const std::string &)
415 // do nothing for now