// File: /workspace/github_c_makefile_star2_O2/theovosse[P]llgen/llgen.c
// Function: determineEmptyRule
static Boolean determineEmptyRule(Node rule) {
	Boolean empty = true, firstPrinted;
	NodeList* rules, emptyRule;

	if (rule == NULL || rule->empty) {
		return true;
	}
	for (Node ptr = rule; ptr != NULL; ptr = ptr->next) {
		switch (ptr->nodeType) {
			case single: /* Only if identifier produces empty, not if string; ignore code and output */
				if (!((ptr->element.name->nameType == identifier && ptr->element.name->empty) ||
					  ptr->element.name->nameType == output ||
					  ptr->element.name->nameType == code)) {
					empty = false;
				}
				break;
			case option: /* Bien sure */
				break;
			case sequence: /* Only if subpart is empty */
				if (!determineEmptyRule(ptr->element.sub)) {
					empty = false;
				}
				break;
			case chain: /* Only if first part of chain is empty, second doesn't matter */
				if (!determineEmptyRule(ptr->element.sub->element.sub)) {
					empty = false;
				}
				break;
			case alternative: /* Only if one of the alternatives is empty */
				firstPrinted = false;
				rules = &ptr->element.alternatives;
				emptyRule = NULL;
				if (!ptr->element.alternatives->empty) {
					while (*rules != NULL) {
						if (determineEmptyRule((*rules)->first)) {
							if (emptyRule != NULL) {
								if (!firstPrinted) {
									if (emptyRule->first != NULL) {
										fprintf(stderr, "%s:%d:error: more than one empty alternative\n",
												inputFileName, emptyRule->first->lineNr);
									} else {
										fprintf(stderr, "%s:%d:error: more than one empty alternative following this line\n",
												inputFileName, ptr->lineNr);
									}
									firstPrinted = true;
								}
								if ((*rules)->first != NULL) {
									fprintf(stderr, "%s:%d:error: and here\n",
											inputFileName, (*rules)->first->lineNr);
								} else {
									fprintf(stderr, "%s:%d:error: and following this line\n",
											inputFileName, ptr->lineNr);
								}
								notLLError = true;
								rules = &(*rules)->rest;
							} else {
								// Take this out of the list and move it to the end
								emptyRule = *rules;
								*rules = emptyRule->rest;
								emptyRule->rest = NULL;
							}
						} else {
							rules = &(*rules)->rest;
						}
					}
					if (emptyRule != NULL) {
						// Reorder such that emptyRule goes to the end.
						*rules = emptyRule;
						ptr->element.alternatives->empty = true;
					} else {
						empty = false;
					}
				}
				break;
			case breakToken:
			case errorMessage:
				break;
			// default:
			// 	fprintf(stderr, "determineEmptyRule: unknown nodetype %d\n", ptr->nodeType);
			// 	return empty;
		}
	}
	rule->empty = empty;
	return empty;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movw $0xffff, %bx            # imm = 0xFFFF
testq %rdi, %rdi
je 0x6367
cmpw $0x0, 0x22(%rdi)
jne 0x6367
movw $0xffff, %bx            # imm = 0xFFFF
leaq 0x9e58(%rip), %r15      # 0x1003c
xorl %ebp, %ebp
movq %rdi, 0x8(%rsp)
movq %rdi, %r14
testq %r14, %r14
je 0x635e
movl 0x4(%r14), %eax
cmpq $0x4, %rax
ja 0x6355
movslq (%r15,%rax,4), %rax
addq %r15, %rax
jmpq *%rax
movq 0x18(%r14), %rcx
movl 0x38(%rcx), %eax
testl %eax, %eax
je 0x632d
andl $-0x2, %eax
cmpl $0x2, %eax
cmovnel %ebp, %ebx
jmp 0x6355
movq 0x18(%r14), %rax
movq 0x18(%rax), %rdi
jmp 0x6239
movq 0x18(%r14), %rdi
callq 0x61b3
testw %ax, %ax
cmovel %ebp, %ebx
jmp 0x6355
movq 0x18(%r14), %rax
cmpw $0x0, 0x10(%rax)
jne 0x6355
leaq 0x18(%r14), %r12
xorl %r13d, %r13d
movq %r12, 0x10(%rsp)
xorl %ebp, %ebp
testq %rax, %rax
je 0x6339
movq (%rax), %rdi
callq 0x61b3
testw %ax, %ax
je 0x6294
testq %rbp, %rbp
jne 0x62a2
movq (%r12), %rbp
movq 0x8(%rbp), %rax
movq %rax, (%r12)
andq $0x0, 0x8(%rbp)
jmp 0x629c
movq (%r12), %r12
addq $0x8, %r12
movq (%r12), %rax
jmp 0x6266
testw %r13w, %r13w
jne 0x62e0
movq (%rbp), %rax
testq %rax, %rax
movq 0x11d42(%rip), %rcx     # 0x17ff8
movq (%rcx), %rdi
movq 0x11ec8(%rip), %rdx     # 0x18188
cmoveq %r14, %rax
leaq 0x9fbd(%rip), %rsi      # 0x10288
leaq 0x9fe4(%rip), %rcx      # 0x102b6
cmoveq %rcx, %rsi
movswl (%rax), %ecx
xorl %eax, %eax
callq 0x3150
movq (%r12), %rax
movq (%rax), %rax
testq %rax, %rax
cmoveq %r14, %rax
leaq 0xa003(%rip), %rsi      # 0x102f8
leaq 0xa013(%rip), %rcx      # 0x1030f
cmoveq %rcx, %rsi
movq 0x11cf1(%rip), %rcx     # 0x17ff8
movq (%rcx), %rdi
movq 0x11e77(%rip), %rdx     # 0x18188
movswl (%rax), %ecx
xorl %eax, %eax
callq 0x3150
movq (%r12), %r12
addq $0x8, %r12
movw $0xffff, %r13w          # imm = 0xFFFF
jmp 0x629c
cmpw $0x0, 0x30(%rcx)
jne 0x6355
jmp 0x621d
testq %rbp, %rbp
je 0x6351
movq %rbp, (%r12)
movq 0x10(%rsp), %rax
movq (%rax), %rax
orw $-0x1, 0x10(%rax)
jmp 0x6353
xorl %ebx, %ebx
xorl %ebp, %ebp
movq 0x28(%r14), %r14
jmp 0x61ee
movq 0x8(%rsp), %rax
movw %bx, 0x22(%rax)
movl %ebx, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq