Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
xpath_parser Struct Reference

Classes

struct  binary_op_t

Public Member Functions

xpath_ast_nodeerror (const char *message)
xpath_ast_nodeerror_oom ()
xpath_ast_nodeerror_rec ()
void * alloc_node ()
xpath_ast_nodealloc_node (ast_type_t type, xpath_value_type rettype, const char_t *value)
xpath_ast_nodealloc_node (ast_type_t type, xpath_value_type rettype, double value)
xpath_ast_nodealloc_node (ast_type_t type, xpath_value_type rettype, xpath_variable *value)
xpath_ast_nodealloc_node (ast_type_t type, xpath_value_type rettype, xpath_ast_node *left=0, xpath_ast_node *right=0)
xpath_ast_nodealloc_node (ast_type_t type, xpath_ast_node *left, axis_t axis, nodetest_t test, const char_t *contents)
xpath_ast_nodealloc_node (ast_type_t type, xpath_ast_node *left, xpath_ast_node *right, predicate_t test)
const char_t * alloc_string (const xpath_lexer_string &value)
xpath_ast_nodeparse_function (const xpath_lexer_string &name, size_t argc, xpath_ast_node *args[2])
axis_t parse_axis_name (const xpath_lexer_string &name, bool &specified)
nodetest_t parse_node_test_type (const xpath_lexer_string &name)
xpath_ast_nodeparse_primary_expression ()
xpath_ast_nodeparse_filter_expression ()
xpath_ast_nodeparse_step (xpath_ast_node *set)
xpath_ast_nodeparse_relative_location_path (xpath_ast_node *set)
xpath_ast_nodeparse_location_path ()
xpath_ast_nodeparse_path_or_unary_expression ()
xpath_ast_nodeparse_expression_rec (xpath_ast_node *lhs, int limit)
xpath_ast_nodeparse_expression (int limit=0)
 xpath_parser (const char_t *query, xpath_variable_set *variables, xpath_allocator *alloc, xpath_parse_result *result)
xpath_ast_nodeparse ()

Static Public Member Functions

static xpath_ast_nodeparse (const char_t *query, xpath_variable_set *variables, xpath_allocator *alloc, xpath_parse_result *result)

Public Attributes

xpath_allocator_alloc
xpath_lexer _lexer
const char_t * _query
xpath_variable_set * _variables
xpath_parse_result * _result
char_t _scratch [32]
size_t _depth

Detailed Description

Definition at line 11305 of file pugixml.cc.

Constructor & Destructor Documentation

◆ xpath_parser()

xpath_parser::xpath_parser ( const char_t * query,
xpath_variable_set * variables,
xpath_allocator * alloc,
xpath_parse_result * result )
inline

Definition at line 12226 of file pugixml.cc.

12226 : _alloc(alloc), _lexer(query), _query(query), _variables(variables), _result(result), _depth(0)
12227 {
12228 }
xpath_variable_set * _variables
Definition pugixml.cc:11311
xpath_lexer _lexer
Definition pugixml.cc:11308
xpath_parse_result * _result
Definition pugixml.cc:11313
size_t _depth
Definition pugixml.cc:11317
const char_t * _query
Definition pugixml.cc:11310
xpath_allocator * _alloc
Definition pugixml.cc:11307

Referenced by parse().

Member Function Documentation

◆ alloc_node() [1/7]

void * xpath_parser::alloc_node ( )
inline

◆ alloc_node() [2/7]

xpath_ast_node * xpath_parser::alloc_node ( ast_type_t type,
xpath_ast_node * left,
axis_t axis,
nodetest_t test,
const char_t * contents )
inline

Definition at line 11369 of file pugixml.cc.

11370 {
11371 void* memory = alloc_node();
11372 return memory ? new (memory) xpath_ast_node(type, left, axis, test, contents) : 0;
11373 }
const axis_t axis_to_type< N >::axis
Definition pugixml.cc:9668
void * alloc_node()
Definition pugixml.cc:11340

◆ alloc_node() [3/7]

xpath_ast_node * xpath_parser::alloc_node ( ast_type_t type,
xpath_ast_node * left,
xpath_ast_node * right,
predicate_t test )
inline

Definition at line 11375 of file pugixml.cc.

11376 {
11377 void* memory = alloc_node();
11378 return memory ? new (memory) xpath_ast_node(type, left, right, test) : 0;
11379 }

◆ alloc_node() [4/7]

xpath_ast_node * xpath_parser::alloc_node ( ast_type_t type,
xpath_value_type rettype,
const char_t * value )
inline

Definition at line 11345 of file pugixml.cc.

11346 {
11347 void* memory = alloc_node();
11348 return memory ? new (memory) xpath_ast_node(type, rettype, value) : 0;
11349 }

◆ alloc_node() [5/7]

xpath_ast_node * xpath_parser::alloc_node ( ast_type_t type,
xpath_value_type rettype,
double value )
inline

Definition at line 11351 of file pugixml.cc.

11352 {
11353 void* memory = alloc_node();
11354 return memory ? new (memory) xpath_ast_node(type, rettype, value) : 0;
11355 }

◆ alloc_node() [6/7]

xpath_ast_node * xpath_parser::alloc_node ( ast_type_t type,
xpath_value_type rettype,
xpath_ast_node * left = 0,
xpath_ast_node * right = 0 )
inline

Definition at line 11363 of file pugixml.cc.

11364 {
11365 void* memory = alloc_node();
11366 return memory ? new (memory) xpath_ast_node(type, rettype, left, right) : 0;
11367 }

◆ alloc_node() [7/7]

xpath_ast_node * xpath_parser::alloc_node ( ast_type_t type,
xpath_value_type rettype,
xpath_variable * value )
inline

Definition at line 11357 of file pugixml.cc.

11358 {
11359 void* memory = alloc_node();
11360 return memory ? new (memory) xpath_ast_node(type, rettype, value) : 0;
11361 }

◆ alloc_string()

const char_t * xpath_parser::alloc_string ( const xpath_lexer_string & value)
inline

Definition at line 11381 of file pugixml.cc.

11382 {
11383 if (!value.begin)
11384 return PUGIXML_TEXT("");
11385
11386 size_t length = static_cast<size_t>(value.end - value.begin);
11387
11388 char_t* c = static_cast<char_t*>(_alloc->allocate((length + 1) * sizeof(char_t)));
11389 if (!c) return 0;
11390
11391 memcpy(c, value.begin, length * sizeof(char_t));
11392 c[length] = 0;
11393
11394 return c;
11395 }
PUGIXML_CHAR char_t
Definition pugixml.hpp:137
#define PUGIXML_TEXT(t)
Definition pugixml.hpp:130
const char_t * begin
Definition pugixml.cc:9232
const char_t * end
Definition pugixml.cc:9233

Referenced by parse_primary_expression(), and parse_step().

◆ error()

xpath_ast_node * xpath_parser::error ( const char * message)
inline

Definition at line 11319 of file pugixml.cc.

11320 {
11321 _result->error = message;
11322 _result->offset = _lexer.current_pos() - _query;
11323
11324 return 0;
11325 }

Referenced by error_rec(), parse(), parse_expression_rec(), parse_filter_expression(), parse_function(), parse_path_or_unary_expression(), parse_primary_expression(), and parse_step().

◆ error_oom()

xpath_ast_node * xpath_parser::error_oom ( )
inline

Definition at line 11327 of file pugixml.cc.

11328 {
11329 assert(_alloc->_error);
11330 *_alloc->_error = true;
11331
11332 return 0;
11333 }

Referenced by parse_primary_expression().

◆ error_rec()

xpath_ast_node * xpath_parser::error_rec ( )
inline

Definition at line 11335 of file pugixml.cc.

11336 {
11337 return error("Exceeded maximum allowed query depth");
11338 }
xpath_ast_node * error(const char *message)
Definition pugixml.cc:11319

Referenced by parse_expression(), parse_expression_rec(), parse_filter_expression(), parse_primary_expression(), parse_relative_location_path(), and parse_step().

◆ parse() [1/2]

xpath_ast_node * xpath_parser::parse ( )
inline

Definition at line 12230 of file pugixml.cc.

12231 {
12232 xpath_ast_node* n = parse_expression();
12233 if (!n) return 0;
12234
12235 assert(_depth == 0);
12236
12237 // check if there are unparsed tokens left
12238 if (_lexer.current() != lex_eof)
12239 return error("Incorrect query");
12240
12241 return n;
12242 }
@ lex_eof
Definition pugixml.cc:9227
xpath_ast_node * parse_expression(int limit=0)
Definition pugixml.cc:12209

Referenced by parse().

◆ parse() [2/2]

xpath_ast_node * xpath_parser::parse ( const char_t * query,
xpath_variable_set * variables,
xpath_allocator * alloc,
xpath_parse_result * result )
inlinestatic

Definition at line 12244 of file pugixml.cc.

12245 {
12246 xpath_parser parser(query, variables, alloc, result);
12247
12248 return parser.parse();
12249 }
xpath_parser(const char_t *query, xpath_variable_set *variables, xpath_allocator *alloc, xpath_parse_result *result)
Definition pugixml.cc:12226

◆ parse_axis_name()

axis_t xpath_parser::parse_axis_name ( const xpath_lexer_string & name,
bool & specified )
inline

Definition at line 11517 of file pugixml.cc.

11518 {
11519 specified = true;
11520
11521 switch (name.begin[0])
11522 {
11523 case 'a':
11524 if (name == PUGIXML_TEXT("ancestor"))
11525 return axis_ancestor;
11526 else if (name == PUGIXML_TEXT("ancestor-or-self"))
11527 return axis_ancestor_or_self;
11528 else if (name == PUGIXML_TEXT("attribute"))
11529 return axis_attribute;
11530
11531 break;
11532
11533 case 'c':
11534 if (name == PUGIXML_TEXT("child"))
11535 return axis_child;
11536
11537 break;
11538
11539 case 'd':
11540 if (name == PUGIXML_TEXT("descendant"))
11541 return axis_descendant;
11542 else if (name == PUGIXML_TEXT("descendant-or-self"))
11544
11545 break;
11546
11547 case 'f':
11548 if (name == PUGIXML_TEXT("following"))
11549 return axis_following;
11550 else if (name == PUGIXML_TEXT("following-sibling"))
11552
11553 break;
11554
11555 case 'n':
11556 if (name == PUGIXML_TEXT("namespace"))
11557 return axis_namespace;
11558
11559 break;
11560
11561 case 'p':
11562 if (name == PUGIXML_TEXT("parent"))
11563 return axis_parent;
11564 else if (name == PUGIXML_TEXT("preceding"))
11565 return axis_preceding;
11566 else if (name == PUGIXML_TEXT("preceding-sibling"))
11568
11569 break;
11570
11571 case 's':
11572 if (name == PUGIXML_TEXT("self"))
11573 return axis_self;
11574
11575 break;
11576
11577 default:
11578 break;
11579 }
11580
11581 specified = false;
11582 return axis_child;
11583 }
const char * name(G4int ptype)
@ axis_preceding
Definition pugixml.cc:9630
@ axis_ancestor_or_self
Definition pugixml.cc:9621
@ axis_attribute
Definition pugixml.cc:9622
@ axis_following_sibling
Definition pugixml.cc:9627
@ axis_child
Definition pugixml.cc:9623
@ axis_descendant
Definition pugixml.cc:9624
@ axis_descendant_or_self
Definition pugixml.cc:9625
@ axis_self
Definition pugixml.cc:9632
@ axis_following
Definition pugixml.cc:9626
@ axis_ancestor
Definition pugixml.cc:9620
@ axis_preceding_sibling
Definition pugixml.cc:9631
@ axis_namespace
Definition pugixml.cc:9628
@ axis_parent
Definition pugixml.cc:9629

Referenced by parse_step().

◆ parse_expression()

xpath_ast_node * xpath_parser::parse_expression ( int limit = 0)
inline

Definition at line 12209 of file pugixml.cc.

12210 {
12211 size_t old_depth = _depth;
12212
12213 if (++_depth > xpath_ast_depth_limit)
12214 return error_rec();
12215
12216 xpath_ast_node* n = parse_path_or_unary_expression();
12217 if (!n) return 0;
12218
12219 n = parse_expression_rec(n, limit);
12220
12221 _depth = old_depth;
12222
12223 return n;
12224 }
xpath_ast_node * error_rec()
Definition pugixml.cc:11335
xpath_ast_node * parse_path_or_unary_expression()
Definition pugixml.cc:12023
xpath_ast_node * parse_expression_rec(xpath_ast_node *lhs, int limit)
Definition pugixml.cc:12155

Referenced by parse(), parse_filter_expression(), parse_path_or_unary_expression(), parse_primary_expression(), and parse_step().

◆ parse_expression_rec()

xpath_ast_node * xpath_parser::parse_expression_rec ( xpath_ast_node * lhs,
int limit )
inline

Definition at line 12155 of file pugixml.cc.

12156 {
12158
12159 while (op.asttype != ast_unknown && op.precedence >= limit)
12160 {
12161 _lexer.next();
12162
12163 if (++_depth > xpath_ast_depth_limit)
12164 return error_rec();
12165
12166 xpath_ast_node* rhs = parse_path_or_unary_expression();
12167 if (!rhs) return 0;
12168
12170
12171 while (nextop.asttype != ast_unknown && nextop.precedence > op.precedence)
12172 {
12173 rhs = parse_expression_rec(rhs, nextop.precedence);
12174 if (!rhs) return 0;
12175
12176 nextop = binary_op_t::parse(_lexer);
12177 }
12178
12179 if (op.asttype == ast_op_union && (lhs->rettype() != xpath_type_node_set || rhs->rettype() != xpath_type_node_set))
12180 return error("Union operator has to be applied to node sets");
12181
12182 lhs = alloc_node(op.asttype, op.rettype, lhs, rhs);
12183 if (!lhs) return 0;
12184
12186 }
12187
12188 return lhs;
12189 }
xpath_value_type rettype() const
Definition pugixml.cc:11291
@ ast_unknown
Definition pugixml.cc:9555
@ ast_op_union
Definition pugixml.cc:9570
static binary_op_t parse(xpath_lexer &lexer)
Definition pugixml.cc:12103

Referenced by parse_expression(), and parse_expression_rec().

◆ parse_filter_expression()

xpath_ast_node * xpath_parser::parse_filter_expression ( )
inline

Definition at line 11734 of file pugixml.cc.

11735 {
11736 xpath_ast_node* n = parse_primary_expression();
11737 if (!n) return 0;
11738
11739 size_t old_depth = _depth;
11740
11741 while (_lexer.current() == lex_open_square_brace)
11742 {
11743 _lexer.next();
11744
11745 if (++_depth > xpath_ast_depth_limit)
11746 return error_rec();
11747
11748 if (n->rettype() != xpath_type_node_set)
11749 return error("Predicate has to be applied to node set");
11750
11751 xpath_ast_node* expr = parse_expression();
11752 if (!expr) return 0;
11753
11755 if (!n) return 0;
11756
11757 if (_lexer.current() != lex_close_square_brace)
11758 return error("Expected ']' to match an opening '['");
11759
11760 _lexer.next();
11761 }
11762
11763 _depth = old_depth;
11764
11765 return n;
11766 }
@ ast_filter
Definition pugixml.cc:9572
@ predicate_default
Definition pugixml.cc:9650
@ lex_close_square_brace
Definition pugixml.cc:9220
@ lex_open_square_brace
Definition pugixml.cc:9219
xpath_ast_node * parse_primary_expression()
Definition pugixml.cc:11621

Referenced by parse_path_or_unary_expression().

◆ parse_function()

xpath_ast_node * xpath_parser::parse_function ( const xpath_lexer_string & name,
size_t argc,
xpath_ast_node * args[2] )
inline

Definition at line 11397 of file pugixml.cc.

11398 {
11399 switch (name.begin[0])
11400 {
11401 case 'b':
11402 if (name == PUGIXML_TEXT("boolean") && argc == 1)
11403 return alloc_node(ast_func_boolean, xpath_type_boolean, args[0]);
11404
11405 break;
11406
11407 case 'c':
11408 if (name == PUGIXML_TEXT("count") && argc == 1)
11409 {
11410 if (args[0]->rettype() != xpath_type_node_set) return error("Function has to be applied to node set");
11411 return alloc_node(ast_func_count, xpath_type_number, args[0]);
11412 }
11413 else if (name == PUGIXML_TEXT("contains") && argc == 2)
11414 return alloc_node(ast_func_contains, xpath_type_boolean, args[0], args[1]);
11415 else if (name == PUGIXML_TEXT("concat") && argc >= 2)
11416 return alloc_node(ast_func_concat, xpath_type_string, args[0], args[1]);
11417 else if (name == PUGIXML_TEXT("ceiling") && argc == 1)
11418 return alloc_node(ast_func_ceiling, xpath_type_number, args[0]);
11419
11420 break;
11421
11422 case 'f':
11423 if (name == PUGIXML_TEXT("false") && argc == 0)
11424 return alloc_node(ast_func_false, xpath_type_boolean);
11425 else if (name == PUGIXML_TEXT("floor") && argc == 1)
11426 return alloc_node(ast_func_floor, xpath_type_number, args[0]);
11427
11428 break;
11429
11430 case 'i':
11431 if (name == PUGIXML_TEXT("id") && argc == 1)
11432 return alloc_node(ast_func_id, xpath_type_node_set, args[0]);
11433
11434 break;
11435
11436 case 'l':
11437 if (name == PUGIXML_TEXT("last") && argc == 0)
11438 return alloc_node(ast_func_last, xpath_type_number);
11439 else if (name == PUGIXML_TEXT("lang") && argc == 1)
11440 return alloc_node(ast_func_lang, xpath_type_boolean, args[0]);
11441 else if (name == PUGIXML_TEXT("local-name") && argc <= 1)
11442 {
11443 if (argc == 1 && args[0]->rettype() != xpath_type_node_set) return error("Function has to be applied to node set");
11444 return alloc_node(argc == 0 ? ast_func_local_name_0 : ast_func_local_name_1, xpath_type_string, args[0]);
11445 }
11446
11447 break;
11448
11449 case 'n':
11450 if (name == PUGIXML_TEXT("name") && argc <= 1)
11451 {
11452 if (argc == 1 && args[0]->rettype() != xpath_type_node_set) return error("Function has to be applied to node set");
11453 return alloc_node(argc == 0 ? ast_func_name_0 : ast_func_name_1, xpath_type_string, args[0]);
11454 }
11455 else if (name == PUGIXML_TEXT("namespace-uri") && argc <= 1)
11456 {
11457 if (argc == 1 && args[0]->rettype() != xpath_type_node_set) return error("Function has to be applied to node set");
11458 return alloc_node(argc == 0 ? ast_func_namespace_uri_0 : ast_func_namespace_uri_1, xpath_type_string, args[0]);
11459 }
11460 else if (name == PUGIXML_TEXT("normalize-space") && argc <= 1)
11461 return alloc_node(argc == 0 ? ast_func_normalize_space_0 : ast_func_normalize_space_1, xpath_type_string, args[0], args[1]);
11462 else if (name == PUGIXML_TEXT("not") && argc == 1)
11463 return alloc_node(ast_func_not, xpath_type_boolean, args[0]);
11464 else if (name == PUGIXML_TEXT("number") && argc <= 1)
11465 return alloc_node(argc == 0 ? ast_func_number_0 : ast_func_number_1, xpath_type_number, args[0]);
11466
11467 break;
11468
11469 case 'p':
11470 if (name == PUGIXML_TEXT("position") && argc == 0)
11471 return alloc_node(ast_func_position, xpath_type_number);
11472
11473 break;
11474
11475 case 'r':
11476 if (name == PUGIXML_TEXT("round") && argc == 1)
11477 return alloc_node(ast_func_round, xpath_type_number, args[0]);
11478
11479 break;
11480
11481 case 's':
11482 if (name == PUGIXML_TEXT("string") && argc <= 1)
11483 return alloc_node(argc == 0 ? ast_func_string_0 : ast_func_string_1, xpath_type_string, args[0]);
11484 else if (name == PUGIXML_TEXT("string-length") && argc <= 1)
11485 return alloc_node(argc == 0 ? ast_func_string_length_0 : ast_func_string_length_1, xpath_type_number, args[0]);
11486 else if (name == PUGIXML_TEXT("starts-with") && argc == 2)
11487 return alloc_node(ast_func_starts_with, xpath_type_boolean, args[0], args[1]);
11488 else if (name == PUGIXML_TEXT("substring-before") && argc == 2)
11489 return alloc_node(ast_func_substring_before, xpath_type_string, args[0], args[1]);
11490 else if (name == PUGIXML_TEXT("substring-after") && argc == 2)
11491 return alloc_node(ast_func_substring_after, xpath_type_string, args[0], args[1]);
11492 else if (name == PUGIXML_TEXT("substring") && (argc == 2 || argc == 3))
11493 return alloc_node(argc == 2 ? ast_func_substring_2 : ast_func_substring_3, xpath_type_string, args[0], args[1]);
11494 else if (name == PUGIXML_TEXT("sum") && argc == 1)
11495 {
11496 if (args[0]->rettype() != xpath_type_node_set) return error("Function has to be applied to node set");
11497 return alloc_node(ast_func_sum, xpath_type_number, args[0]);
11498 }
11499
11500 break;
11501
11502 case 't':
11503 if (name == PUGIXML_TEXT("translate") && argc == 3)
11504 return alloc_node(ast_func_translate, xpath_type_string, args[0], args[1]);
11505 else if (name == PUGIXML_TEXT("true") && argc == 0)
11506 return alloc_node(ast_func_true, xpath_type_boolean);
11507
11508 break;
11509
11510 default:
11511 break;
11512 }
11513
11514 return error("Unrecognized function or wrong parameter count");
11515 }
@ ast_func_substring_3
Definition pugixml.cc:9594
@ ast_func_sum
Definition pugixml.cc:9607
@ ast_func_name_1
Definition pugixml.cc:9585
@ ast_func_floor
Definition pugixml.cc:9608
@ ast_func_concat
Definition pugixml.cc:9588
@ ast_func_name_0
Definition pugixml.cc:9584
@ ast_func_not
Definition pugixml.cc:9601
@ ast_func_string_1
Definition pugixml.cc:9587
@ ast_func_string_0
Definition pugixml.cc:9586
@ ast_func_number_0
Definition pugixml.cc:9605
@ ast_func_substring_before
Definition pugixml.cc:9591
@ ast_func_string_length_0
Definition pugixml.cc:9595
@ ast_func_local_name_1
Definition pugixml.cc:9581
@ ast_func_namespace_uri_0
Definition pugixml.cc:9582
@ ast_func_lang
Definition pugixml.cc:9604
@ ast_func_true
Definition pugixml.cc:9602
@ ast_func_normalize_space_1
Definition pugixml.cc:9598
@ ast_func_contains
Definition pugixml.cc:9590
@ ast_func_substring_2
Definition pugixml.cc:9593
@ ast_func_position
Definition pugixml.cc:9577
@ ast_func_ceiling
Definition pugixml.cc:9609
@ ast_func_last
Definition pugixml.cc:9576
@ ast_func_normalize_space_0
Definition pugixml.cc:9597
@ ast_func_boolean
Definition pugixml.cc:9600
@ ast_func_count
Definition pugixml.cc:9578
@ ast_func_substring_after
Definition pugixml.cc:9592
@ ast_func_namespace_uri_1
Definition pugixml.cc:9583
@ ast_func_translate
Definition pugixml.cc:9599
@ ast_func_round
Definition pugixml.cc:9610
@ ast_func_number_1
Definition pugixml.cc:9606
@ ast_func_string_length_1
Definition pugixml.cc:9596
@ ast_func_starts_with
Definition pugixml.cc:9589
@ ast_func_false
Definition pugixml.cc:9603
@ ast_func_local_name_0
Definition pugixml.cc:9580
@ ast_func_id
Definition pugixml.cc:9579

Referenced by parse_primary_expression().

◆ parse_location_path()

xpath_ast_node * xpath_parser::parse_location_path ( )
inline

Definition at line 11983 of file pugixml.cc.

11984 {
11985 if (_lexer.current() == lex_slash)
11986 {
11987 _lexer.next();
11988
11989 xpath_ast_node* n = alloc_node(ast_step_root, xpath_type_node_set);
11990 if (!n) return 0;
11991
11992 // relative location path can start from axis_attribute, dot, double_dot, multiply and string lexemes; any other lexeme means standalone root path
11993 lexeme_t l = _lexer.current();
11994
11995 if (l == lex_string || l == lex_axis_attribute || l == lex_dot || l == lex_double_dot || l == lex_multiply)
11997 else
11998 return n;
11999 }
12000 else if (_lexer.current() == lex_double_slash)
12001 {
12002 _lexer.next();
12003
12004 xpath_ast_node* n = alloc_node(ast_step_root, xpath_type_node_set);
12005 if (!n) return 0;
12006
12008 if (!n) return 0;
12009
12011 }
12012
12013 // else clause moved outside of if because of bogus warning 'control may reach end of non-void function being inlined' in gcc 4.0.1
12015 }
@ ast_step
Definition pugixml.cc:9611
@ ast_step_root
Definition pugixml.cc:9612
lexeme_t
Definition pugixml.cc:9200
@ lex_multiply
Definition pugixml.cc:9210
@ lex_double_slash
Definition pugixml.cc:9218
@ lex_axis_attribute
Definition pugixml.cc:9223
@ lex_slash
Definition pugixml.cc:9217
@ lex_dot
Definition pugixml.cc:9224
@ lex_string
Definition pugixml.cc:9221
@ lex_double_dot
Definition pugixml.cc:9225
@ nodetest_type_node
Definition pugixml.cc:9639
xpath_ast_node * parse_relative_location_path(xpath_ast_node *set)
Definition pugixml.cc:11949

Referenced by parse_path_or_unary_expression().

◆ parse_node_test_type()

nodetest_t xpath_parser::parse_node_test_type ( const xpath_lexer_string & name)
inline

Definition at line 11585 of file pugixml.cc.

11586 {
11587 switch (name.begin[0])
11588 {
11589 case 'c':
11590 if (name == PUGIXML_TEXT("comment"))
11591 return nodetest_type_comment;
11592
11593 break;
11594
11595 case 'n':
11596 if (name == PUGIXML_TEXT("node"))
11597 return nodetest_type_node;
11598
11599 break;
11600
11601 case 'p':
11602 if (name == PUGIXML_TEXT("processing-instruction"))
11603 return nodetest_type_pi;
11604
11605 break;
11606
11607 case 't':
11608 if (name == PUGIXML_TEXT("text"))
11609 return nodetest_type_text;
11610
11611 break;
11612
11613 default:
11614 break;
11615 }
11616
11617 return nodetest_none;
11618 }
@ nodetest_none
Definition pugixml.cc:9637
@ nodetest_type_text
Definition pugixml.cc:9642
@ nodetest_type_comment
Definition pugixml.cc:9640
@ nodetest_type_pi
Definition pugixml.cc:9641

Referenced by parse_path_or_unary_expression(), and parse_step().

◆ parse_path_or_unary_expression()

xpath_ast_node * xpath_parser::parse_path_or_unary_expression ( )
inline

Definition at line 12023 of file pugixml.cc.

12024 {
12025 // Clarification.
12026 // PathExpr begins with either LocationPath or FilterExpr.
12027 // FilterExpr begins with PrimaryExpr
12028 // PrimaryExpr begins with '$' in case of it being a variable reference,
12029 // '(' in case of it being an expression, string literal, number constant or
12030 // function call.
12031 if (_lexer.current() == lex_var_ref || _lexer.current() == lex_open_brace ||
12032 _lexer.current() == lex_quoted_string || _lexer.current() == lex_number ||
12033 _lexer.current() == lex_string)
12034 {
12035 if (_lexer.current() == lex_string)
12036 {
12037 // This is either a function call, or not - if not, we shall proceed with location path
12038 const char_t* state = _lexer.state();
12039
12040 while (PUGI__IS_CHARTYPE(*state, ct_space)) ++state;
12041
12042 if (*state != '(')
12043 return parse_location_path();
12044
12045 // This looks like a function call; however this still can be a node-test. Check it.
12046 if (parse_node_test_type(_lexer.contents()) != nodetest_none)
12047 return parse_location_path();
12048 }
12049
12050 xpath_ast_node* n = parse_filter_expression();
12051 if (!n) return 0;
12052
12053 if (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash)
12054 {
12055 lexeme_t l = _lexer.current();
12056 _lexer.next();
12057
12058 if (l == lex_double_slash)
12059 {
12060 if (n->rettype() != xpath_type_node_set)
12061 return error("Step has to be applied to node set");
12062
12064 if (!n) return 0;
12065 }
12066
12067 // select from location path
12069 }
12070
12071 return n;
12072 }
12073 else if (_lexer.current() == lex_minus)
12074 {
12075 _lexer.next();
12076
12077 // precedence 7+ - only parses union expressions
12078 xpath_ast_node* n = parse_expression(7);
12079 if (!n) return 0;
12080
12081 return alloc_node(ast_op_negate, xpath_type_number, n);
12082 }
12083 else
12084 {
12085 return parse_location_path();
12086 }
12087 }
@ ast_op_negate
Definition pugixml.cc:9569
@ lex_quoted_string
Definition pugixml.cc:9215
@ lex_var_ref
Definition pugixml.cc:9212
@ lex_minus
Definition pugixml.cc:9209
@ lex_number
Definition pugixml.cc:9216
@ lex_open_brace
Definition pugixml.cc:9213
#define PUGI__IS_CHARTYPE(c, ct)
Definition pugixml.cc:1915
@ ct_space
Definition pugixml.cc:1850
xpath_ast_node * parse_filter_expression()
Definition pugixml.cc:11734
nodetest_t parse_node_test_type(const xpath_lexer_string &name)
Definition pugixml.cc:11585
xpath_ast_node * parse_location_path()
Definition pugixml.cc:11983

Referenced by parse_expression(), and parse_expression_rec().

◆ parse_primary_expression()

xpath_ast_node * xpath_parser::parse_primary_expression ( )
inline

Definition at line 11621 of file pugixml.cc.

11622 {
11623 switch (_lexer.current())
11624 {
11625 case lex_var_ref:
11626 {
11627 xpath_lexer_string name = _lexer.contents();
11628
11629 if (!_variables)
11630 return error("Unknown variable: variable set is not provided");
11631
11632 xpath_variable* var = 0;
11633 if (!get_variable_scratch(_scratch, _variables, name.begin, name.end, &var))
11634 return error_oom();
11635
11636 if (!var)
11637 return error("Unknown variable: variable set does not contain the given name");
11638
11639 _lexer.next();
11640
11641 return alloc_node(ast_variable, var->type(), var);
11642 }
11643
11644 case lex_open_brace:
11645 {
11646 _lexer.next();
11647
11648 xpath_ast_node* n = parse_expression();
11649 if (!n) return 0;
11650
11651 if (_lexer.current() != lex_close_brace)
11652 return error("Expected ')' to match an opening '('");
11653
11654 _lexer.next();
11655
11656 return n;
11657 }
11658
11659 case lex_quoted_string:
11660 {
11661 const char_t* value = alloc_string(_lexer.contents());
11662 if (!value) return 0;
11663
11664 _lexer.next();
11665
11666 return alloc_node(ast_string_constant, xpath_type_string, value);
11667 }
11668
11669 case lex_number:
11670 {
11671 double value = 0;
11672
11673 if (!convert_string_to_number_scratch(_scratch, _lexer.contents().begin, _lexer.contents().end, &value))
11674 return error_oom();
11675
11676 _lexer.next();
11677
11678 return alloc_node(ast_number_constant, xpath_type_number, value);
11679 }
11680
11681 case lex_string:
11682 {
11683 xpath_ast_node* args[2] = {0};
11684 size_t argc = 0;
11685
11686 xpath_lexer_string function = _lexer.contents();
11687 _lexer.next();
11688
11689 xpath_ast_node* last_arg = 0;
11690
11691 if (_lexer.current() != lex_open_brace)
11692 return error("Unrecognized function call");
11693 _lexer.next();
11694
11695 size_t old_depth = _depth;
11696
11697 while (_lexer.current() != lex_close_brace)
11698 {
11699 if (argc > 0)
11700 {
11701 if (_lexer.current() != lex_comma)
11702 return error("No comma between function arguments");
11703 _lexer.next();
11704 }
11705
11706 if (++_depth > xpath_ast_depth_limit)
11707 return error_rec();
11708
11709 xpath_ast_node* n = parse_expression();
11710 if (!n) return 0;
11711
11712 if (argc < 2) args[argc] = n;
11713 else last_arg->set_next(n);
11714
11715 argc++;
11716 last_arg = n;
11717 }
11718
11719 _lexer.next();
11720
11721 _depth = old_depth;
11722
11723 return parse_function(function, argc, args);
11724 }
11725
11726 default:
11727 return error("Unrecognizable primary expression");
11728 }
11729 }
G4double(*)(G4double) function
void set_next(xpath_ast_node *value)
Definition pugixml.cc:10460
@ ast_number_constant
Definition pugixml.cc:9574
@ ast_variable
Definition pugixml.cc:9575
@ ast_string_constant
Definition pugixml.cc:9573
@ lex_comma
Definition pugixml.cc:9222
@ lex_close_brace
Definition pugixml.cc:9214
PUGI__FN bool get_variable_scratch(char_t(&buffer)[32], xpath_variable_set *set, const char_t *begin, const char_t *end, xpath_variable **out_result)
Definition pugixml.cc:8947
PUGI__FN bool convert_string_to_number_scratch(char_t(&buffer)[32], const char_t *begin, const char_t *end, double *out_result)
Definition pugixml.cc:8558
xpath_ast_node * error_oom()
Definition pugixml.cc:11327
const char_t * alloc_string(const xpath_lexer_string &value)
Definition pugixml.cc:11381
xpath_ast_node * parse_function(const xpath_lexer_string &name, size_t argc, xpath_ast_node *args[2])
Definition pugixml.cc:11397
char_t _scratch[32]
Definition pugixml.cc:11315

Referenced by parse_filter_expression().

◆ parse_relative_location_path()

xpath_ast_node * xpath_parser::parse_relative_location_path ( xpath_ast_node * set)
inline

Definition at line 11949 of file pugixml.cc.

11950 {
11951 xpath_ast_node* n = parse_step(set);
11952 if (!n) return 0;
11953
11954 size_t old_depth = _depth;
11955
11956 while (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash)
11957 {
11958 lexeme_t l = _lexer.current();
11959 _lexer.next();
11960
11961 if (l == lex_double_slash)
11962 {
11964 if (!n) return 0;
11965
11966 ++_depth;
11967 }
11968
11969 if (++_depth > xpath_ast_depth_limit)
11970 return error_rec();
11971
11972 n = parse_step(n);
11973 if (!n) return 0;
11974 }
11975
11976 _depth = old_depth;
11977
11978 return n;
11979 }
xpath_ast_node * parse_step(xpath_ast_node *set)
Definition pugixml.cc:11773

Referenced by parse_location_path(), and parse_path_or_unary_expression().

◆ parse_step()

xpath_ast_node * xpath_parser::parse_step ( xpath_ast_node * set)
inline

Definition at line 11773 of file pugixml.cc.

11774 {
11775 if (set && set->rettype() != xpath_type_node_set)
11776 return error("Step has to be applied to node set");
11777
11778 bool axis_specified = false;
11779 axis_t axis = axis_child; // implied child axis
11780
11781 if (_lexer.current() == lex_axis_attribute)
11782 {
11784 axis_specified = true;
11785
11786 _lexer.next();
11787 }
11788 else if (_lexer.current() == lex_dot)
11789 {
11790 _lexer.next();
11791
11792 if (_lexer.current() == lex_open_square_brace)
11793 return error("Predicates are not allowed after an abbreviated step");
11794
11796 }
11797 else if (_lexer.current() == lex_double_dot)
11798 {
11799 _lexer.next();
11800
11801 if (_lexer.current() == lex_open_square_brace)
11802 return error("Predicates are not allowed after an abbreviated step");
11803
11805 }
11806
11807 nodetest_t nt_type = nodetest_none;
11808 xpath_lexer_string nt_name;
11809
11810 if (_lexer.current() == lex_string)
11811 {
11812 // node name test
11813 nt_name = _lexer.contents();
11814 _lexer.next();
11815
11816 // was it an axis name?
11817 if (_lexer.current() == lex_double_colon)
11818 {
11819 // parse axis name
11820 if (axis_specified)
11821 return error("Two axis specifiers in one step");
11822
11823 axis = parse_axis_name(nt_name, axis_specified);
11824
11825 if (!axis_specified)
11826 return error("Unknown axis");
11827
11828 // read actual node test
11829 _lexer.next();
11830
11831 if (_lexer.current() == lex_multiply)
11832 {
11833 nt_type = nodetest_all;
11834 nt_name = xpath_lexer_string();
11835 _lexer.next();
11836 }
11837 else if (_lexer.current() == lex_string)
11838 {
11839 nt_name = _lexer.contents();
11840 _lexer.next();
11841 }
11842 else
11843 {
11844 return error("Unrecognized node test");
11845 }
11846 }
11847
11848 if (nt_type == nodetest_none)
11849 {
11850 // node type test or processing-instruction
11851 if (_lexer.current() == lex_open_brace)
11852 {
11853 _lexer.next();
11854
11855 if (_lexer.current() == lex_close_brace)
11856 {
11857 _lexer.next();
11858
11859 nt_type = parse_node_test_type(nt_name);
11860
11861 if (nt_type == nodetest_none)
11862 return error("Unrecognized node type");
11863
11864 nt_name = xpath_lexer_string();
11865 }
11866 else if (nt_name == PUGIXML_TEXT("processing-instruction"))
11867 {
11868 if (_lexer.current() != lex_quoted_string)
11869 return error("Only literals are allowed as arguments to processing-instruction()");
11870
11871 nt_type = nodetest_pi;
11872 nt_name = _lexer.contents();
11873 _lexer.next();
11874
11875 if (_lexer.current() != lex_close_brace)
11876 return error("Unmatched brace near processing-instruction()");
11877 _lexer.next();
11878 }
11879 else
11880 {
11881 return error("Unmatched brace near node type test");
11882 }
11883 }
11884 // QName or NCName:*
11885 else
11886 {
11887 if (nt_name.end - nt_name.begin > 2 && nt_name.end[-2] == ':' && nt_name.end[-1] == '*') // NCName:*
11888 {
11889 nt_name.end--; // erase *
11890
11891 nt_type = nodetest_all_in_namespace;
11892 }
11893 else
11894 {
11895 nt_type = nodetest_name;
11896 }
11897 }
11898 }
11899 }
11900 else if (_lexer.current() == lex_multiply)
11901 {
11902 nt_type = nodetest_all;
11903 _lexer.next();
11904 }
11905 else
11906 {
11907 return error("Unrecognized node test");
11908 }
11909
11910 const char_t* nt_name_copy = alloc_string(nt_name);
11911 if (!nt_name_copy) return 0;
11912
11913 xpath_ast_node* n = alloc_node(ast_step, set, axis, nt_type, nt_name_copy);
11914 if (!n) return 0;
11915
11916 size_t old_depth = _depth;
11917
11918 xpath_ast_node* last = 0;
11919
11920 while (_lexer.current() == lex_open_square_brace)
11921 {
11922 _lexer.next();
11923
11924 if (++_depth > xpath_ast_depth_limit)
11925 return error_rec();
11926
11927 xpath_ast_node* expr = parse_expression();
11928 if (!expr) return 0;
11929
11930 xpath_ast_node* pred = alloc_node(ast_predicate, 0, expr, predicate_default);
11931 if (!pred) return 0;
11932
11933 if (_lexer.current() != lex_close_square_brace)
11934 return error("Expected ']' to match an opening '['");
11935 _lexer.next();
11936
11937 if (last) last->set_next(pred);
11938 else n->set_right(pred);
11939
11940 last = pred;
11941 }
11942
11943 _depth = old_depth;
11944
11945 return n;
11946 }
@ ast_predicate
Definition pugixml.cc:9571
@ lex_double_colon
Definition pugixml.cc:9226
nodetest_t
Definition pugixml.cc:9636
@ nodetest_all
Definition pugixml.cc:9644
@ nodetest_name
Definition pugixml.cc:9638
@ nodetest_all_in_namespace
Definition pugixml.cc:9645
@ nodetest_pi
Definition pugixml.cc:9643
axis_t
Definition pugixml.cc:9619
axis_t parse_axis_name(const xpath_lexer_string &name, bool &specified)
Definition pugixml.cc:11517

Referenced by parse_relative_location_path().

Member Data Documentation

◆ _alloc

xpath_allocator* xpath_parser::_alloc

Definition at line 11307 of file pugixml.cc.

Referenced by alloc_node(), alloc_string(), error_oom(), and xpath_parser().

◆ _depth

◆ _lexer

◆ _query

const char_t* xpath_parser::_query

Definition at line 11310 of file pugixml.cc.

Referenced by error(), and xpath_parser().

◆ _result

xpath_parse_result* xpath_parser::_result

Definition at line 11313 of file pugixml.cc.

Referenced by error(), and xpath_parser().

◆ _scratch

char_t xpath_parser::_scratch[32]

Definition at line 11315 of file pugixml.cc.

Referenced by parse_primary_expression().

◆ _variables

xpath_variable_set* xpath_parser::_variables

Definition at line 11311 of file pugixml.cc.

Referenced by parse_primary_expression(), and xpath_parser().


The documentation for this struct was generated from the following file: