// File: adamiaonr[P]rid-analytics/src/pugixml.cpp
// Function: pugi::impl::(anonymous namespace)::xpath_parser::parse_path_or_unary_expression()
xpath_ast_node* parse_path_or_unary_expression()
		{
			// Clarification.
			// PathExpr begins with either LocationPath or FilterExpr.
			// FilterExpr begins with PrimaryExpr
			// PrimaryExpr begins with '$' in case of it being a variable reference,
			// '(' in case of it being an expression, string literal, number constant or
			// function call.

			if (_lexer.current() == lex_var_ref || _lexer.current() == lex_open_brace ||
				_lexer.current() == lex_quoted_string || _lexer.current() == lex_number ||
				_lexer.current() == lex_string)
			{
				if (_lexer.current() == lex_string)
				{
					// This is either a function call, or not - if not, we shall proceed with location path
					const char_t* state = _lexer.state();

					while (PUGI__IS_CHARTYPE(*state, ct_space)) ++state;

					if (*state != '(') return parse_location_path();

					// This looks like a function call; however this still can be a node-test. Check it.
					if (parse_node_test_type(_lexer.contents()) != nodetest_none) return parse_location_path();
				}

				xpath_ast_node* n = parse_filter_expression();

				if (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash)
				{
					lexeme_t l = _lexer.current();
					_lexer.next();

					if (l == lex_double_slash)
					{
						if (n->rettype() != xpath_type_node_set) throw_error("Step has to be applied to node set");

						n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0);
					}

					// select from location path
					return parse_relative_location_path(n);
				}

				return n;
			}
			else if (_lexer.current() == lex_minus)
			{
				_lexer.next();

				// precedence 7+ - only parses union expressions
				xpath_ast_node* expr = parse_expression_rec(parse_path_or_unary_expression(), 7);

				return new (alloc_node()) xpath_ast_node(ast_op_negate, xpath_type_number, expr);
			}
			else
				return parse_location_path();
		}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x38(%rbp)
addq $0x8, %rdi
callq 0x1eed0
cmpl $0xb, %eax
je 0x1f1ee
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x1eed0
cmpl $0xc, %eax
je 0x1f1ee
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x1eed0
cmpl $0xe, %eax
je 0x1f1ee
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x1eed0
cmpl $0xf, %eax
je 0x1f1ee
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x1eed0
cmpl $0x14, %eax
jne 0x1f35b
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x1eed0
cmpl $0x14, %eax
jne 0x1f28f
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x1f970
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movzbl (%rax), %eax
movl %eax, %ecx
leaq 0x3f6cb(%rip), %rax     # 0x5e8f0
movzbl (%rax,%rcx), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x1f23f
movq -0x18(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x18(%rbp)
jmp 0x1f215
movq -0x18(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x28, %eax
je 0x1f25d
movq -0x38(%rbp), %rdi
callq 0x1f990
movq %rax, -0x8(%rbp)
jmp 0x1f3d7
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x1f6e0
movq -0x38(%rbp), %rdi
movq %rax, %rsi
callq 0x1fb00
cmpl $0x0, %eax
je 0x1f28d
movq -0x38(%rbp), %rdi
callq 0x1f990
movq %rax, -0x8(%rbp)
jmp 0x1f3d7
jmp 0x1f28f
movq -0x38(%rbp), %rdi
callq 0x1fbe0
movq -0x38(%rbp), %rdi
movq %rax, -0x20(%rbp)
addq $0x8, %rdi
callq 0x1eed0
cmpl $0x10, %eax
je 0x1f2c4
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x1eed0
cmpl $0x11, %eax
jne 0x1f351
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x1eed0
movq -0x38(%rbp), %rdi
movl %eax, -0x24(%rbp)
addq $0x8, %rdi
callq 0x1e7c0
cmpl $0x11, -0x24(%rbp)
jne 0x1f33b
movq -0x20(%rbp), %rdi
callq 0x10790
cmpl $0x1, %eax
je 0x1f305
movq -0x38(%rbp), %rdi
leaq 0x419b1(%rip), %rsi     # 0x60cb1
callq 0x1eef0
movq -0x38(%rbp), %rdi
callq 0x1f650
movq %rax, %rdi
movq %rdi, -0x40(%rbp)
movq -0x20(%rbp), %rdx
movl $0x38, %esi
movl $0x5, %ecx
movl $0x2, %r8d
xorl %eax, %eax
movl %eax, %r9d
callq 0x1fcc0
movq -0x40(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x38(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x1fd50
movq %rax, -0x8(%rbp)
jmp 0x1f3d7
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x1f3d7
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x1eed0
cmpl $0x8, %eax
jne 0x1f3ca
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x1e7c0
movq -0x38(%rbp), %rdi
callq 0x1f180
movq -0x38(%rbp), %rdi
movq %rax, %rsi
movl $0x7, %edx
callq 0x1ef90
movq -0x38(%rbp), %rdi
movq %rax, -0x30(%rbp)
callq 0x1f650
movq %rax, %rdi
movq %rdi, -0x48(%rbp)
movq -0x30(%rbp), %rcx
movl $0xe, %esi
movl $0x2, %edx
xorl %eax, %eax
movl %eax, %r8d
callq 0x1f690
movq -0x48(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x1f3d7
movq -0x38(%rbp), %rdi
callq 0x1f990
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)