Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep AxisSpecifier ::= AxisName '::' | '@'? NodeTest ::= NameTest | NodeType '(' ')' | 'processing-instruction' '(' Literal ')' NameTest ::= '*' | NCName ':' '*' | QName AbbreviatedStep ::= '.' | '..'
| 10456 | // NameTest ::= '*' | NCName ':' '*' | QName |
| 10457 | // AbbreviatedStep ::= '.' | '..' |
| 10458 | xpath_ast_node* parse_step(xpath_ast_node* set) |
| 10459 | { |
| 10460 | if (set && set->rettype() != xpath_type_node_set) |
| 10461 | throw_error("Step has to be applied to node set"); |
| 10462 | |
| 10463 | bool axis_specified = false; |
| 10464 | axis_t axis = axis_child; // implied child axis |
| 10465 | |
| 10466 | if (_lexer.current() == lex_axis_attribute) |
| 10467 | { |
| 10468 | axis = axis_attribute; |
| 10469 | axis_specified = true; |
| 10470 | |
| 10471 | _lexer.next(); |
| 10472 | } |
| 10473 | else if (_lexer.current() == lex_dot) |
| 10474 | { |
| 10475 | _lexer.next(); |
| 10476 | |
| 10477 | return new (alloc_node()) xpath_ast_node(ast_step, set, axis_self, nodetest_type_node, 0); |
| 10478 | } |
| 10479 | else if (_lexer.current() == lex_double_dot) |
| 10480 | { |
| 10481 | _lexer.next(); |
| 10482 | |
| 10483 | return new (alloc_node()) xpath_ast_node(ast_step, set, axis_parent, nodetest_type_node, 0); |
| 10484 | } |
| 10485 | |
| 10486 | nodetest_t nt_type = nodetest_none; |
| 10487 | xpath_lexer_string nt_name; |
| 10488 | |
| 10489 | if (_lexer.current() == lex_string) |
| 10490 | { |
| 10491 | // node name test |
| 10492 | nt_name = _lexer.contents(); |
| 10493 | _lexer.next(); |
| 10494 | |
| 10495 | // was it an axis name? |
| 10496 | if (_lexer.current() == lex_double_colon) |
| 10497 | { |
| 10498 | // parse axis name |
| 10499 | if (axis_specified) throw_error("Two axis specifiers in one step"); |
| 10500 | |
| 10501 | axis = parse_axis_name(nt_name, axis_specified); |
| 10502 | |
| 10503 | if (!axis_specified) throw_error("Unknown axis"); |
| 10504 | |
| 10505 | // read actual node test |
| 10506 | _lexer.next(); |
| 10507 | |
| 10508 | if (_lexer.current() == lex_multiply) |
| 10509 | { |
| 10510 | nt_type = nodetest_all; |
| 10511 | nt_name = xpath_lexer_string(); |
| 10512 | _lexer.next(); |
| 10513 | } |
| 10514 | else if (_lexer.current() == lex_string) |
| 10515 | { |