示例#1
0
 def test_elim_null_prod(self):
     for x, y in zip(cases.elim_null_test_cases,
                     cases.elim_null_test_cases_targets):
         x = gm.parse(x)
         y = gm.parse(y)
         ng = elim_null(x)
         self.assertEqual(ng, y)
示例#2
0
 def test_elim_unit_prod(self):
     for x, y in zip(cases.elim_unit_test_cases,
                     cases.elim_unit_test_cases_targets):
         x = gm.parse(x)
         y = gm.parse(y)
         ng = elim_unit(x)
         ng = remove_same_rules(ng, False, False)
         self.assertEqual(ng, y)
示例#3
0
 def test_elim_left_recursion(self):
     for x, y in zip(cases.elim_lr_test_cases,
                     cases.elim_lr_test_cases_targets):
         x, f = x
         x = gm.parse(x)
         if f:
             x = gm.reverse_grammar(x)
         y = gm.parse(y)
         ng = elim_lr(x)
         self.assertEqual(ng, y)
示例#4
0
 def test_follow_set(self):
     for x, y in zip(cases.first_follow_set_test_cases,
                     cases.follow_set_test_cases_targets):
         x = gm.parse(x)
         fs = first_sets(x)
         start = list(x.keys())[0]
         fls = follow_sets(start, x, fs)
         self.assertEqual(fls, y)
示例#5
0
 def test_first_set(self):
     for x, y in zip(cases.first_follow_set_test_cases,
                     cases.first_set_test_cases_targets):
         x = gm.parse(x)
         fs = first_sets(x)
         self.assertEqual(fs, y)
示例#6
0
 def test_is_nullable(self):
     for x, y in zip(cases.is_nullable_test_cases,
                     cases.is_nullable_test_cases_targets):
         x = gm.parse(x)
         self.assertEqual(is_nullable("S", x), y)
示例#7
0
 def test_parse_grammar(self):
     for x, y in zip(cases.parser_test_cases,
                     cases.parser_test_cases_targets):
         self.assertEqual(gm.parse(x), y)
示例#8
0
def main():
    args = docopt(__doc__)

    # check if file exits
    if not os.path.exists(args["FILE"]):
        print(cf.red("{} doesn't exist\n".format(args["FILE"])))
        exit(1)

    # create the output file
    of = args["-o"]
    open(of, "w").close()

    f = open(args["FILE"])
    grammar = f.read()
    f.close()

    # clear console
    clear()

    # print banner
    print(cf.yellow_bold(BANNER))

    print(cf.bold_white("Input Grammar:\n"))
    pgrammar = gm.parse(grammar)
    orignal = pgrammar
    gm.pprint(pgrammar)
    print()

    write_to_output(of, "Input Grammar", gm.str_pgrammar(pgrammar))

    choices = [
        "Remove Null Productions",
        "Remove Unit Productions",
        "Remove Left Recursion",
        "First Sets",
        "Follow Sets",
        "Parsing Table",
    ]

    misc_choices = [
        "Restore Original Grammar",
        "Print Current Grammar",
        "Clear",
        "Exit",
    ]

    question = {
        "type": "list",
        "name": "ops",
        "message": "Which operation would you like to perform?",
        "choices": choices + [Separator()] + misc_choices,
    }

    reuse_confirm = {
        "type": "confirm",
        "name": "last_grammar",
        "message": "Use this grammar output for subsequent operations?",
        "default": True,
    }

    reverse_confirm = {
        "type": "confirm",
        "name": "reverse_grammar",
        "message": "Reverse Non-Terminal ordering?",
        "default": True,
    }

    start_input = {
        "type": "input",
        "name": "start_sym",
        "message": "Enter Start Symbol:",
    }

    # will contain the last output
    output = None
    # if last output was a grammar (as opposed to follow sets)
    output_grammar = False

    while True:
        answer = prompt(question)
        choice = answer["ops"]

        if choice == misc_choices[0]:
            pgrammar = orignal
            print(cf.white_bold("\nRestored\n"))
            gm.pprint(pgrammar)
            print()
            write_to_output(of, choice, gm.str_pgrammar(pgrammar))
            continue

        elif choice == misc_choices[1]:
            print()
            gm.pprint(pgrammar)
            print()
            continue

        elif choice == misc_choices[2]:
            clear()
            continue

        if choice == misc_choices[3]:
            print(cf.cyan("Bye!"))
            print("Remember! Logs are saved in", of)
            print()
            break

        # --------

        if choice == choices[0]:
            output = elim_null(pgrammar)

        elif choice == choices[1]:
            output = elim_unit(pgrammar)
            output = remove_same_rules(output, False, False)

        elif choice == choices[2]:
            continuel = False
            for rule in pgrammar.values():
                if "eps" in rule:
                    print(
                        cf.red(
                            "\nGrammar contains null productions. This operation can't"
                            " be performed\n"))
                    continuel = True
                    break

            if continuel:
                continue

            answer = prompt(reverse_confirm)
            reverse = answer["reverse_grammar"]
            if reverse:
                print(
                    "\nReversing the order of non-terminals for Left Recursion Removal."
                )

                ng = gm.reverse_grammar(pgrammar)
            else:
                ng = pgrammar

            ng = elim_lr(ng)
            if reverse:
                ng = gm.reverse_grammar(ng)
            output = ng

        elif choice == choices[3]:
            fs = first_sets(pgrammar)
            output = fs

        elif choice == choices[4]:
            start_input["validate"] = lambda x: x in pgrammar.keys()
            answer = prompt(start_input)
            fs = first_sets(pgrammar)
            fls = follow_sets(answer["start_sym"], pgrammar, fs)
            output = fls

        elif choice == choices[5]:
            start_input["validate"] = lambda x: x in pgrammar.keys()
            answer = prompt(start_input)
            fs = first_sets(pgrammar)
            fls = follow_sets(answer["start_sym"], pgrammar, fs)

            output = parsing_table(pgrammar, fs, fls)

        if choice != choices[5]:

            # flag to check if the last operation output a pgrammar
            # only the first 3 operations output a grammar
            output_grammar = choices.index(choice) in range(3)

            # print output
            print(cf.bold_green("\n=>\n"))

            (gm.pprint if output_grammar else gm.set_print)(output)

            # log to the output file
            write_to_output(
                of,
                choice,
                (gm.str_pgrammar if output_grammar else gm.str_set)(output),
            )

            print()

            # ask to use grammar from last operation
            if output_grammar:
                answer = prompt(reuse_confirm)
                if answer["last_grammar"]:
                    pgrammar = output

        else:
            # print parsing table
            print("\n" + output + "\n")
            write_to_output(
                of,
                choice,
                output,
            )