// File: /workspace/github_cpp_makefile_star2_O3/pfnet-research[P]pml/src/parser.cpp
// Function: next_token(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, unsigned long)
token_t next_token(std::string const& input, size_t pos) {
    using kind_t = token_t::kind_t;

    pos = skip_spaces(input, pos);

    if (pos >= input.size()) {
        return token_t {
            token_t::kind_t::Eof, pos, ""
        };
    }

    if (std::isdigit(input[pos]) || (input[pos] == '-' && std::isdigit(input[pos+1]))) {
        size_t len = 1;
        while (std::isdigit(input[pos + len]) && pos + len < input.size())
            ++len;
        return token_t {
            kind_t::Int, pos, input.substr(pos, len)
        };
    }

    std::unordered_map<std::string, kind_t> string_token = {
        {"->", kind_t::Arrow},
        {"=>", kind_t::FatArrow},
        {"==", kind_t::DoubleEq},
        {"!=", kind_t::Neq},
        {"<=", kind_t::Leq},
        {">=", kind_t::Geq},
        {"\\/", kind_t::Or},
        {"/\\", kind_t::And}
    };
    for (auto const& pair : string_token) {
        if (pair.first == input.substr(pos, pair.first.size()))
            return token_t {pair.second, pos, pair.first};
    }

    std::unordered_map<char, token_t::kind_t> char_token = {
        {'=', kind_t::Eq},
        {'+', kind_t::Plus},
        {'-', kind_t::Minus},
        {'*', kind_t::Star},
        {'/', kind_t::Slash},
        {',', kind_t::Comma},
        {'&', kind_t::Amp},
        {'\\', kind_t::BackSlash},
        {'|', kind_t::Bar},
        {':', kind_t::Colon},
        {'{', kind_t::LBrace},
        {'}', kind_t::RBrace},
        {'(', kind_t::LParen},
        {')', kind_t::RParen}
    };
    auto found_ch = char_token.find(input[pos]);
    if (found_ch != char_token.end()) {
        return token_t {
            found_ch->second, pos, std::string{found_ch->first}
        };
    }

    size_t len = ident_len(input, pos);
    if (len != 0) {
        std::unordered_map<std::string, token_t::kind_t> keywords = {
            {"let", kind_t::Let},
            {"letfun", kind_t::LetFun},
            {"in", kind_t::In},
            {"if", kind_t::If},
            {"else", kind_t::Else},
            {"then", kind_t::Then},
            {"rand", kind_t::Rand},
            {"true", kind_t::True},
            {"false", kind_t::False},
            {"Prob", kind_t::Prob},
            {"not", kind_t::Not},
            {"dummy", kind_t::Dummy}
        };
        std::string lexime = input.substr(pos, len);
        auto found_keyword = keywords.find(lexime);
        if (found_keyword != keywords.end()) {
            return token_t { found_keyword->second, pos, lexime };
        } else {
            return token_t { kind_t::Ident, pos,  lexime};
        }
    }

    throw std::runtime_error{"unknown token at " + std::to_string(pos) + " : " + input.substr(pos, 5) + ".."};
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x328, %rsp            # imm = 0x328
movq %rdx, %r12
movq %rdi, %rbx
movq (%rsi), %r14
movq %rsi, 0x10(%rsp)
movq 0x8(%rsi), %rbp
movq %r12, %r15
movsbl (%r14,%r12), %r13d
movl %r13d, %edi
callq 0x9060
incq %r12
testl %eax, %eax
je 0x1ba74
cmpq %rbp, %r15
jb 0x1ba58
leaq -0x1(%r12), %rax
cmpq %rbp, %r15
jae 0x1bad3
movq %rax, 0x18(%rsp)
leal -0x30(%r13), %eax
cmpl $0xa, %eax
jae 0x1bafd
xorl %eax, %eax
leaq (%r14,%rax), %rcx
movsbl (%r12,%rcx), %edx
addl $-0x30, %edx
leaq 0x1(%rax), %rcx
cmpl $0x9, %edx
ja 0x1baae
addq %r12, %rax
cmpq %rbp, %rax
movq %rcx, %rax
jb 0x1ba8e
movl $0x7, (%rbx)
movq 0x18(%rsp), %rdx
movq %rdx, 0x8(%rbx)
movq %rbx, %rdi
addq $0x10, %rdi
movq 0x10(%rsp), %rsi
callq 0x9310
jmp 0x1c1e3
movl $0x25, (%rbx)
movq %rax, 0x8(%rbx)
leaq 0x10(%rbx), %rdi
leaq 0x20(%rbx), %rax
movq %rax, 0x10(%rbx)
leaq 0x2b6b1(%rip), %rdx     # 0x471a1
movq %rdx, %rsi
callq 0x116f8
jmp 0x1c1e3
cmpb $0x2d, %r13b
jne 0x1bb14
movsbl (%r14,%r12), %eax
addl $-0x30, %eax
cmpl $0x9, %eax
jbe 0x1ba8c
leaq 0xc8(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x2c79f(%rip), %rsi     # 0x482c6
leaq 0x2c79a(%rip), %rdx     # 0x482c8
leaq 0xb8(%rsp), %r13
movq %r13, %rdi
callq 0x116f8
leaq 0xe0(%rsp), %rbp
movl $0xb, -0x8(%rbp)
leaq 0xf0(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x2c348(%rip), %rsi     # 0x47ea8
leaq 0x2c343(%rip), %rdx     # 0x47eaa
movq %rbp, %rdi
callq 0x116f8
leaq 0x108(%rsp), %rbp
movl $0xc, -0x8(%rbp)
leaq 0x118(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x2c747(%rip), %rsi     # 0x482d8
leaq 0x2c742(%rip), %rdx     # 0x482da
movq %rbp, %rdi
callq 0x116f8
leaq 0x130(%rsp), %rbp
movl $0x13, -0x8(%rbp)
leaq 0x140(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x2c2e2(%rip), %rsi     # 0x47ea4
leaq 0x2c2dd(%rip), %rdx     # 0x47ea6
movq %rbp, %rdi
callq 0x116f8
leaq 0x158(%rsp), %rbp
movl $0x14, -0x8(%rbp)
leaq 0x168(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x2b918(%rip), %rsi     # 0x4750b
leaq 0x2b913(%rip), %rdx     # 0x4750d
movq %rbp, %rdi
callq 0x116f8
leaq 0x180(%rsp), %rbp
movl $0x16, -0x8(%rbp)
leaq 0x190(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x2b8ea(%rip), %rsi     # 0x4750e
leaq 0x2b8e5(%rip), %rdx     # 0x47510
movq %rbp, %rdi
callq 0x116f8
leaq 0x1a8(%rsp), %rbp
movl $0x17, -0x8(%rbp)
leaq 0x1b8(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x2c674(%rip), %rsi     # 0x482c9
leaq 0x2c66f(%rip), %rdx     # 0x482cb
movq %rbp, %rdi
callq 0x116f8
leaq 0x1d0(%rsp), %rbp
movl $0x21, -0x8(%rbp)
leaq 0x1e0(%rsp), %r14
movq %r14, -0x10(%r14)
leaq 0x2c646(%rip), %rsi     # 0x482cc
leaq 0x2c641(%rip), %rdx     # 0x482ce
movq %rbp, %rdi
callq 0x116f8
leaq 0x1f8(%rsp), %rdx
movl $0x22, -0x8(%rdx)
leaq 0x20(%rsp), %rax
movq %rax, (%rsp)
leaq 0x2f0(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
leaq 0x2b8(%rsp), %r8
leaq 0x80(%rsp), %r9
xorl %ecx, %ecx
callq 0x2774e
movq $-0x140, %r13           # imm = 0xFEC0
movq 0x18(%rsp), %r15
movq -0x10(%r14), %rdi
cmpq %rdi, %r14
je 0x1bcf4
movq (%r14), %rsi
incq %rsi
callq 0x92e0
addq $-0x28, %r14
addq $0x28, %r13
jne 0x1bce0
movq 0x300(%rsp), %r14
testq %r14, %r14
je 0x1bda4
leaq 0xb8(%rsp), %r13
movq 0x10(%r14), %rcx
movq %r13, %rdi
movq 0x10(%rsp), %rsi
movq %r15, %rdx
callq 0x9310
movq 0x10(%r14), %rdx
cmpq 0xc0(%rsp), %rdx
jne 0x1bd5a
movq 0xb8(%rsp), %rbp
testq %rdx, %rdx
je 0x1bd67
movq 0x8(%r14), %rdi
movq %rbp, %rsi
callq 0x9300
testl %eax, %eax
sete %r15b
jmp 0x1bd6a
movq 0xb8(%rsp), %rbp
xorl %r15d, %r15d
jmp 0x1bd6a
movb $0x1, %r15b
leaq 0xc8(%rsp), %rax
cmpq %rax, %rbp
je 0x1bd8a
movq 0xc8(%rsp), %rsi
incq %rsi
movq %rbp, %rdi
callq 0x92e0
testb %r15b, %r15b
jne 0x1be36
movq (%r14), %r14
testq %r14, %r14
movq 0x18(%rsp), %r15
jne 0x1bd17
leaq 0x2c489(%rip), %rsi     # 0x48234
leaq 0xb8(%rsp), %rax
movl $0x1c, %ecx
movq %rax, %rdi
rep  movsl (%rsi), %es:(%rdi)
leaq 0x128(%rsp), %rdx
leaq 0x60(%rsp), %rcx
movq %rcx, (%rsp)
leaq 0x2b8(%rsp), %rdi
leaq 0x80(%rsp), %r8
leaq 0x20(%rsp), %r9
movq %rax, %rsi
xorl %ecx, %ecx
callq 0x27c72
movq 0x10(%rsp), %rax
movq (%rax), %rax
leaq (%rax,%r12), %rsi
decq %rsi
leaq 0x2b8(%rsp), %rdi
callq 0x28004
testq %rax, %rax
je 0x1be66
movl 0xc(%rax), %ecx
movl %ecx, (%rbx)
movq %r15, 0x8(%rbx)
movb 0x8(%rax), %al
leaq 0x20(%rbx), %rcx
movq %rcx, 0x10(%rbx)
movb %al, 0x20(%rbx)
movq $0x1, 0x18(%rbx)
movb $0x0, 0x21(%rbx)
jmp 0x1c1c9
movl 0x28(%r14), %eax
movl %eax, (%rbx)
movq 0x18(%rsp), %rax
movq %rax, 0x8(%rbx)
leaq 0x10(%rbx), %rdi
leaq 0x20(%rbx), %rax
movq %rax, 0x10(%rbx)
movq 0x8(%r14), %rsi
movq 0x10(%r14), %rdx
addq %rsi, %rdx
callq 0xac68
jmp 0x1c1d6
movq 0x10(%rsp), %rdi
movq %r15, %rsi
callq 0x1b9e2
testq %rax, %rax
je 0x1c1f8
movq %rax, %rbp
leaq 0xb8(%rsp), %r12
leaq 0xc8(%rsp), %rax
movq %rax, (%r12)
leaq 0x2f1db(%rip), %rsi     # 0x4b075
leaq 0x2f1d7(%rip), %rdx     # 0x4b078
movq %r12, %rdi
callq 0x116f8
leaq 0xe0(%rsp), %r13
movl $0x0, -0x8(%r13)
leaq 0xf0(%rsp), %rax
movq %rax, (%r13)
leaq 0x2c3d8(%rip), %rsi     # 0x482a4
leaq 0x2c3d7(%rip), %rdx     # 0x482aa
movq %r13, %rdi
callq 0x116f8
leaq 0x108(%rsp), %r13
movl $0x1, -0x8(%r13)
leaq 0x118(%rsp), %rax
movq %rax, (%r13)
leaq 0x2c3ad(%rip), %rsi     # 0x482ab
leaq 0x2c3a8(%rip), %rdx     # 0x482ad
movq %r13, %rdi
callq 0x116f8
leaq 0x130(%rsp), %r13
movl $0x2, -0x8(%r13)
leaq 0x140(%rsp), %rax
movq %rax, (%r13)
leaq 0x2c37e(%rip), %rsi     # 0x482ae
leaq 0x2c379(%rip), %rdx     # 0x482b0
movq %r13, %rdi
callq 0x116f8
leaq 0x158(%rsp), %r13
movl $0x3, -0x8(%r13)
leaq 0x168(%rsp), %rax
movq %rax, (%r13)
leaq 0x2c354(%rip), %rsi     # 0x482b6
leaq 0x2c351(%rip), %rdx     # 0x482ba
movq %r13, %rdi
callq 0x116f8
leaq 0x180(%rsp), %r13
movl $0x4, -0x8(%r13)
leaq 0x190(%rsp), %rax
movq %rax, (%r13)
leaq 0x2c31d(%rip), %rsi     # 0x482b1
leaq 0x2c31a(%rip), %rdx     # 0x482b5
movq %r13, %rdi
callq 0x116f8
leaq 0x1a8(%rsp), %r13
movl $0x5, -0x8(%r13)
leaq 0x1b8(%rsp), %rax
movq %rax, (%r13)
leaq 0x2f0bf(%rip), %rsi     # 0x4b085
leaq 0x2f0bc(%rip), %rdx     # 0x4b089
movq %r13, %rdi
callq 0x116f8
leaq 0x1d0(%rsp), %r13
movl $0x6, -0x8(%r13)
leaq 0x1e0(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x30bf3(%rip), %rsi     # 0x4cbeb
leaq 0x30bf0(%rip), %rdx     # 0x4cbef
movq %r13, %rdi
callq 0x116f8
leaq 0x208(%rsp), %rax
movl $0x8, -0x18(%rax)
movq %rax, -0x10(%rax)
leaq 0x2ee32(%rip), %rsi     # 0x4ae53
leaq 0x2ee30(%rip), %rdx     # 0x4ae58
leaq 0x1f8(%rsp), %r13
movq %r13, %rdi
callq 0x116f8
leaq 0x220(%rsp), %r13
movl $0x9, -0x8(%r13)
leaq 0x230(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x2c274(%rip), %rsi     # 0x482cf
leaq 0x2c271(%rip), %rdx     # 0x482d3
movq %r13, %rdi
callq 0x116f8
leaq 0x248(%rsp), %r13
movl $0x23, -0x8(%r13)
leaq 0x258(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x2c247(%rip), %rsi     # 0x482d4
leaq 0x2c243(%rip), %rdx     # 0x482d7
movq %r13, %rdi
callq 0x116f8
leaq 0x270(%rsp), %r13
movl $0x24, -0x8(%r13)
leaq 0x280(%rsp), %r14
movq %r14, -0x10(%r14)
leaq 0x2c22b(%rip), %rsi     # 0x482ea
leaq 0x2c229(%rip), %rdx     # 0x482ef
movq %r13, %rdi
callq 0x116f8
leaq 0x298(%rsp), %r12
movl $0x26, -0x8(%r12)
leaq 0x40(%rsp), %rax
movq %rax, (%rsp)
leaq 0x80(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
leaq 0x20(%rsp), %r8
leaq 0x60(%rsp), %r9
movq %r12, %rdx
xorl %ecx, %ecx
callq 0x2774e
movq $-0x1e0, %r12           # imm = 0xFE20
movq -0x10(%r14), %rdi
cmpq %rdi, %r14
je 0x1c127
movq (%r14), %rsi
incq %rsi
callq 0x92e0
addq $-0x28, %r14
addq $0x28, %r12
jne 0x1c113
leaq 0xb8(%rsp), %rdi
movq 0x10(%rsp), %rsi
movq %r15, %rdx
movq %rbp, %rcx
callq 0x9310
leaq 0x80(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
callq 0x28062
testq %rax, %rax
je 0x1c168
movl 0x28(%rax), %eax
jmp 0x1c16d
movl $0xa, %eax
movl %eax, (%rbx)
movq %r15, 0x8(%rbx)
leaq 0x10(%rbx), %rdi
leaq 0x20(%rbx), %rax
movq %rax, 0x10(%rbx)
movq 0xb8(%rsp), %rsi
movq 0xc0(%rsp), %rdx
addq %rsi, %rdx
callq 0xac68
movq 0xb8(%rsp), %rdi
leaq 0xc8(%rsp), %rax
cmpq %rax, %rdi
je 0x1c1bc
movq 0xc8(%rsp), %rsi
incq %rsi
callq 0x92e0
leaq 0x80(%rsp), %rdi
callq 0x24ef4
leaq 0x2b8(%rsp), %rdi
callq 0x2500e
leaq 0x2f0(%rsp), %rdi
callq 0x24ef4
movq %rbx, %rax
addq $0x328, %rsp            # imm = 0x328
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x10, %edi
callq 0x9150
movq %rax, %r12
leaq 0x40(%rsp), %rdi
movq %r15, %rsi
callq 0x246dc
leaq 0x2c0d7(%rip), %rsi     # 0x482f0
leaq 0x60(%rsp), %rdi
leaq 0x40(%rsp), %rdx
callq 0xc8b3
leaq 0x2b9f9(%rip), %rsi     # 0x47c28
leaq 0x60(%rsp), %rdi
callq 0x9540
leaq 0x30(%rsp), %r13
movq %r13, -0x10(%r13)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
jne 0x1c25b
movups (%rcx), %xmm0
movups %xmm0, (%r13)
jmp 0x1c268
movq %rdx, 0x20(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x30(%rsp)
movq 0x8(%rax), %rdx
movq %rdx, 0x28(%rsp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq 0x298(%rsp), %rdi
movl $0x5, %ecx
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdx
callq 0x9310
leaq 0x80(%rsp), %rdi
leaq 0x20(%rsp), %rsi
leaq 0x298(%rsp), %rdx
callq 0x24634
leaq 0x2bde4(%rip), %rsi     # 0x480a1
leaq 0x80(%rsp), %rdi
callq 0x9540
leaq 0xc8(%rsp), %rcx
movq %rcx, 0xb8(%rsp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
jne 0x1c2f9
movups (%rcx), %xmm0
leaq 0xc8(%rsp), %rdx
movups %xmm0, (%rdx)
jmp 0x1c30c
movq %rdx, 0xb8(%rsp)
movq (%rcx), %rdx
movq %rdx, 0xc8(%rsp)
movq 0x8(%rax), %rdx
leaq 0xb8(%rsp), %rsi
movq %rdx, 0x8(%rsi)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
movb $0x1, %bpl
movq %r12, %rdi
callq 0x9470
xorl %ebp, %ebp
movq 0x45cb1(%rip), %rsi     # 0x61ff0
movq 0x45c5a(%rip), %rdx     # 0x61fa0
movq %r12, %rdi
callq 0x94b0
movq %rax, %rbx
movq 0xb8(%rsp), %rdi
leaq 0xc8(%rsp), %rax
cmpq %rax, %rdi
je 0x1c37e
movq 0xc8(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x1c37e
movq %rax, %rbx
movb $0x1, %bpl
leaq 0x90(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x1c3a7
movq 0x90(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x1c3a7
movq %rax, %rbx
movb $0x1, %bpl
leaq 0x2a8(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x1c3d0
movq 0x2a8(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x1c3d0
movq %rax, %rbx
movb $0x1, %bpl
movq 0x20(%rsp), %rdi
cmpq %r13, %rdi
je 0x1c3ef
movq 0x30(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x1c3ef
movq %rax, %rbx
movb $0x1, %bpl
leaq 0x70(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x1c40a
movq 0x70(%rsp), %rsi
incq %rsi
callq 0x92e0
leaq 0x50(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x1c425
movq 0x50(%rsp), %rsi
incq %rsi
callq 0x92e0
testb %bpl, %bpl
jne 0x1c452
jmp 0x1c4f4
movq %rax, %rbx
leaq 0x50(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x1c452
movq 0x50(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x1c452
movq %rax, %rbx
movq %r12, %rdi
callq 0x9200
jmp 0x1c4f4
movq %rax, %rbx
jmp 0x1c4e2
movq %rax, %rbx
leaq 0xb8(%rsp), %rsi
movq %r12, %rdi
callq 0x9693
jmp 0x1c4f4
jmp 0x1c48d
jmp 0x1c48d
jmp 0x1c48d
jmp 0x1c48d
jmp 0x1c48d
jmp 0x1c48d
jmp 0x1c48d
jmp 0x1c48d
jmp 0x1c48d
jmp 0x1c48d
movq %rax, %rbx
movq -0x28(%r13), %rdi
leaq -0x18(%r13), %rax
cmpq %rdi, %rax
je 0x1c4a8
movq (%rax), %rsi
incq %rsi
callq 0x92e0
addq $-0x28, %r13
cmpq %r12, %r13
jne 0x1c490
jmp 0x1c4f4
jmp 0x1c4f1
jmp 0x1c556
movq %rax, %rbx
movq 0xb8(%rsp), %rdi
leaq 0xc8(%rsp), %rax
cmpq %rax, %rdi
je 0x1c4e2
movq 0xc8(%rsp), %rsi
incq %rsi
callq 0x92e0
leaq 0x80(%rsp), %rdi
callq 0x24ef4
jmp 0x1c4f4
movq %rax, %rbx
leaq 0x2b8(%rsp), %rdi
callq 0x2500e
jmp 0x1c559
jmp 0x1c556
movq %rax, %rbx
leaq 0xb8(%rsp), %rsi
leaq 0x1f8(%rsp), %rdi
callq 0x9660
jmp 0x1c566
jmp 0x1c52b
jmp 0x1c52b
jmp 0x1c52b
jmp 0x1c52b
jmp 0x1c52b
jmp 0x1c52b
movq %rax, %rbx
movq -0x28(%rbp), %rdi
leaq -0x18(%rbp), %rax
cmpq %rdi, %rax
je 0x1c546
movq (%rax), %rsi
incq %rsi
callq 0x92e0
addq $-0x28, %rbp
cmpq %r13, %rbp
jne 0x1c52e
jmp 0x1c566
movq %rax, %rbx
jmp 0x1c566
movq %rax, %rbx
leaq 0x2f0(%rsp), %rdi
callq 0x24ef4
movq %rbx, %rdi
callq 0x94e0