// File: /workspace/github_cpp_makefile_star2_O1/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 0x5582
xorl %ebx, %ebx
xorl %r14d, %r14d
movq (%rdx,%rbx), %rdi
cmpl $0x1, 0x48(%rdi)
jne 0x53be
movq 0x90(%rdi), %rsi
cmpq 0x98(%rdi), %rsi
je 0x53af
movq %rdi, (%rsi)
addq $0x8, 0x90(%rdi)
jmp 0x53be
addq %rbx, %rdx
addq $0x88, %rdi
callq 0xb024
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 0x5388
jmp 0x5582
xorl %edx, %edx
xorl %edi, %edi
movq %rdx, -0x58(%rbp)
movq (%rax,%rdx,8), %rax
movq 0x38(%rax), %r8
movq %rax, -0x38(%rbp)
subq 0x30(%rax), %r8
shrq $0x3, %r8
testl %r8d, %r8d
jle 0x555b
andl $0x7fffffff, %r8d       # imm = 0x7FFFFFFF
leaq -0x1(%r8), %rbx
movq $0x0, -0x50(%rbp)
movq %r8, %r13
xorl %r12d, %r12d
movq %r8, -0x48(%rbp)
movq -0x38(%rbp), %rax
movq 0x30(%rax), %rax
movq (%rax,%r12,8), %rcx
movq %rcx, -0x30(%rbp)
cmpl $0x1, 0x48(%rcx)
jne 0x5473
testq %r12, %r12
je 0x5543
movq -0x8(%rax,%r12,8), %rsi
cmpl $0x2, 0x48(%rsi)
jne 0x5543
movl $0x88, %eax
addq %rax, %rsi
movq -0x30(%rbp), %rdx
addq %rax, %rdx
movl %edi, %r14d
callq 0x6c10
movl %r14d, %edi
addl %eax, %edi
jmp 0x5543
testq %r12, %r12
je 0x54a3
movq -0x8(%rax,%r12,8), %rsi
cmpl $0x2, 0x48(%rsi)
jne 0x54a3
addq $0x88, %rsi
movq -0x30(%rbp), %rax
leaq 0x70(%rax), %rdx
movl %edi, %r15d
callq 0x6c10
movl %r15d, %edi
movq -0x48(%rbp), %r8
addl %eax, %edi
leaq 0x1(%r12), %r14
cmpq %r8, %r14
jae 0x54d0
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 0x54f6
incq %rcx
cmpq %rcx, %r13
jne 0x54be
movl $0x88, %edx
movq -0x30(%rbp), %rax
leaq (%rax,%rdx), %rsi
movq -0x38(%rbp), %rax
addq 0x8(%rax), %rdx
movl %edi, %r15d
callq 0x6c10
movl %r15d, %edi
movq -0x48(%rbp), %r8
addl %eax, %edi
cmpq %r8, %r14
jae 0x5543
addq $0x88, -0x30(%rbp)
movq %r12, %r15
cmpq %r15, %r12
jae 0x553b
movq -0x38(%rbp), %rax
movq 0x30(%rax), %rax
movq (%rax,%r15,8), %rcx
cmpb $0x1, 0x68(%rcx)
jne 0x5543
movq 0x8(%rax,%r15,8), %rdx
addq $0x70, %rdx
movq -0x30(%rbp), %rsi
movq %rbx, %r14
movl %edi, %ebx
callq 0x6c10
movl %ebx, %edi
movq %r14, %rbx
addl %eax, %edi
incq %r15
cmpq %r15, %rbx
jne 0x5506
incq %r12
addq $0x8, -0x50(%rbp)
decq %r13
movq -0x48(%rbp), %r8
cmpq %r8, %r12
jne 0x5424
movq -0x58(%rbp), %rdx
incq %rdx
movq -0x40(%rbp), %rcx
movq 0x20(%rcx), %rax
movq 0x28(%rcx), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %rdx, %rcx
ja 0x53e6
testl %edi, %edi
je 0x5594
movq -0x40(%rbp), %rcx
movq 0x20(%rcx), %rax
cmpq %rax, 0x28(%rcx)
jne 0x53e2
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop