def render_grammar(grammar: Grammar):
    g = Digraph('production_hierarchy')

    for production, children in grammar.productions.items():
        color = ["black", "red"][grammar.is_abstract_production(production)]
        color = [color, "purple"][hasattr(production, "__is_generated")]

        production_name = production.__name__

        g.node(name=production_name,
               label=production_name,
               color=color,
               shape="hexagon")

        for child_name, child_info in children.items():
            g.node(name=production_name + child_name,
                   label=str(child_info.symbol[0].__name__) + "\n" +
                   child_name,
                   color=color,
                   shape="box")

            g.edge(production_name, production_name + child_name)

    for sub_production, super_productions in grammar.symbol_supertypes.items():
        for super_production in super_productions[:1]:
            g.edge(super_production.__name__,
                   sub_production.__name__,
                   constraint='true')

    return g
Ejemplo n.º 2
0
class GrammarValidationTest(unittest.TestCase):
    grammar = Grammar.from_modules(arithmetic)

    def test_invalid_trees(self):
        with self.assertRaisesRegex(GrammarError, "Expected child.*Optional"):
            self.grammar.validate_tree(
                Addition(Addition(Constant(1)), Constant(1)))

        with self.assertRaisesRegex(GrammarError, "Expected child of type.*"):
            self.grammar.validate_tree(Addition(UnrelatedClass(), Constant(1)))

        with self.assertRaisesRegex(GrammarError,
                                    "Unexpected sequence-like.*"):
            self.grammar.validate_tree(
                Addition([Constant(1), Constant(2)], Constant(1)))

        with self.assertRaisesRegex(GrammarError, "Expected sequence.*"):
            s = Sum()
            s.addends = Constant(1)
            self.grammar.validate_tree(s)

    def test_valid_trees(self):
        valid_trees = [
            arithmetic.parse_rpn(t) for t in [
                "1 2 + 2.5 * 2 5 SUM", "1 2 3 SUM 4 5 SUM 6 7 SUM",
                "1 2 3 SUM 4 5 SUM 6 7 SUM 8.5 *"
            ]
        ]

        for valid_tree in valid_trees:
            self.assertTrue(self.grammar.validate_tree(valid_tree))
Ejemplo n.º 3
0
def render_grammar(grammar: Grammar):
    g = Digraph('production_hierarchy')

    for production in grammar.productions:
        color = ["black", "red"][grammar.is_abstract_production(production)]
        color = [color, "purple"][hasattr(production, "__is_generated")]

        g.node(name=production.__name__,
               label=production.__name__,
               color=color,
               shape="box")

    for sub_production, super_productions in grammar.super_productions.items():
        for super_production in super_productions[:1]:
            g.edge(super_production.__name__, sub_production.__name__)

    return g
Ejemplo n.º 4
0
    def get_ast_root(self):
        ast_root = self.analysis_context.ast

        if isinstance(ast_root, Exception):
            raise PatternMatchError("AST is not available") from ast_root

        if ast_root is None:
            raise PatternMatchError("AST is not available")

        # TODO: transformed dict or grammar should be available in analysis_context
        ast_root = DictTransformer(Grammar.from_modules(ast),
                                   implicit_terminals=True).transform(ast_root)

        if not isinstance(ast_root, ast.SourceUnit):
            raise PatternNotApplicableError("Unrecognized AST root type.")

        return ast_root
Ejemplo n.º 5
0
class DictTransformerTest(unittest.TestCase):
    grammar = Grammar.from_modules(simple)
    transformer = DictTransformer(grammar=grammar, class_identifier="type")

    pprint(grammar.grammar_info())

    def test(self):
        tree = {
            "type":
            "B",
            "seq": [{
                "type": "C",
                "single": {
                    "type": "B",
                    "seq": []
                }
            }, {
                "type": "A",
                "optional": {
                    "type": "E"
                }
            }, {
                "type": "A",
                "optional": {
                    "type": "A"
                }
            }, {
                "type": "A"
            }]
        }

        ast = self.transformer.transform(tree)

        self.assertEqual(ast.seq[0].single.seq, [])
        self.assertEqual(ast.seq[0].__class__, simple.C)
        self.assertEqual(ast.seq[1].__class__, simple.A)
        self.assertEqual(ast.seq[1].optional.__class__, simple.E)
Ejemplo n.º 6
0
from securify.grammar import Grammar
from securify.solidity.v_0_5_x import solidity_grammar


def render_grammar(grammar: Grammar):
    g = Digraph('production_hierarchy')

    for production in grammar.productions:
        color = ["black", "red"][grammar.is_abstract_production(production)]
        color = [color, "purple"][hasattr(production, "__is_generated")]

        g.node(name=production.__name__,
               label=production.__name__,
               color=color,
               shape="box")

    for sub_production, super_productions in grammar.super_productions.items():
        for super_production in super_productions[:1]:
            g.edge(super_production.__name__, sub_production.__name__)

    return g


if __name__ == '__main__':
    grammar = Grammar.from_modules(solidity_grammar)

    g = render_grammar(grammar)

    g.format = "png"
    g.render("test", cleanup=True)