// File: SeanLee97[P]LL1-Parser/grammar.cpp
// Function: Grammar::parse()
void Grammar::parse() {
    stack<int> parse_stack;
    int expected_symbol;
    token input_tok;
    parse_stack.push(start_symbol);
    input_tok = scan();

    do {
    	expected_symbol = parse_stack.top();
    	if(input_tok.num == 32) {
    		cout << "\nError: Invalid token \"" << input_tok.image << "\" at row: " << input_tok.line << " column: " << input_tok.column <<endl;
    		exit(0);
    		input_tok = scan();
    	}
    	if(expected_symbol < 0) {
    		if(input_tok.num == abs(expected_symbol)) {    			
    			cout << "Match: " << input_tok.image << "\n";
    			input_tok = scan(); 
    			parse_stack.pop();
    		} else {
    			cout <<"Error: \"" << input_tok.image << "\" at row: " << input_tok.line << " column: " << input_tok.column << " was not matched with expected \"" << terminal_names[abs(expected_symbol)] <<"\""<<endl;
    			exit(0);
    			parse_stack.pop();
    		}
    	} else if (expected_symbol > 0) {

    		if(parse_table[abs(expected_symbol)-1][input_tok.num-1] == 0) {
    			vector<int> this_nonterminals_first = first_sets[expected_symbol];
    			vector<int> this_nonterminals_follow = follow_sets[expected_symbol];
    			cout << "Error: Invalid input for symbol pair: (" << nonterminal_names[expected_symbol] << ", " << input_tok.image << ")"<<endl;
    			exit(0);
    			do {
    				input_tok = scan();
    				if(_in_array(this_nonterminals_first, input_tok.num)) {
    					cout << "\tInput token: \"" << input_tok.image << "\" was found in \"" << nonterminal_names[expected_symbol] << "\"\'s first set."<<endl;
    					break;
    				} else if (_in_array(this_nonterminals_follow, input_tok.num)) {
    					cout << "\tInput token: \"" << input_tok.image << "\" was found in \"" << nonterminal_names[expected_symbol] << "\"'s first set."<<endl;
    					parse_stack.pop();
    					break;
    				}
    			} while(input_tok.num != tok_eof);
    		} else {
    			vector<int> pred_rule = right_hand_sides[parse_table[abs(expected_symbol) - 1][input_tok.num - 1] - 1];


    			cout << "Predicted: " << nonterminal_names[expected_symbol] << " -> ";
				parse_stack.pop();

				int i = 0;
				while(pred_rule[i] != 0) {
					parse_stack.push(pred_rule[i]);
					++i;
				}

				for(i = i-1; i >= 0; i--) {
					if(pred_rule[i] < 0)
						cout << terminal_names[abs(pred_rule[i])] << " ";
					else
						cout << nonterminal_names[abs(pred_rule[i])] << " ";
				}
				i = 0; 
				cout << endl; 

			}
    	}
    } while (parse_stack.top() != -1);
    cout << "succeed!" << endl;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x280, %rsp            # imm = 0x280
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x178(%rbp)
leaq -0x58(%rbp), %rdi
movq %rdi, -0x170(%rbp)
callq 0x9240
leaq -0x98(%rbp), %rdi
callq 0x4420
movq -0x170(%rbp), %rdi
leaq 0x119cc(%rip), %rsi     # 0x19330
callq 0x9270
jmp 0x796b
leaq -0xe0(%rbp), %rdi
callq 0x3e00
jmp 0x7979
leaq -0x98(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x92a0
leaq -0xe0(%rbp), %rdi
callq 0x44f0
leaq -0x58(%rbp), %rdi
callq 0x9300
movq %rax, -0x180(%rbp)
jmp 0x79aa
movq -0x180(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x5c(%rbp)
cmpl $0x20, -0x98(%rbp)
jne 0x7a96
movq 0x11606(%rip), %rdi     # 0x18fd0
leaq 0x989c(%rip), %rsi      # 0x1126d
callq 0x3200
movq %rax, -0x188(%rbp)
jmp 0x79df
movq -0x188(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x31e0
movq %rax, -0x190(%rbp)
jmp 0x79fb
movq -0x190(%rbp), %rdi
leaq 0x987c(%rip), %rsi      # 0x11285
callq 0x3200
movq %rax, -0x198(%rbp)
jmp 0x7a17
movq -0x198(%rbp), %rdi
movl -0x68(%rbp), %esi
callq 0x3380
movq %rax, -0x1a0(%rbp)
jmp 0x7a2f
movq -0x1a0(%rbp), %rdi
leaq 0x9853(%rip), %rsi      # 0x11290
callq 0x3200
movq %rax, -0x1a8(%rbp)
jmp 0x7a4b
movq -0x1a8(%rbp), %rdi
movl -0x64(%rbp), %esi
callq 0x3380
movq %rax, -0x1b0(%rbp)
jmp 0x7a63
movq -0x1b0(%rbp), %rdi
movq 0x1154f(%rip), %rsi     # 0x18fc0
callq 0x3230
jmp 0x7a78
xorl %edi, %edi
callq 0x32b0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x8125
cmpl $0x0, -0x5c(%rbp)
jge 0x7c7a
movl -0x98(%rbp), %eax
movl -0x5c(%rbp), %ecx
movl %ecx, %edx
negl %edx
cmovnsl %edx, %ecx
cmpl %ecx, %eax
jne 0x7b49
movq 0x11511(%rip), %rdi     # 0x18fd0
leaq 0x97d4(%rip), %rsi      # 0x1129a
callq 0x3200
movq %rax, -0x1b8(%rbp)
jmp 0x7ad4
movq -0x1b8(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x31e0
movq %rax, -0x1c0(%rbp)
jmp 0x7af0
movq -0x1c0(%rbp), %rdi
leaq 0x97a4(%rip), %rsi      # 0x112a2
callq 0x3200
jmp 0x7b05
leaq -0x118(%rbp), %rdi
callq 0x3e00
jmp 0x7b13
leaq -0x98(%rbp), %rdi
leaq -0x118(%rbp), %rsi
movq %rsi, -0x1c8(%rbp)
callq 0x92a0
movq -0x1c8(%rbp), %rdi
callq 0x44f0
leaq -0x58(%rbp), %rdi
callq 0x9320
jmp 0x7b44
jmp 0x7c75
movq 0x11480(%rip), %rdi     # 0x18fd0
leaq 0x974d(%rip), %rsi      # 0x112a4
callq 0x3200
movq %rax, -0x1d0(%rbp)
jmp 0x7b65
movq -0x1d0(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x31e0
movq %rax, -0x1d8(%rbp)
jmp 0x7b81
movq -0x1d8(%rbp), %rdi
leaq 0x96f6(%rip), %rsi      # 0x11285
callq 0x3200
movq %rax, -0x1e0(%rbp)
jmp 0x7b9d
movq -0x1e0(%rbp), %rdi
movl -0x68(%rbp), %esi
callq 0x3380
movq %rax, -0x1e8(%rbp)
jmp 0x7bb5
movq -0x1e8(%rbp), %rdi
leaq 0x96cd(%rip), %rsi      # 0x11290
callq 0x3200
movq %rax, -0x1f0(%rbp)
jmp 0x7bd1
movq -0x1f0(%rbp), %rdi
movl -0x64(%rbp), %esi
callq 0x3380
movq %rax, -0x1f8(%rbp)
jmp 0x7be9
movq -0x1f8(%rbp), %rdi
leaq 0x96b6(%rip), %rsi      # 0x112ad
callq 0x3200
movq %rax, -0x200(%rbp)
jmp 0x7c05
movq -0x178(%rbp), %rdi
addq $0x238, %rdi            # imm = 0x238
movl -0x5c(%rbp), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movslq %eax, %rsi
callq 0x8db0
movq -0x200(%rbp), %rdi
movq %rax, %rsi
callq 0x31e0
movq %rax, -0x208(%rbp)
jmp 0x7c3d
movq -0x208(%rbp), %rdi
leaq 0x9660(%rip), %rsi      # 0x112ab
callq 0x3200
movq %rax, -0x210(%rbp)
jmp 0x7c59
movq -0x210(%rbp), %rdi
movq 0x11359(%rip), %rsi     # 0x18fc0
callq 0x3230
jmp 0x7c6e
xorl %edi, %edi
callq 0x32b0
jmp 0x80b2
cmpl $0x0, -0x5c(%rbp)
jle 0x80b0
movq -0x178(%rbp), %rdi
addq $0x2b0, %rdi            # imm = 0x2B0
movl -0x5c(%rbp), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x86a0
movq %rax, %rdi
movl -0x98(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x86c0
cmpl $0x0, (%rax)
jne 0x7e12
movq -0x178(%rbp), %rdi
addq $0x268, %rdi            # imm = 0x268
movslq -0x5c(%rbp), %rsi
callq 0x86a0
movq %rax, %rsi
leaq -0x130(%rbp), %rdi
callq 0x87e0
jmp 0x7cec
movq -0x178(%rbp), %rdi
addq $0x280, %rdi            # imm = 0x280
movslq -0x5c(%rbp), %rsi
callq 0x86a0
movq %rax, %rsi
leaq -0x148(%rbp), %rdi
callq 0x87e0
jmp 0x7d14
movq 0x112b5(%rip), %rdi     # 0x18fd0
leaq 0x95ac(%rip), %rsi      # 0x112ce
callq 0x3200
movq %rax, -0x218(%rbp)
jmp 0x7d30
movq -0x178(%rbp), %rdi
addq $0x250, %rdi            # imm = 0x250
movslq -0x5c(%rbp), %rsi
callq 0x8db0
movq -0x218(%rbp), %rdi
movq %rax, %rsi
callq 0x31e0
movq %rax, -0x220(%rbp)
jmp 0x7d5f
movq -0x220(%rbp), %rdi
leaq 0x9589(%rip), %rsi      # 0x112f6
callq 0x3200
movq %rax, -0x228(%rbp)
jmp 0x7d7b
movq -0x228(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x31e0
movq %rax, -0x230(%rbp)
jmp 0x7d97
movq -0x230(%rbp), %rdi
leaq 0x963e(%rip), %rsi      # 0x113e3
callq 0x3200
movq %rax, -0x238(%rbp)
jmp 0x7db3
movq -0x238(%rbp), %rdi
movq 0x111ff(%rip), %rsi     # 0x18fc0
callq 0x3230
jmp 0x7dc8
xorl %edi, %edi
callq 0x32b0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x7e01
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x148(%rbp), %rdi
callq 0x3900
leaq -0x130(%rbp), %rdi
callq 0x3900
jmp 0x8125
movq -0x178(%rbp), %rdi
movq %rdi, %rax
addq $0x2e0, %rax            # imm = 0x2E0
movq %rax, -0x240(%rbp)
addq $0x2b0, %rdi            # imm = 0x2B0
movl -0x5c(%rbp), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
decl %eax
movslq %eax, %rsi
callq 0x86a0
movq %rax, %rdi
movl -0x98(%rbp), %eax
decl %eax
movslq %eax, %rsi
callq 0x86c0
movq -0x240(%rbp), %rdi
movl (%rax), %eax
decl %eax
movslq %eax, %rsi
callq 0x86a0
movq %rax, %rsi
leaq -0x160(%rbp), %rdi
callq 0x87e0
jmp 0x7e7b
movq 0x1114e(%rip), %rdi     # 0x18fd0
leaq 0x9470(%rip), %rsi      # 0x112f9
callq 0x3200
movq %rax, -0x248(%rbp)
jmp 0x7e97
movq -0x178(%rbp), %rdi
addq $0x250, %rdi            # imm = 0x250
movslq -0x5c(%rbp), %rsi
callq 0x8db0
movq -0x248(%rbp), %rdi
movq %rax, %rsi
callq 0x31e0
movq %rax, -0x250(%rbp)
jmp 0x7ec6
movq -0x250(%rbp), %rdi
leaq 0x9431(%rip), %rsi      # 0x11305
callq 0x3200
jmp 0x7edb
leaq -0x58(%rbp), %rdi
callq 0x9320
jmp 0x7ee6
movl $0x0, -0x164(%rbp)
movslq -0x164(%rbp), %rsi
leaq -0x160(%rbp), %rdi
callq 0x86c0
cmpl $0x0, (%rax)
je 0x7f5d
movslq -0x164(%rbp), %rsi
leaq -0x160(%rbp), %rdi
callq 0x86c0
movq %rax, %rsi
leaq -0x58(%rbp), %rdi
callq 0x9270
jmp 0x7f29
movl -0x164(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x164(%rbp)
jmp 0x7ef0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x3900
jmp 0x8125
movl -0x164(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x164(%rbp)
cmpl $0x0, -0x164(%rbp)
jl 0x8083
movslq -0x164(%rbp), %rsi
leaq -0x160(%rbp), %rdi
callq 0x86c0
cmpl $0x0, (%rax)
jge 0x7fff
movq -0x178(%rbp), %rax
addq $0x238, %rax            # imm = 0x238
movq %rax, -0x260(%rbp)
movslq -0x164(%rbp), %rsi
leaq -0x160(%rbp), %rdi
callq 0x86c0
movq -0x260(%rbp), %rdi
movl (%rax), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movslq %eax, %rsi
callq 0x8db0
movq %rax, %rsi
movq 0x10ff6(%rip), %rdi     # 0x18fd0
callq 0x31e0
movq %rax, -0x258(%rbp)
jmp 0x7fe8
movq -0x258(%rbp), %rdi
leaq 0x935b(%rip), %rsi      # 0x11351
callq 0x3200
jmp 0x7ffd
jmp 0x806d
movq -0x178(%rbp), %rax
addq $0x250, %rax            # imm = 0x250
movq %rax, -0x270(%rbp)
movslq -0x164(%rbp), %rsi
leaq -0x160(%rbp), %rdi
callq 0x86c0
movq -0x270(%rbp), %rdi
movl (%rax), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movslq %eax, %rsi
callq 0x8db0
movq %rax, %rsi
movq 0x10f88(%rip), %rdi     # 0x18fd0
callq 0x31e0
movq %rax, -0x268(%rbp)
jmp 0x8056
movq -0x268(%rbp), %rdi
leaq 0x92ed(%rip), %rsi      # 0x11351
callq 0x3200
jmp 0x806b
jmp 0x806d
jmp 0x806f
movl -0x164(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x164(%rbp)
jmp 0x7f6c
movl $0x0, -0x164(%rbp)
movq 0x10f3c(%rip), %rdi     # 0x18fd0
movq 0x10f25(%rip), %rsi     # 0x18fc0
callq 0x3230
jmp 0x80a2
leaq -0x160(%rbp), %rdi
callq 0x3900
jmp 0x80b0
jmp 0x80b2
jmp 0x80b4
leaq -0x58(%rbp), %rdi
callq 0x9300
movq %rax, -0x278(%rbp)
jmp 0x80c6
movq -0x278(%rbp), %rax
cmpl $-0x1, (%rax)
jne 0x7998
movq 0x10ef3(%rip), %rdi     # 0x18fd0
leaq 0x9226(%rip), %rsi      # 0x1130a
callq 0x3200
movq %rax, -0x280(%rbp)
jmp 0x80f2
movq -0x280(%rbp), %rdi
movq 0x10ec0(%rip), %rsi     # 0x18fc0
callq 0x3230
jmp 0x8107
leaq -0x98(%rbp), %rdi
callq 0x44f0
leaq -0x58(%rbp), %rdi
callq 0x9340
addq $0x280, %rsp            # imm = 0x280
popq %rbp
retq
leaq -0x98(%rbp), %rdi
callq 0x44f0
leaq -0x58(%rbp), %rdi
callq 0x9340
movq -0xa0(%rbp), %rdi
callq 0x3390
nopw %cs:(%rax,%rax)