#include <iostream>
#include <fstream>
#include <cassert>

#include "nfa.h"
#include "grammar.h"
#include "LL1.h"
using namespace std;

int main(int argc, char** argv) {

    NFA nfa = RexToNFA();
    printNFA(nfa);

    DFA dfa = nfaToDFA(nfa);
    //printDFA(dfa);
    DFA minimizedDFA = minimizeDFA(minimizeDFA(dfa));
    removeUnreachableStates(minimizedDFA);
    //printDFA(minimizedDFA);

    string inputs[6] = {
        "tests/00/00.txt",
        "tests/01/01.txt",
        "tests/02/02.txt",
        "tests/07/07.txt",
        "tests/08_err/08.txt",
        "tests/10_err/10.txt"
    };

    string outputs_lexical[6] = {
    "tests/00/00_my_lexical.txt",
    "tests/01/01_my_lexical.txt",
    "tests/02/02_my_lexical.txt",
    "tests/07/07_my_lexical.txt",
    "tests/08_err/08_my_lexical.txt",
    "tests/10_err/10_my_lexical.txt"
    };

    string outputs_grammar[6] = {
    "tests/00/00_my_grammar.txt",
    "tests/01/01_my_grammar.txt",
    "tests/02/02_my_grammar.txt",
    "tests/07/07_my_grammar.txt",
    "tests/08_err/08_my_grammar.txt",
    "tests/10_err/10_my_grammar.txt"
    };


    int i = 0;
    for (auto input : inputs) {
        LL1 ll;
        //ll.print_grammar_set();

        string content = readfile(input);
        vector<string> token_strings = recognize(minimizedDFA, content,outputs_lexical[i]);

	    bool flag = ll.IsLL1();
	    ll.build_LL1_predict();


	    // ll.print_LL1_predict();
        ll.get_token_strings(token_strings);


        // ll.print_token_strings();
        ll.build_LL1_grammar();


        ll.fileout_LL1_grammar_log(outputs_grammar[i]);


        // ll.print_LL1_grammar_log();
        cout << endl;
        i++;
    }

	

	return 0;
}