// File: JameyWoo[P]re2graph/algorithms.cpp
// Function: re2nfa(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
NFA re2nfa(string rexp) {  // 将正则表达式转化为nfa的函数
    // 对rexp进行一些预处理, 处理[] 的情况
    string prexp, middle;
    bool is_mid = false;
    for (auto c : rexp) {
        if (c == '[') {
            is_mid = true;
            prexp.push_back('(');
        } else if (c == ']') {
            string mid = parse_range(middle);
            for (auto m : mid) {
                prexp += m;
                prexp += '|';
            }
            prexp.pop_back();
            prexp.push_back(')');
            middle = "";
            is_mid = false;
        } else {
            if (is_mid)
                middle += c;
            else
                prexp += c;
        }
    }
    // cout << "prexp: " << prexp << endl;
    rexp = prexp;

    int state       = 0;
    Graph nfa_graph = parse_re(rexp, state);
    // cout << "start: " << nfa_graph.start << endl;
    // cout << "end: " << nfa_graph.end << endl;
    // for (auto edge : nfa_graph.edges) {
    //     cout << edge.from << ' ' << edge.cond << ' ' << edge.to << endl;
    // }

    // 获取除规则字符之外的字符
    set<char> char_set;
    char_set.insert('~');
    for (auto c : rexp) {
        if (not(c == '|' || c == '(' || c == ')' || c == '*')) {
            char_set.insert(c);
        }
    }

    // 将数据存入到nfa中
    NFA nfa;
    nfa.char_cnt      = char_set.size();
    nfa.state_cnt     = state;
    nfa.start_state   = 0;
    nfa.end_state_cnt = 1;
    nfa.end_states.push_back(state - 1);
    for (auto s : char_set) {
        nfa.chars.push_back(s);
    }
    for (int i = 0; i < state; ++i) {
        nfa.states.push_back(i);
    }
    vector<map<char, vector<int>>> jump(state);
    for (auto edge : nfa_graph.edges) {
        jump[edge.from][edge.cond].push_back(edge.to);
    }
    nfa.jump = jump;
    return nfa;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x280, %rsp            # imm = 0x280
movq %rsi, -0x218(%rbp)
movq %rdi, -0x228(%rbp)
movq %rdi, %rax
movq %rax, -0x220(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x3410
leaq -0x50(%rbp), %rdi
callq 0x3410
movq -0x218(%rbp), %rsi
movb $0x0, -0x51(%rbp)
movq %rsi, -0x60(%rbp)
movq -0x60(%rbp), %rdi
callq 0x3290
movq %rax, -0x68(%rbp)
movq -0x60(%rbp), %rdi
callq 0x3180
movq %rax, -0x70(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x8b00
testb $0x1, %al
jne 0x8c6c
jmp 0x8e49
leaq -0x68(%rbp), %rdi
callq 0x8bb0
movb (%rax), %al
movb %al, -0x71(%rbp)
movsbl -0x71(%rbp), %eax
cmpl $0x5b, %eax
jne 0x8cb0
movb $0x1, -0x51(%rbp)
leaq -0x30(%rbp), %rdi
movl $0x28, %esi
callq 0x3280
jmp 0x8c97
jmp 0x8e39
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x9353
movsbl -0x71(%rbp), %eax
cmpl $0x5d, %eax
jne 0x8e0d
leaq -0xc8(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3120
jmp 0x8ccf
leaq -0xa8(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0x9370
jmp 0x8ce4
leaq -0xc8(%rbp), %rdi
callq 0x31c0
leaq -0xa8(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rdi
callq 0x3290
movq %rax, -0xd8(%rbp)
movq -0xd0(%rbp), %rdi
callq 0x3180
movq %rax, -0xe0(%rbp)
leaq -0xd8(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x8b00
testb $0x1, %al
jne 0x8d40
jmp 0x8dc6
leaq -0xd8(%rbp), %rdi
callq 0x8bb0
movb (%rax), %al
movb %al, -0xe1(%rbp)
movsbl -0xe1(%rbp), %esi
leaq -0x30(%rbp), %rdi
callq 0x31d0
jmp 0x8d66
leaq -0x30(%rbp), %rdi
movl $0x7c, %esi
callq 0x31d0
jmp 0x8d76
jmp 0x8d78
leaq -0xd8(%rbp), %rdi
callq 0x8b80
jmp 0x8d24
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x31c0
jmp 0x9353
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x31c0
jmp 0x9353
leaq -0x30(%rbp), %rdi
movq %rdi, -0x230(%rbp)
callq 0x33a0
movq -0x230(%rbp), %rdi
movl $0x29, %esi
callq 0x3280
jmp 0x8de9
leaq 0x24489(%rip), %rsi     # 0x2d279
leaq -0x50(%rbp), %rdi
callq 0x3400
jmp 0x8dfb
movb $0x0, -0x51(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x31c0
jmp 0x8e37
testb $0x1, -0x51(%rbp)
je 0x8e24
movsbl -0x71(%rbp), %esi
leaq -0x50(%rbp), %rdi
callq 0x31d0
jmp 0x8e22
jmp 0x8e35
movsbl -0x71(%rbp), %esi
leaq -0x30(%rbp), %rdi
callq 0x31d0
jmp 0x8e33
jmp 0x8e35
jmp 0x8e37
jmp 0x8e39
jmp 0x8e3b
leaq -0x68(%rbp), %rdi
callq 0x8b80
jmp 0x8c56
movq -0x218(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x3040
jmp 0x8e5b
movq -0x218(%rbp), %rsi
movl $0x0, -0xe8(%rbp)
leaq -0x128(%rbp), %rdi
callq 0x3120
jmp 0x8e7a
leaq -0x108(%rbp), %rdi
leaq -0x128(%rbp), %rsi
leaq -0xe8(%rbp), %rdx
callq 0x9530
jmp 0x8e96
leaq -0x128(%rbp), %rdi
callq 0x31c0
leaq -0x158(%rbp), %rdi
movq %rdi, -0x248(%rbp)
callq 0x11d80
movq -0x248(%rbp), %rdi
movb $0x7e, -0x159(%rbp)
leaq -0x159(%rbp), %rsi
callq 0x11da0
movb %dl, -0x239(%rbp)
movq %rax, -0x238(%rbp)
jmp 0x8ede
movq -0x218(%rbp), %rax
movb -0x239(%rbp), %cl
movq -0x238(%rbp), %rdx
movq %rdx, -0x170(%rbp)
movb %cl, -0x168(%rbp)
movq %rax, -0x178(%rbp)
movq -0x178(%rbp), %rdi
callq 0x3290
movq %rax, -0x180(%rbp)
movq -0x178(%rbp), %rdi
callq 0x3180
movq %rax, -0x188(%rbp)
leaq -0x180(%rbp), %rdi
leaq -0x188(%rbp), %rsi
callq 0x8b00
testb $0x1, %al
jne 0x8f48
jmp 0x9019
leaq -0x180(%rbp), %rdi
callq 0x8bb0
movb (%rax), %al
movb %al, -0x189(%rbp)
movsbl -0x189(%rbp), %eax
cmpl $0x7c, %eax
je 0x9006
movsbl -0x189(%rbp), %eax
cmpl $0x28, %eax
je 0x9006
movsbl -0x189(%rbp), %eax
cmpl $0x29, %eax
je 0x9006
movsbl -0x189(%rbp), %eax
cmpl $0x2a, %eax
je 0x9006
leaq -0x158(%rbp), %rdi
leaq -0x189(%rbp), %rsi
callq 0x11df0
movb %dl, -0x251(%rbp)
movq %rax, -0x250(%rbp)
jmp 0x8fb6
movb -0x251(%rbp), %al
movq -0x250(%rbp), %rcx
movq %rcx, -0x1a0(%rbp)
movb %al, -0x198(%rbp)
jmp 0x9006
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x128(%rbp), %rdi
callq 0x31c0
jmp 0x9353
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x933b
jmp 0x9008
leaq -0x180(%rbp), %rdi
callq 0x8b80
jmp 0x8f2c
movq -0x228(%rbp), %rdi
movb $0x0, -0x1a1(%rbp)
callq 0x11e40
leaq -0x158(%rbp), %rdi
callq 0x11e90
movq -0x228(%rbp), %rdi
movl %eax, (%rdi)
movl -0xe8(%rbp), %eax
movl %eax, 0x4(%rdi)
movl $0x0, 0x8(%rdi)
movl $0x1, 0xc(%rdi)
addq $0x40, %rdi
movl -0xe8(%rbp), %eax
decl %eax
movl %eax, -0x1a8(%rbp)
leaq -0x1a8(%rbp), %rsi
callq 0x11eb0
jmp 0x9078
leaq -0x158(%rbp), %rax
movq %rax, -0x1b0(%rbp)
movq -0x1b0(%rbp), %rdi
callq 0x11ee0
movq %rax, -0x1b8(%rbp)
movq -0x1b0(%rbp), %rdi
callq 0x11f10
movq %rax, -0x1c0(%rbp)
leaq -0x1b8(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0x11f40
testb $0x1, %al
jne 0x90c5
jmp 0x9116
leaq -0x1b8(%rbp), %rdi
callq 0x11f70
movq -0x228(%rbp), %rdi
movb (%rax), %al
movb %al, -0x1c1(%rbp)
addq $0x10, %rdi
leaq -0x1c1(%rbp), %rsi
callq 0x11f90
jmp 0x90f2
jmp 0x90f4
leaq -0x1b8(%rbp), %rdi
callq 0x12000
jmp 0x90ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x932f
movl $0x0, -0x1c8(%rbp)
movl -0x1c8(%rbp), %eax
cmpl -0xe8(%rbp), %eax
jge 0x915a
movq -0x228(%rbp), %rdi
addq $0x28, %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x12030
jmp 0x9147
jmp 0x9149
movl -0x1c8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c8(%rbp)
jmp 0x9120
movslq -0xe8(%rbp), %rax
movq %rax, -0x268(%rbp)
leaq -0x1e1(%rbp), %rdi
movq %rdi, -0x260(%rbp)
callq 0x120a0
movq -0x268(%rbp), %rsi
movq -0x260(%rbp), %rdx
leaq -0x1e0(%rbp), %rdi
callq 0x120c0
jmp 0x9197
leaq -0x1e1(%rbp), %rdi
callq 0x5d70
leaq -0x108(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x1f0(%rbp)
movq -0x1f0(%rbp), %rdi
callq 0x12130
movq %rax, -0x1f8(%rbp)
movq -0x1f0(%rbp), %rdi
callq 0x12160
movq %rax, -0x200(%rbp)
leaq -0x1f8(%rbp), %rdi
leaq -0x200(%rbp), %rsi
callq 0x12190
testb $0x1, %al
jne 0x91f7
jmp 0x92b4
leaq -0x1f8(%rbp), %rdi
callq 0x121d0
movl 0x8(%rax), %ecx
movl %ecx, -0x208(%rbp)
movq (%rax), %rax
movq %rax, -0x210(%rbp)
leaq -0x208(%rbp), %rax
movq %rax, -0x278(%rbp)
movslq -0x210(%rbp), %rsi
leaq -0x1e0(%rbp), %rdi
callq 0x121f0
movq -0x278(%rbp), %rsi
movq %rax, %rdi
callq 0x12210
movq %rax, -0x270(%rbp)
jmp 0x924f
movq -0x270(%rbp), %rdi
leaq -0x20c(%rbp), %rsi
callq 0x12030
jmp 0x9264
jmp 0x9266
leaq -0x1f8(%rbp), %rdi
callq 0x122f0
jmp 0x91db
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x1e1(%rbp), %rdi
callq 0x5d70
jmp 0x932f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x1e0(%rbp), %rdi
callq 0x7180
jmp 0x932f
movq -0x228(%rbp), %rdi
addq $0x58, %rdi
leaq -0x1e0(%rbp), %rsi
callq 0x12310
jmp 0x92cd
movb $0x1, -0x1a1(%rbp)
leaq -0x1e0(%rbp), %rdi
callq 0x7180
testb $0x1, -0x1a1(%rbp)
jne 0x92f5
movq -0x228(%rbp), %rdi
callq 0x4880
leaq -0x158(%rbp), %rdi
callq 0x12560
leaq -0x108(%rbp), %rdi
callq 0x12580
leaq -0x50(%rbp), %rdi
callq 0x31c0
leaq -0x30(%rbp), %rdi
callq 0x31c0
movq -0x220(%rbp), %rax
addq $0x280, %rsp            # imm = 0x280
popq %rbp
retq
movq -0x228(%rbp), %rdi
callq 0x4880
leaq -0x158(%rbp), %rdi
callq 0x12560
leaq -0x108(%rbp), %rdi
callq 0x12580
leaq -0x50(%rbp), %rdi
callq 0x31c0
leaq -0x30(%rbp), %rdi
callq 0x31c0
movq -0x80(%rbp), %rdi
callq 0x34e0
nop