// File: /workspace/github_cpp_makefile_star2_O2/SeanLee97[P]LL1-Parser/grammar.cpp
// Function: Grammar::get_first(std::vector<bool, std::allocator<bool>>)
vector<vector<int> > Grammar::get_first(vector<bool> local_is_epsilon) {
	// array
	vector<vector<int> > temp_first(num_nonterminals + 1, vector<int>(0));
	bool complete = false;

	while(!complete) {
		complete = true;
		for(int i = 0; i < full_rules.size(); i++) {   // line
			for(int j = 1; j < full_rules[i].size(); j++) {  // symbol of line
				if(full_rules[i][j] == 0) {
					//  0 为结束标记 end
					break;

				// full_rules[i][j] - terminal
				} else if(full_rules[i][j] < 0) {

					// full_rules[i][j] 是否在 temp_first[full_rules[i][0]] 中
					if(!_in_array(temp_first[full_rules[i][0]], full_rules[i][j])) {
						temp_first[full_rules[i][0]].push_back(abs(full_rules[i][j]));
						complete = false; 
						// 找到first terminal退出
						break;
					} else break;

				// full_rules[i][j] - nonterminal
				// temp_first[full_rules[i][j]] 的first集不为空
				// temp_first[full_rules[i][j]] 的first集也为当前nonterminal的first集,故追加上
				} else if(full_rules[i][j] > 0 && temp_first[full_rules[i][j]].size() > 0) {

					vector<int> cur_elements_first = temp_first[full_rules[i][j]];

					for(int k = 0; k < cur_elements_first.size(); k++) {
						if(!_in_array(temp_first[full_rules[i][0]], cur_elements_first[k])) {
							temp_first[full_rules[i][0]].push_back(cur_elements_first[k]);
							complete = false;
						}
					}
				}
				
				// 当前nonterminal !-> epsilon，则退出
				if(! local_is_epsilon[abs(full_rules[i][j]) - 1]) {
					break;
				}
			}
		}
	}

	return temp_first;			
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rdx, -0x70(%rbp)
movq %rdi, %rbx
movq %rsi, -0x30(%rbp)
movslq 0x4(%rsi), %r12
leaq -0x60(%rbp), %rdi
leaq -0x36(%rbp), %rdx
xorl %esi, %esi
callq 0x4b42
incq %r12
leaq -0x60(%rbp), %rdx
leaq -0x35(%rbp), %rcx
movq %rbx, -0x40(%rbp)
movq %rbx, %rdi
movq %r12, %rsi
callq 0x4b94
leaq -0x60(%rbp), %rbx
movq %rbx, %rdi
callq 0x2632
xorl %edi, %edi
movb $0x1, %r8b
pushq $0x18
popq %rsi
leaq -0x88(%rbp), %r13
movq -0x40(%rbp), %r12
movl %edi, %edi
movq -0x30(%rbp), %rcx
movq 0x2d0(%rcx), %rax
subq 0x2c8(%rcx), %rax
cqto
idivq %rsi
cmpq %rdi, %rax
jbe 0x3129
movl %r8d, -0x34(%rbp)
movq %rdi, -0x68(%rbp)
imulq $0x18, %rdi, %r14
pushq $0x1
popq %r15
movq -0x30(%rbp), %rax
movq 0x2c8(%rax), %rax
movq (%rax,%r14), %rcx
movq 0x8(%rax,%r14), %rax
subq %rcx, %rax
sarq $0x2, %rax
cmpq %r15, %rax
jbe 0x31cb
movl (%rcx,%r15,4), %eax
testq %rax, %rax
je 0x31cb
testl %eax, %eax
js 0x3140
movq (%r12), %rsi
imulq $0x18, %rax, %rcx
movq 0x8(%rsi,%rcx), %rdx
cmpq (%rsi,%rcx), %rdx
je 0x3103
addq %rcx, %rsi
movq %rbx, %rdi
callq 0x4c16
movq %r15, -0x48(%rbp)
xorl %ebx, %ebx
xorl %r15d, %r15d
movq -0x58(%rbp), %rax
subq -0x60(%rbp), %rax
sarq $0x2, %rax
cmpq %r15, %rax
jbe 0x30e0
movq -0x30(%rbp), %rax
movq 0x2c8(%rax), %rax
movq (%rax,%r14), %rax
movslq (%rax), %rax
imulq $0x18, %rax, %rsi
addq (%r12), %rsi
movq %r13, %rdi
callq 0x4c16
movq -0x60(%rbp), %rax
movl (%rax,%r15,4), %edx
movq %r13, %rsi
callq 0x3230
movl %eax, %r12d
movq %r13, %rdi
callq 0x2632
testb %r12b, %r12b
movq -0x40(%rbp), %r12
jne 0x30d4
movq -0x30(%rbp), %rax
movq 0x2c8(%rax), %rax
movq (%rax,%r14), %rax
movslq (%rax), %rax
imulq $0x18, %rax, %rdi
addq (%r12), %rdi
movq -0x60(%rbp), %rsi
addq %rbx, %rsi
callq 0x4c6e
movl $0x0, -0x34(%rbp)
incq %r15
addq $0x4, %rbx
jmp 0x3050
leaq -0x60(%rbp), %rbx
movq %rbx, %rdi
callq 0x2632
movq -0x30(%rbp), %rax
movq 0x2c8(%rax), %rax
movq (%rax,%r14), %rax
movq -0x48(%rbp), %r15
movl (%rax,%r15,4), %eax
movl %eax, %ecx
negl %ecx
cmovsl %eax, %ecx
decl %ecx
movslq %ecx, %rsi
movq -0x70(%rbp), %rdi
callq 0x4bf4
incq %r15
testq %rdx, (%rax)
jne 0x2fec
jmp 0x31cb
movl $0x0, %edi
testb $0x1, %r8b
movb $0x1, %r8b
je 0x2fba
jmp 0x31dd
movq %r15, -0x48(%rbp)
movslq (%rcx), %rax
imulq $0x18, %rax, %rsi
addq (%r12), %rsi
leaq -0xa0(%rbp), %r15
movq %r15, %rdi
callq 0x4c16
movq -0x30(%rbp), %rax
movq 0x2c8(%rax), %rax
movq (%rax,%r14), %rax
movq -0x48(%rbp), %r12
movl (%rax,%r12,4), %edx
movq %r15, %rsi
callq 0x3230
movq %r15, %rdi
movq %r12, %r15
movl %eax, %r12d
callq 0x2632
testb %r12b, %r12b
movq -0x40(%rbp), %r12
jne 0x31cb
movq -0x30(%rbp), %rax
movq 0x2c8(%rax), %rax
movq (%rax,%r14), %rax
movslq (%rax), %rcx
imulq $0x18, %rcx, %rdi
addq (%r12), %rdi
movl (%rax,%r15,4), %eax
movl %eax, %ecx
negl %ecx
cmovsl %eax, %ecx
movl %ecx, -0x60(%rbp)
movq %rbx, %rsi
callq 0x52cc
movl $0x0, -0x34(%rbp)
movq -0x68(%rbp), %rdi
incl %edi
pushq $0x18
popq %rsi
movl -0x34(%rbp), %r8d
jmp 0x2fba
movq %r12, %rax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r14
leaq -0x60(%rbp), %rdi
callq 0x2632
jmp 0x3228
movq %rax, %r14
jmp 0x3228
jmp 0x320f
movq %rax, %r14
movq -0x40(%rbp), %r12
jmp 0x3220
jmp 0x320f
movq %rax, %r14
jmp 0x3220
movq %rax, %r14
leaq -0x60(%rbp), %rdi
callq 0x2632
movq %r12, %rdi
callq 0x257e
movq %r14, %rdi
callq 0x22c0