// File: /workspace/github_cpp_makefile_star2_O3/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, %r12
movq %rsi, %r15
movq %rdi, %rbx
movslq 0x4(%rsi), %rsi
incq %rsi
xorps %xmm0, %xmm0
leaq -0x50(%rbp), %rdx
movaps %xmm0, (%rdx)
movq $0x0, 0x10(%rdx)
leaq -0x29(%rbp), %rcx
callq 0x5e1a
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x3445
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x21d0
xorl %esi, %esi
movb $0x1, %r13b
movabsq $-0x5555555555555555, %rdx # imm = 0xAAAAAAAAAAAAAAAB
movq %r12, -0x60(%rbp)
movl %esi, %esi
movq 0x2c8(%r15), %rax
movq 0x2d0(%r15), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
imulq %rdx, %rcx
cmpq %rsi, %rcx
jbe 0x365c
movq %rsi, -0x68(%rbp)
leaq (%rsi,%rsi,2), %r14
movq (%rax,%r14,8), %rcx
movq 0x8(%rax,%r14,8), %rdx
subq %rcx, %rdx
cmpq $0x5, %rdx
jb 0x374b
movl $0x1, %edi
movl (%rcx,%rdi,4), %edx
testq %rdx, %rdx
je 0x374b
testl %edx, %edx
js 0x3673
movq (%rbx), %rcx
leaq (%rdx,%rdx,2), %rdx
movq 0x8(%rcx,%rdx,8), %rsi
cmpq (%rcx,%rdx,8), %rsi
je 0x35e5
movq %rdi, -0x58(%rbp)
leaq (%rcx,%rdx,8), %rsi
leaq -0x50(%rbp), %rdi
callq 0x5ebc
movq -0x50(%rbp), %rdi
cmpq %rdi, -0x48(%rbp)
je 0x35c9
xorl %r12d, %r12d
movq 0x2c8(%r15), %rax
movq (%rax,%r14,8), %rax
movslq (%rax), %rax
leaq (%rax,%rax,2), %rsi
shlq $0x3, %rsi
addq (%rbx), %rsi
leaq -0x80(%rbp), %rdi
callq 0x5ebc
movq -0x80(%rbp), %rdi
movq -0x78(%rbp), %rax
subq %rdi, %rax
je 0x3546
sarq $0x2, %rax
movq -0x50(%rbp), %rcx
movl (%rcx,%r12,4), %edx
movl %edx, %ecx
negl %ecx
cmovsl %edx, %ecx
cmpq $0x1, %rax
adcq $0x0, %rax
xorl %edx, %edx
cmpl %ecx, (%rdi,%rdx,4)
je 0x3594
incq %rdx
cmpq %rdx, %rax
jne 0x3537
jmp 0x354b
testq %rdi, %rdi
je 0x3557
movq -0x70(%rbp), %rsi
subq %rdi, %rsi
callq 0x21d0
movq 0x2c8(%r15), %rax
movq (%rax,%r14,8), %rax
movslq (%rax), %rax
movq (%rbx), %rcx
leaq (%rax,%rax,2), %rax
leaq (,%r12,4), %rdx
addq -0x50(%rbp), %rdx
leaq (%rcx,%rax,8), %rdi
movq 0x8(%rdi), %rsi
cmpq 0x10(%rdi), %rsi
je 0x35a2
movl (%rdx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x8(%rdi)
jmp 0x35a7
movq -0x70(%rbp), %rsi
subq %rdi, %rsi
callq 0x21d0
jmp 0x35aa
callq 0x66b8
xorl %r13d, %r13d
incq %r12
movq -0x50(%rbp), %rdi
movq -0x48(%rbp), %rax
subq %rdi, %rax
sarq $0x2, %rax
cmpq %r12, %rax
ja 0x34eb
movq -0x60(%rbp), %r12
testq %rdi, %rdi
je 0x35da
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x21d0
movq 0x2c8(%r15), %rax
movq -0x58(%rbp), %rdi
movq (%rax,%r14,8), %rcx
movl (%rcx,%rdi,4), %esi
movl %esi, %edx
negl %edx
cmovsl %esi, %edx
leal -0x1(%rdx), %esi
movslq %esi, %rsi
addl $0x3e, %edx
testl %esi, %esi
cmovnsl %esi, %edx
sarl $0x6, %edx
shlq $0x3, %rdx
addq (%r12), %rdx
movq %rdi, %r10
movabsq $-0x8000000000000000, %r9 # imm = 0x8000000000000000
leaq 0x3f(%r9), %rdi
andq %rsi, %rdi
xorl %r8d, %r8d
cmpq %r9, %rdi
setbe %r8b
movq -0x8(%rdx,%r8,8), %rdx
btq %rsi, %rdx
jae 0x374b
leaq (%rax,%r14,8), %rdx
incq %r10
movq 0x8(%rdx), %rdx
subq %rcx, %rdx
sarq $0x2, %rdx
cmpq %r10, %rdx
movq %r10, %rdi
ja 0x349f
jmp 0x374b
movl $0x0, %esi
testb $0x1, %r13b
movb $0x1, %r13b
je 0x3458
jmp 0x3760
movq %rdi, -0x58(%rbp)
movslq (%rcx), %rax
leaq (%rax,%rax,2), %rsi
shlq $0x3, %rsi
addq (%rbx), %rsi
leaq -0x98(%rbp), %rdi
callq 0x5ebc
movq -0x98(%rbp), %rdi
movq -0x90(%rbp), %rax
subq %rdi, %rax
je 0x36da
sarq $0x2, %rax
movq 0x2c8(%r15), %rcx
movq (%rcx,%r14,8), %rcx
movq -0x58(%rbp), %rdx
movl (%rcx,%rdx,4), %edx
movl %edx, %ecx
negl %ecx
cmovsl %edx, %ecx
cmpq $0x1, %rax
adcq $0x0, %rax
xorl %edx, %edx
cmpl %ecx, (%rdi,%rdx,4)
je 0x372e
incq %rdx
cmpq %rdx, %rax
jne 0x36cb
jmp 0x36df
testq %rdi, %rdi
je 0x36ee
movq -0x88(%rbp), %rsi
subq %rdi, %rsi
callq 0x21d0
movq 0x2c8(%r15), %rax
movq (%rax,%r14,8), %rax
movslq (%rax), %rcx
movq (%rbx), %rdx
leaq (%rcx,%rcx,2), %rcx
leaq (%rdx,%rcx,8), %rdi
movq -0x58(%rbp), %rcx
movl (%rax,%rcx,4), %ecx
movl %ecx, %eax
negl %eax
cmovsl %ecx, %eax
movl %eax, -0x50(%rbp)
movq 0x8(%rdi), %rsi
cmpq 0x10(%rdi), %rsi
je 0x373f
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x8(%rdi)
jmp 0x3748
movq -0x88(%rbp), %rsi
subq %rdi, %rsi
callq 0x21d0
jmp 0x374b
leaq -0x50(%rbp), %rdx
callq 0x6596
xorl %r13d, %r13d
movq -0x68(%rbp), %rsi
incl %esi
movabsq $-0x5555555555555555, %rdx # imm = 0xAAAAAAAAAAAAAAAB
jmp 0x3458
movq %rbx, %rax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r14
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x37b5
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x21d0
jmp 0x37b5
jmp 0x3790
jmp 0x3790
movq %rax, %r14
jmp 0x37ad
movq %rax, %r14
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x37ad
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x21d0
movq %rbx, %rdi
callq 0x2690
movq %r14, %rdi
callq 0x22e0
nop