// File: neguse[P]no/lang.cc
// Function: Lang::ParseNode(Input&, int)
Node::Ref ParseNode(Input &input, int level = 0) {
    char c;
    for (;;) {
      c = input.Get();
      // skip space
      if (c == ' ' || c == '\t' || c == '\n') {
        continue;
      } else if (c == EOF) {
        return nullptr;
      }
      break;
    }

    assert(syntax_.find(c) != syntax_.end());

    auto syntax = syntax_[c];
    auto n = std::make_shared<Node>(Node{c});
    n->st = syntax.st;
    n->pos = input.pos();
    if (syntax.ht == HierarchicalType::Parent) {
      n->a = this->ParseNode(input, level + 1);
      n->d = this->ParseNode(input, level + 1);
    }
    return n;
  }

// Assembly:
subq $0x118, %rsp            # imm = 0x118
movq %rdi, 0x20(%rsp)
movq %rdi, %rax
movq %rax, 0x28(%rsp)
movq %rdi, 0x110(%rsp)
movq %rsi, 0x108(%rsp)
movq %rdx, 0x100(%rsp)
movl %ecx, 0xfc(%rsp)
movq 0x108(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x100(%rsp), %rdi
callq 0x81e0
movb %al, 0xfb(%rsp)
movsbl 0xfb(%rsp), %eax
cmpl $0x20, %eax
je 0x7f1b
movsbl 0xfb(%rsp), %eax
cmpl $0x9, %eax
je 0x7f1b
movsbl 0xfb(%rsp), %eax
cmpl $0xa, %eax
jne 0x7f1d
jmp 0x7ee0
movsbl 0xfb(%rsp), %eax
cmpl $-0x1, %eax
jne 0x7f3d
movq 0x20(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x8260
jmp 0x818f
jmp 0x7f3f
jmp 0x7f41
movq 0x30(%rsp), %rdi
leaq 0xfb(%rsp), %rsi
callq 0x82a0
movq 0x30(%rsp), %rdi
movq %rax, 0xf0(%rsp)
callq 0x6460
movq %rax, 0xe8(%rsp)
leaq 0xf0(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x8280
testb $0x1, %al
jne 0x7f88
jmp 0x7f8a
jmp 0x7fa9
leaq 0x91b0(%rip), %rdi      # 0x11141
leaq 0x9182(%rip), %rsi      # 0x1111a
movl $0x125, %edx            # imm = 0x125
leaq 0x91be(%rip), %rcx      # 0x11162
callq 0x20d0
movq 0x30(%rsp), %rdi
leaq 0xfb(%rsp), %rsi
callq 0x5440
movq %rax, %rsi
leaq 0xb0(%rsp), %rdi
callq 0x82d0
movb $0x0, 0xaf(%rsp)
movb 0xfb(%rsp), %al
movb %al, 0x70(%rsp)
leaq 0x78(%rsp), %rdi
callq 0x83d0
leaq 0x88(%rsp), %rdi
callq 0x83d0
movq 0x20(%rsp), %rdi
movl $0x0, 0x98(%rsp)
movl $0x0, 0x9c(%rsp)
movl $0x0, 0xa0(%rsp)
leaq 0x70(%rsp), %rsi
callq 0x8350
jmp 0x8027
leaq 0x70(%rsp), %rdi
callq 0x83e0
movq 0x20(%rsp), %rdi
movl 0xb4(%rsp), %eax
movl %eax, 0x14(%rsp)
callq 0x8410
movl 0x14(%rsp), %ecx
movl %ecx, 0x30(%rax)
movq 0x100(%rsp), %rdi
callq 0x8420
movq %rax, 0x18(%rsp)
jmp 0x8061
movq 0x20(%rsp), %rdi
movq 0x18(%rsp), %rax
movq %rax, 0x5c(%rsp)
callq 0x8410
movq 0x5c(%rsp), %rcx
movq %rcx, 0x28(%rax)
cmpl $0x1, 0xb0(%rsp)
jne 0x8155
movq 0x30(%rsp), %rsi
movq 0x100(%rsp), %rdx
movl 0xfc(%rsp), %ecx
incl %ecx
leaq 0x48(%rsp), %rdi
callq 0x7ea0
jmp 0x80ae
movq 0x20(%rsp), %rdi
callq 0x8410
movq %rax, %rdi
addq $0x8, %rdi
leaq 0x48(%rsp), %rsi
movq %rsi, 0x8(%rsp)
callq 0x8440
movq 0x8(%rsp), %rdi
callq 0x4940
movq 0x30(%rsp), %rsi
movq 0x100(%rsp), %rdx
movl 0xfc(%rsp), %ecx
incl %ecx
leaq 0x38(%rsp), %rdi
callq 0x7ea0
jmp 0x80fa
movq 0x20(%rsp), %rdi
callq 0x8410
movq %rax, %rdi
addq $0x18, %rdi
leaq 0x38(%rsp), %rsi
callq 0x8440
leaq 0x38(%rsp), %rdi
callq 0x4940
jmp 0x8155
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x68(%rsp)
movl %eax, 0x64(%rsp)
leaq 0x70(%rsp), %rdi
callq 0x83e0
jmp 0x8180
movq 0x20(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x68(%rsp)
movl %eax, 0x64(%rsp)
callq 0x4940
jmp 0x8180
movb $0x1, 0xaf(%rsp)
testb $0x1, 0xaf(%rsp)
jne 0x8171
movq 0x20(%rsp), %rdi
callq 0x4940
leaq 0xb0(%rsp), %rdi
callq 0x5590
jmp 0x818f
leaq 0xb0(%rsp), %rdi
callq 0x5590
jmp 0x819c
movq 0x28(%rsp), %rax
addq $0x118, %rsp            # imm = 0x118
retq
movq 0x68(%rsp), %rdi
callq 0x21d0
nopw %cs:(%rax,%rax)