Ejemplo n.º 1
0
def execute_banana_string(banana, driver=None, emitter=emit.PrintEmitter()):
    """
    Execute the provided banana string.
    It will run the parse phase, and the typechecker.
    :type banana: str
    :param banana: The string to parse and type check.
    :type driver: monasca_analytics.spark.driver.DriverExecutor | None
    :param driver: Driver that will manage the created
        components and connect them together.
    :type emitter: emit.Emitter
    :param emitter: Emitter for reporting errors/warning.
    """
    try:
        # Convert the grammar into an AST
        parser = grammar.banana_grammar(emitter)
        ast = parser.parse(banana)
        # Compute the type table for the given AST
        type_table = typeck.typeck(ast)
        # Remove from the tree path that are "dead"
        deadpathck.deadpathck(ast, type_table, emitter)
        # Check that there's at least one path to be executed
        deadpathck.contains_at_least_one_path_to_a_sink(ast, type_table)
        # Evaluate the script
        if driver is not None:
            ev.eval_ast(ast, type_table, driver)
    except exception.BananaException as err:
        emitter.emit_error(err.get_span(), str(err))
    except p.ParseSyntaxException as err:
        emitter.emit_error(span_util.from_pyparsing_exception(err), err.msg)
    except p.ParseFatalException as err:
        emitter.emit_error(span_util.from_pyparsing_exception(err), err.msg)
    except p.ParseException as err:
        emitter.emit_error(span_util.from_pyparsing_exception(err), err.msg)
Ejemplo n.º 2
0
def compute_type_table(banana):
    """
    Compute the type table for the provided banana string
    if possible.
    :type banana: str
    :param banana: The string to parse and type check.
    """
    # Convert the grammar into an AST
    parser = grammar.banana_grammar()
    ast = parser.parse(banana)
    # Compute the type table for the given AST
    return typeck.typeck(ast)
 def test_banana_should_pass_when_more_source_sink(self):
     banana_str = "" +\
         "a = CloudMarkovChainSource()\n" +\
         "b = StdoutSink()\n" +\
         "c = CloudIngestor()\n" +\
         "d = LiNGAM()\n" +\
         "a -> c -> d -> b"
     # Convert the grammar into an AST
     parser = grammar.banana_grammar()
     ast = parser.parse(banana_str)
     # Compute the type table for the given AST
     type_table = typeck.typeck(ast)
     # Remove from the tree path that are "dead"
     deadpathck.deadpathck(ast, type_table)
     deadpathck.contains_at_least_one_path_to_a_sink(ast, type_table)
     # We should reach this line.
     self.assertTrue(True)
Ejemplo n.º 4
0
def compute_evaluation_context(banana, cb=lambda *a, **k: None):
    """
    Compute the evaluation context for the provided
    banana string.
    :type banana_str: str
    :param banana_str: The string to parse and type check.
    :param cb: Callback called after each statement
    """
    parser = grammar.banana_grammar()
    ast = parser.parse(banana)
    type_table = typeck.typeck(ast)
    context = ctx.EvaluationContext()

    def custom_cb(_type, lhs, value):
        cb(context, _type, lhs, value)

    ev.eval_statements_generic(ast.statements, type_table, context, custom_cb)
 def test_banana_should_fail_when_no_sink(self):
     banana_str = "" +\
         "a = CloudMarkovChainSource()\n" +\
         "b = StdoutSink()\n" +\
         "c = CloudIngestor()\n" +\
         "d = LiNGAM()\n" +\
         "a -> c -> d"
     # Convert the grammar into an AST
     parser = grammar.banana_grammar()
     ast = parser.parse(banana_str)
     # Compute the type table for the given AST
     type_table = typeck.typeck(ast)
     # Remove from the tree path that are "dead"
     deadpathck.deadpathck(ast, type_table)
     self.assertRaises(exception.BananaNoFullPath,
                       deadpathck.contains_at_least_one_path_to_a_sink, ast,
                       type_table)
 def test_banana_should_not_remove_anything(self):
     banana_str = "" +\
         "a = CloudMarkovChainSource()\n" +\
         "b = StdoutSink()\n" +\
         "c = CloudIngestor()\n" +\
         "d = LiNGAM()\n" +\
         "a -> c -> d -> b"
     emitter = CustomEmitter()
     # Convert the grammar into an AST
     parser = grammar.banana_grammar(emitter)
     ast = parser.parse(banana_str)
     # Compute the type table for the given AST
     type_table = typeck.typeck(ast)
     # Remove from the tree path that are "dead"
     deadpathck.deadpathck(ast, type_table, emitter)
     self.assertEqual(emitter.nb_errors, 0)
     self.assertEqual(emitter.nb_warnings, 0)
     self.assertEqual(len(ast.components), 4)
     self.assertEqual(len(list(ast.connections.connections)), 3)
Ejemplo n.º 7
0
 def test_banana_should_not_remove_anything(self):
     banana_str = "" +\
         "a = CloudMarkovChainSource()\n" +\
         "b = StdoutSink()\n" +\
         "c = CloudIngestor()\n" +\
         "d = LiNGAM()\n" +\
         "a -> c -> d -> b"
     emitter = CustomEmitter()
     # Convert the grammar into an AST
     parser = grammar.banana_grammar(emitter)
     ast = parser.parse(banana_str)
     # Compute the type table for the given AST
     type_table = typeck.typeck(ast)
     # Remove from the tree path that are "dead"
     deadpathck.deadpathck(ast, type_table, emitter)
     self.assertEqual(emitter.nb_errors, 0)
     self.assertEqual(emitter.nb_warnings, 0)
     self.assertEqual(len(ast.components), 4)
     self.assertEqual(len(list(ast.connections.connections)), 3)
Ejemplo n.º 8
0
def try_compute_type_table(banana):
    """
    Compute the type table for the provided banana string
    if possible. Does not throw any exception if it fails.
    :type banana: str
    :param banana: The string to parse and type check.
    """
    try:
        # Convert the grammar into an AST
        parser = grammar.banana_grammar()
        ast = parser.parse(banana)
        # Compute the type table for the given AST
        return typeck.typeck(ast)
    except exception.BananaException:
        return None
    except p.ParseSyntaxException:
        return None
    except p.ParseFatalException:
        return None
    except p.ParseException:
        return None
Ejemplo n.º 9
0
def upgrade_test_case():
    grammar = banana_grammar()
    regex_raise = re.compile("#(?: )*RAISE(?: )*([^\n]+)")
    regex_ast_eq = re.compile("#(?: )*AST_EQ(?: )(?: )*([^\n]+)")
    regex_stmt_eq = re.compile("#(?: )*STMT_EQ(?: )(?: )*([^\n]+)")
    regex_conn_eq = re.compile("#(?: )*CONN_EQ(?: )(?: )*([^\n]+)")

    for root, dirs, files in os.walk('./banana/grammar/should_pass'):
        for filename in files:
            name_no_ext, _ = os.path.splitext(filename)
            _has_some_file_that_should["pass"] = True
            with open(os.path.join(root, filename), 'r') as f:
                content = f.read()

                expected_ast = regex_ast_eq.search(content)
                if expected_ast is not None:
                    expected_ast = expected_ast.group(1)
                expected_stmt = regex_stmt_eq.search(content)
                if expected_stmt is not None:
                    expected_stmt = expected_stmt.group(1)
                expected_conn = regex_conn_eq.search(content)
                if expected_conn is not None:
                    expected_conn = expected_conn.group(1)

                def create_test(test_str, expect_ast, expect_stmt, exp_conn):
                    def should_pass(self):
                        tree = grammar.parse(test_str)
                        if expect_ast is not None:
                            self.assertEqual(str(tree),
                                             expect_ast)
                        if expect_stmt is not None:
                            self.assertEqual(tree.statements_to_str(),
                                             expect_stmt)
                        if exp_conn is not None:
                            self.assertEqual(str(tree.connections),
                                             exp_conn)
                        if exp_conn is None and expect_ast is None and\
                           expect_stmt is None:
                            raise Exception("Expected at least one check!")

                    should_pass.__name__ = "test_banana_pass_" + name_no_ext
                    return should_pass

                setattr(GrammarTestCase, "test_banana_pass_" + name_no_ext,
                        create_test(content, expected_ast, expected_stmt,
                                    expected_conn))

    for root, dirs, files in os.walk('./banana/grammar/should_fail'):
        for filename in files:
            name_no_ext, _ = os.path.splitext(filename)
            _has_some_file_that_should["fail"] = True
            with open(os.path.join(root, filename), 'r') as f:
                content = f.read()

                def create_test(test_str):
                    def should_fail(self):
                        expected_error = regex_raise.search(test_str).group(1)
                        expected_exception = get_exception_from_str(
                            expected_error)
                        self.assertRaises(
                            expected_exception,
                            grammar.parse,
                            test_str)
                    should_fail.__name__ = "test_banana_fail_" + name_no_ext
                    return should_fail

                setattr(GrammarTestCase, "test_banana_fail_" + name_no_ext,
                        create_test(content))
def upgrade_test_case():
    grammar = banana_grammar()
    regex_raise = re.compile("#(?: )*RAISE(?: )*([^\n]+)")
    regex_ast_eq = re.compile("#(?: )*AST_EQ(?: )(?: )*([^\n]+)")
    regex_stmt_eq = re.compile("#(?: )*STMT_EQ(?: )(?: )*([^\n]+)")
    regex_conn_eq = re.compile("#(?: )*CONN_EQ(?: )(?: )*([^\n]+)")

    for root, dirs, files in os.walk('./banana/grammar/should_pass'):
        for filename in files:
            name_no_ext, _ = os.path.splitext(filename)
            _has_some_file_that_should["pass"] = True
            with open(os.path.join(root, filename), 'r') as f:
                content = f.read()

                expected_ast = regex_ast_eq.search(content)
                if expected_ast is not None:
                    expected_ast = expected_ast.group(1)
                expected_stmt = regex_stmt_eq.search(content)
                if expected_stmt is not None:
                    expected_stmt = expected_stmt.group(1)
                expected_conn = regex_conn_eq.search(content)
                if expected_conn is not None:
                    expected_conn = expected_conn.group(1)

                def create_test(test_str, expect_ast, expect_stmt, exp_conn):
                    def should_pass(self):
                        tree = grammar.parse(test_str)
                        if expect_ast is not None:
                            self.assertEqual(str(tree), expect_ast)
                        if expect_stmt is not None:
                            self.assertEqual(tree.statements_to_str(),
                                             expect_stmt)
                        if exp_conn is not None:
                            self.assertEqual(str(tree.connections), exp_conn)
                        if exp_conn is None and expect_ast is None and\
                           expect_stmt is None:
                            raise Exception("Expected at least one check!")

                    should_pass.__name__ = "test_banana_pass_" + name_no_ext
                    return should_pass

                setattr(
                    GrammarTestCase, "test_banana_pass_" + name_no_ext,
                    create_test(content, expected_ast, expected_stmt,
                                expected_conn))

    for root, dirs, files in os.walk('./banana/grammar/should_fail'):
        for filename in files:
            name_no_ext, _ = os.path.splitext(filename)
            _has_some_file_that_should["fail"] = True
            with open(os.path.join(root, filename), 'r') as f:
                content = f.read()

                def create_test(test_str):
                    def should_fail(self):
                        expected_error = regex_raise.search(test_str).group(1)
                        expected_exception = get_exception_from_str(
                            expected_error)
                        self.assertRaises(expected_exception, grammar.parse,
                                          test_str)

                    should_fail.__name__ = "test_banana_fail_" + name_no_ext
                    return should_fail

                setattr(GrammarTestCase, "test_banana_fail_" + name_no_ext,
                        create_test(content))