Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep AxisSpecifier ::= AxisName '::' | '@'? NodeTest ::= NameTest | NodeType '(' ')' | 'processing-instruction' '(' Literal ')' NameTest ::= '*' | NCName ':' '*' | QName AbbreviatedStep ::= '.' | '..'
| 9927 | // NameTest ::= '*' | NCName ':' '*' | QName |
| 9928 | // AbbreviatedStep ::= '.' | '..' |
| 9929 | xpath_ast_node* parse_step(xpath_ast_node* set) |
| 9930 | { |
| 9931 | if (set && set->rettype() != xpath_type_node_set) |
| 9932 | throw_error("Step has to be applied to node set"); |
| 9933 | |
| 9934 | bool axis_specified = false; |
| 9935 | axis_t axis = axis_child; // implied child axis |
| 9936 | |
| 9937 | if (_lexer.current() == lex_axis_attribute) |
| 9938 | { |
| 9939 | axis = axis_attribute; |
| 9940 | axis_specified = true; |
| 9941 | |
| 9942 | _lexer.next(); |
| 9943 | } |
| 9944 | else if (_lexer.current() == lex_dot) |
| 9945 | { |
| 9946 | _lexer.next(); |
| 9947 | |
| 9948 | return new (alloc_node()) xpath_ast_node(ast_step, set, axis_self, nodetest_type_node, 0); |
| 9949 | } |
| 9950 | else if (_lexer.current() == lex_double_dot) |
| 9951 | { |
| 9952 | _lexer.next(); |
| 9953 | |
| 9954 | return new (alloc_node()) xpath_ast_node(ast_step, set, axis_parent, nodetest_type_node, 0); |
| 9955 | } |
| 9956 | |
| 9957 | nodetest_t nt_type = nodetest_none; |
| 9958 | xpath_lexer_string nt_name; |
| 9959 | |
| 9960 | if (_lexer.current() == lex_string) |
| 9961 | { |
| 9962 | // node name test |
| 9963 | nt_name = _lexer.contents(); |
| 9964 | _lexer.next(); |
| 9965 | |
| 9966 | // was it an axis name? |
| 9967 | if (_lexer.current() == lex_double_colon) |
| 9968 | { |
| 9969 | // parse axis name |
| 9970 | if (axis_specified) |
| 9971 | throw_error("Two axis specifiers in one step"); |
| 9972 | |
| 9973 | axis = parse_axis_name(nt_name, axis_specified); |
| 9974 | |
| 9975 | if (!axis_specified) |
| 9976 | throw_error("Unknown axis"); |
| 9977 | |
| 9978 | // read actual node test |
| 9979 | _lexer.next(); |
| 9980 | |
| 9981 | if (_lexer.current() == lex_multiply) |
| 9982 | { |
| 9983 | nt_type = nodetest_all; |
| 9984 | nt_name = xpath_lexer_string(); |
| 9985 | _lexer.next(); |
| 9986 | } |