// File: /workspace/github_cpp_makefile_star2_O3/kiven-li[P]xbytes/xbytes.cpp
// Function: xbytes::xbytes::find_follow_set()
void xbytes::find_follow_set()
{
	for(int i = 0; i < symbols.size(); ++i)
	{
		if(symbols[i]->type == ST_TERMINAL)
		{
			symbols[i]->follow_set.push_back(symbols[i]);
		}
	}

	while(true)
	{
		int change_count = 0;
		for(int x = 0; x < rules.size(); ++x)
		{
			rule* r = rules[x];
			int k = r->rights.size();
			if(k == 0) continue;

			for(int i = 0; i < k; ++i)
			{
				symbol* s = r->rights[i];
				if(s->type == ST_TERMINAL) 
				{
					//终结符前面是非终结符，则加入到前面的FOLLOW中
					if(i > 0 && r->rights[i-1]->type == ST_NONTERMINAL)
					{
						change_count += merge_symbol_set(r->rights[i-1]->follow_set, s->follow_set);
					}						
					continue;
				}

				//两个相邻的非终结符，后一个的FIRST是前一个的FOLLOW
				if(i > 0 && r->rights[i-1]->type == ST_NONTERMINAL)
				{
					change_count += merge_symbol_set(r->rights[i-1]->follow_set, s->first_set);
				}

				//if Yi+1 ... Yk 都可为空的 then
				//FOLLOW[Yi] = FOLLOW[Yi] U FOLLOW[X]
				bool is_all_follow_nullable = true;
				for(int j = i + 1; j < k; ++j)
				{
					if(!r->rights[j]->is_nullable)
					{
						is_all_follow_nullable = false;
						break;
					}
				}
				if(is_all_follow_nullable)
				{
					change_count += merge_symbol_set(s->follow_set, r->left->follow_set);
				}

				//if Yi+1 .. Yj-1 都可为空的 then
				//FOLLOW[Yi] = FOLLOW[Yi] U FIRST[Yj]
				for(int j = i + 1; j < k; ++j)
				{
					if(i+1 > j-1) continue;
					if(!r->rights[j-1]->is_nullable) break;
					change_count += merge_symbol_set(s->follow_set, r->rights[j]->first_set);
				}
			}
		}

		if(!change_count) break;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq 0x8(%rdi), %rdx
movq %rdi, -0x40(%rbp)
cmpq %rdx, 0x10(%rdi)
je 0x53e9
xorl %ebx, %ebx
xorl %r14d, %r14d
movq (%rdx,%rbx), %rdi
cmpl $0x1, 0x48(%rdi)
jne 0x53ca
movq 0x90(%rdi), %rsi
cmpq 0x98(%rdi), %rsi
je 0x53bb
movq %rdi, (%rsi)
addq $0x8, 0x90(%rdi)
jmp 0x53ca
addq %rbx, %rdx
addq $0x88, %rdi
callq 0xb088
incq %r14
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rdx
movq 0x10(%rax), %rax
subq %rdx, %rax
sarq $0x3, %rax
addq $0x8, %rbx
cmpq %r14, %rax
ja 0x5394
movq -0x40(%rbp), %rcx
movq 0x20(%rcx), %rax
movq 0x28(%rcx), %rcx
cmpq %rax, %rcx
je 0x55a7
xorl %esi, %esi
xorl %edi, %edi
movq (%rax,%rsi,8), %rdx
movq 0x38(%rdx), %r8
movq %rdx, -0x38(%rbp)
subq 0x30(%rdx), %r8
shrq $0x3, %r8
testl %r8d, %r8d
jle 0x5589
movq %rsi, -0x58(%rbp)
andl $0x7fffffff, %r8d       # imm = 0x7FFFFFFF
leaq -0x1(%r8), %rbx
movq %r8, %r12
movq $0x0, -0x50(%rbp)
xorl %r15d, %r15d
movq %r8, -0x48(%rbp)
movq -0x38(%rbp), %rax
movq 0x30(%rax), %rax
movq (%rax,%r15,8), %rcx
movq %rcx, -0x30(%rbp)
cmpl $0x1, 0x48(%rcx)
jne 0x548f
testq %r15, %r15
je 0x5561
movq -0x8(%rax,%r15,8), %rsi
cmpl $0x2, 0x48(%rsi)
jne 0x5561
movl $0x88, %eax
addq %rax, %rsi
movq -0x30(%rbp), %rdx
addq %rax, %rdx
movl %edi, %r14d
callq 0x6c34
movl %r14d, %edi
addl %eax, %edi
jmp 0x5561
testq %r15, %r15
je 0x54bf
movq -0x8(%rax,%r15,8), %rsi
cmpl $0x2, 0x48(%rsi)
jne 0x54bf
addq $0x88, %rsi
movq -0x30(%rbp), %rax
leaq 0x70(%rax), %rdx
movl %edi, %r13d
callq 0x6c34
movl %r13d, %edi
movq -0x48(%rbp), %r8
addl %eax, %edi
leaq 0x1(%r15), %r14
cmpq %r8, %r14
jae 0x54eb
movq -0x38(%rbp), %rax
movq 0x30(%rax), %rax
addq -0x50(%rbp), %rax
movl $0x1, %ecx
movq (%rax,%rcx,8), %rdx
cmpb $0x0, 0x68(%rdx)
je 0x5514
incq %rcx
cmpq %rcx, %r12
jne 0x54d9
movl $0x88, %eax
movq -0x30(%rbp), %rcx
leaq (%rcx,%rax), %rsi
movq -0x38(%rbp), %rcx
movq 0x8(%rcx), %rdx
addq %rax, %rdx
movl %edi, %r13d
callq 0x6c34
movl %r13d, %edi
movq -0x48(%rbp), %r8
addl %eax, %edi
cmpq %r8, %r14
jae 0x5561
addq $0x88, -0x30(%rbp)
movq %r15, %r13
cmpq %r13, %r15
jae 0x5559
movq -0x38(%rbp), %rax
movq 0x30(%rax), %rax
movq (%rax,%r13,8), %rcx
cmpb $0x1, 0x68(%rcx)
jne 0x5561
movq 0x8(%rax,%r13,8), %rdx
addq $0x70, %rdx
movq -0x30(%rbp), %rsi
movq %rbx, %r14
movl %edi, %ebx
callq 0x6c34
movl %ebx, %edi
movq %r14, %rbx
addl %eax, %edi
incq %r13
cmpq %r13, %rbx
jne 0x5524
incq %r15
addq $0x8, -0x50(%rbp)
decq %r12
movq -0x48(%rbp), %r8
cmpq %r8, %r15
jne 0x5440
movq -0x40(%rbp), %rcx
movq 0x20(%rcx), %rax
movq 0x28(%rcx), %rcx
movq -0x58(%rbp), %rsi
incq %rsi
movq %rcx, %rdx
subq %rax, %rdx
sarq $0x3, %rdx
cmpq %rsi, %rdx
ja 0x5402
testl %edi, %edi
jne 0x53f5
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq