// File: jliesch[P]ofxget/pugixml/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 (!n) return 0;

				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)
							return error("Step has to be applied to node set");

						n = alloc_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0);
						if (!n) return 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* n = parse_expression(7);
				if (!n) return 0;

				return alloc_node(ast_op_negate, xpath_type_number, n);
			}
			else
			{
				return parse_location_path();
			}
		}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x38(%rbp)
addq $0x8, %rdi
callq 0x5af60
cmpl $0xb, %eax
je 0x5b03e
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x5af60
cmpl $0xc, %eax
je 0x5b03e
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x5af60
cmpl $0xe, %eax
je 0x5b03e
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x5af60
cmpl $0xf, %eax
je 0x5b03e
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x5af60
cmpl $0x14, %eax
jne 0x5b1cb
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x5af60
cmpl $0x14, %eax
jne 0x5b0df
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x5b480
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movzbl (%rax), %eax
movl %eax, %ecx
leaq 0x1005b(%rip), %rax     # 0x6b0d0
movzbl (%rax,%rcx), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x5b08f
movq -0x18(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x18(%rbp)
jmp 0x5b065
movq -0x18(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x28, %eax
je 0x5b0ad
movq -0x38(%rbp), %rdi
callq 0x5b4a0
movq %rax, -0x8(%rbp)
jmp 0x5b23c
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x5b700
movq -0x38(%rbp), %rdi
movq %rax, %rsi
callq 0x5b620
cmpl $0x0, %eax
je 0x5b0dd
movq -0x38(%rbp), %rdi
callq 0x5b4a0
movq %rax, -0x8(%rbp)
jmp 0x5b23c
jmp 0x5b0df
movq -0x38(%rbp), %rdi
callq 0x5b790
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0x5b100
movq $0x0, -0x8(%rbp)
jmp 0x5b23c
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x5af60
cmpl $0x10, %eax
je 0x5b128
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x5af60
cmpl $0x11, %eax
jne 0x5b1c1
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x5af60
movq -0x38(%rbp), %rdi
movl %eax, -0x24(%rbp)
addq $0x8, %rdi
callq 0x5a830
cmpl $0x11, -0x24(%rbp)
jne 0x5b1ae
movq -0x20(%rbp), %rdi
callq 0x4b490
cmpl $0x1, %eax
je 0x5b172
movq -0x38(%rbp), %rdi
leaq 0x12259(%rip), %rsi     # 0x6d3bd
callq 0x5af80
movq %rax, -0x8(%rbp)
jmp 0x5b23c
movq -0x38(%rbp), %rdi
movq -0x20(%rbp), %rdx
movl $0x38, %esi
movl $0x5, %ecx
movl $0x2, %r8d
xorl %eax, %eax
movl %eax, %r9d
callq 0x5b8b0
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0x5b1ac
movq $0x0, -0x8(%rbp)
jmp 0x5b23c
jmp 0x5b1ae
movq -0x38(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x5b920
movq %rax, -0x8(%rbp)
jmp 0x5b23c
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x5b23c
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x5af60
cmpl $0x8, %eax
jne 0x5b22f
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x5a830
movq -0x38(%rbp), %rdi
movl $0x7, %esi
callq 0x5af10
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x5b20d
movq $0x0, -0x8(%rbp)
jmp 0x5b23c
movq -0x38(%rbp), %rdi
movq -0x30(%rbp), %rcx
movl $0xe, %esi
movl $0x2, %edx
xorl %eax, %eax
movl %eax, %r8d
callq 0x5ba30
movq %rax, -0x8(%rbp)
jmp 0x5b23c
movq -0x38(%rbp), %rdi
callq 0x5b4a0
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)