Esempio n. 1
0
 def test_parsing_with_no_localized_grammars(self):
     mgr = EvaluableParseManager(self.symbol_table, Grammar())
     parse_tree1 = mgr.parse('message == "2009-07-13"')
     parse_tree2 = mgr.parse('message == "2009-07-13"', None)
     expected_tree = EvaluableParseTree(
         Equal(String("Hello world"), String("2009-07-13")))
     eq_(parse_tree1, parse_tree2)
     eq_(parse_tree1, expected_tree)
Esempio n. 2
0
def get_boolean_evaluator(statment,
                          variables=None,
                          constants=None,
                          grammar_tokens=None):
    """
    an fast and easy to use helper to build a parser with variables and constants.
    return a callable which take a dict of value (for the variables).

    the returning scope will cotains the variables as is, and the constants into the namespace ``const:``

    ie:  'age < const:majority & "o" in name & birthdate > "1983-02-02"'

    :param str statment: the statment to use
    :param list|tuple variables:  the sample of variables
    :param dict constants:  the value for the consts
    :param dict grammar_tokens: all extra parameters must be a valid grammar token replacements. (is_subset='in')
    :return: the parse tree that, if called, return a boolean result
    :rtype: :class:`booleano.parser.trees.ParseTree`
    """

    grammar_tokens = grammar_tokens or {}
    grammar = Grammar(**grammar_tokens)
    if variables is None:
        variables = [{}]

    root_table = variable_symbol_table_builder('root', variables[0])
    """:type: booleano.parser.scope.SymbolTable"""
    if constants:
        root_table.add_subtable(
            constants_symbol_table_builder('const', constants), )

    parse_manager = EvaluableParseManager(root_table, grammar)
    return parse_manager.parse(statment)
Esempio n. 3
0
    def _solve_rules(self, rules, metrics):
        """
        solve the rules using the given metrics.
        metrics must contains all needed metrics.
        :param list[Rule] rules: the
        :param metrics:
        :return:
        :raises:
            pyparsing.ParseException
        """
        results = {}

        root_table = SymbolTable('root', ())

        for metric_name, values in metrics.items():
            # bind to allow "rmq & rmq:xxx"
            root_table.add_object(Bind(metric_name, Constant(bool(values))))
            # bind to allow "rmq:latency" etc
            root_table.add_subtable(
                SymbolTable(
                    metric_name,
                    tuple(Bind(k, Constant(v)) for k, v in values.items())))
        # build the symbol table for all rules (as boolean)
        rules_symbols = SymbolTable('rules', ())

        root_table.add_subtable(rules_symbols)
        for rule in rules:
            rule_name_ = rule['name']

            rules_symbols.add_object(
                Bind(
                    rule_name_,
                    BooleanVariable(
                        partial(get_rule_result,
                                rule_name=rule_name_,
                                rule=rule))))
            rules_symbols.add_subtable(
                SymbolTable(rule_name_, (Bind(
                    'since',
                    DurationVariable(
                        partial(get_since, rule_name=rule_name_,
                                rule=rule))), )))

        parse_manager = EvaluableParseManager(root_table, grammar)

        for rule in rules:

            expression_ = rule['expression']
            try:
                results[rule['name']] = parse_manager.parse(expression_)(
                    results)
            except pyparsing.ParseException as e:
                logger.debug("error while parsing %r: %s", expression_, e)
                raise
        return results
Esempio n. 4
0
 def test_parsing_with_localized_grammars(self):
     castilian_grammar = Grammar(decimal_separator=",",
                                 thousands_separator=".")
     mgr = EvaluableParseManager(self.symbol_table,
                                 Grammar(),
                                 es=castilian_grammar)
     parse_tree = mgr.parse(u"tráfico:peatones_cruzando_calle <= 3,00",
                            "es")
     expected_tree = EvaluableParseTree(
         LessEqual(PedestriansCrossingRoad(), Number(3.0)))
     eq_(parse_tree, expected_tree)
Esempio n. 5
0
 def test_adding_grammar(self):
     """It should be possible to add grammars after instantiation."""
     castilian_grammar = Grammar(decimal_separator=",",
                                 thousands_separator=".")
     mgr = EvaluableParseManager(self.symbol_table, Grammar())
     mgr.add_parser("es", castilian_grammar)
     parse_tree = mgr.parse(u'tráfico:peatones_cruzando_calle <= 3,00',
                            "es")
     expected_tree = EvaluableParseTree(
         LessEqual(PedestriansCrossingRoad(), Number(3.0)))
     eq_(parse_tree, expected_tree)
Esempio n. 6
0
    def test_parsing_with_defined_grammar_but_no_available_translations(self):
        """
        When an expression is written in an supported grammar but there are no
        translated bindings, the default names must be used along with the
        custom grammar.

        """
        french_grammar = Grammar(decimal_separator=",",
                                 thousands_separator=".")
        mgr = EvaluableParseManager(self.symbol_table,
                                    Grammar(),
                                    fr=french_grammar)
        # French grammar is not supported:
        parse_tree = mgr.parse("traffic:pedestrians_crossing_road <= 3,0",
                               "fr")
        expected_tree = EvaluableParseTree(
            LessEqual(PedestriansCrossingRoad(), Number(3)))
        eq_(parse_tree, expected_tree)
Esempio n. 7
0
    def test_parsing_with_undefined_grammar_and_no_translated_bindings(self):
        """
        When an expression is written in an unsupported grammar, a parser
        based on the generic grammar must be created and used.

        If there are no translated bindings, the default names must be used.

        """
        log_handler = LoggingHandlerFixture()
        mgr = EvaluableParseManager(self.symbol_table, Grammar())
        # French grammar is not supported:
        parse_tree = mgr.parse("traffic:pedestrians_crossing_road <= 3.0",
                               "fr")
        expected_tree = EvaluableParseTree(
            LessEqual(PedestriansCrossingRoad(), Number(3)))
        eq_(parse_tree, expected_tree)
        # Checking the log:
        info = "Generated parser for unknown grammar %s" % repr('fr')
        ok_(info in log_handler.handler.messages['info'])
        log_handler.undo()
Esempio n. 8
0
    def test_parsing_with_undefined_grammar_but_available_translations(self):
        """
        When an expression is written in an unsupported grammar, a parser
        based on the generic grammar must be created and used.

        The respective translated bindings must be used if available.

        """
        log_handler = LoggingHandlerFixture()
        mgr = EvaluableParseManager(self.symbol_table, Grammar())
        # Castilian grammar is not supported:
        parse_tree = mgr.parse(u"tráfico:peatones_cruzando_calle <= 3.0", "es")
        expected_tree = EvaluableParseTree(
            LessEqual(PedestriansCrossingRoad(), Number(3)))
        eq_(parse_tree, expected_tree)
        # Checking the log:
        info = "Generated parser for unknown grammar %s" % repr(u'es')

        ok_(info in log_handler.handler.messages['info'])
        log_handler.undo()
Esempio n. 9
0
# 2: create the parser with se symbol table and the grammar (customized)

grammar = Grammar(belongs_to='in')
parse_manager = EvaluableParseManager(root_table, grammar)
# 3: compile a expression
# compiled_expression = parse_manager.parse('age < majority & "o" in name & birthdate > "1983-02-02"')

# check the command line args
if len(sys.argv) == 1:
    print("try something like %s '\"a\" in name'" % sys.argv[0])
    exit(1)

stmt = " ".join(sys.argv[1:])
print("searching with expression %r" % stmt)
try:
    compiled_expression = parse_manager.parse(stmt)
except pyparsing.ParseException as e:
    attrs = dict(expr=stmt,
                 e=e,
                 tild='^',
                 grammar="\n".join(
                     "%s => '%s'" % (k, v)
                     for k, v in grammar.get_all_tokens().items()))
    msg = "error while parsing the expression {expr} at {e.lineno}:{e.col}: {e}\n" \
          "{e.line}\n" \
          "{tild:->{e.col}}\n" \
          " valid grammar : {grammar}".format(**attrs)
    print(msg)
    exit(2)
else:
    # run the rule for all sample data
Esempio n. 10
0
        Bind('name', name),
        Bind('training', DurationVariable('training')),
        Bind('bending', SetVariable('bending')),
    ]), SymbolTable('consts', [
        Bind('majority', Number(18)),
    ]))

grammar = Grammar(**{'and': 'and', 'or': 'or', 'belongs_to': 'in'})

# 2: create the parser with se symbol table and the grammar (customized)
parse_manager = EvaluableParseManager(symbols, grammar)
# 3: compile a expression
compiled_expression = parse_manager.parse(
    'character:age < consts:majority and '
    '"a" in character and '
    '('
    '    {"water"} in character:bending or '
    '    character:training > "3d4h"'
    ')')

sample = [
    {
        "name": "katara",
        "age": 14,
        "training": datetime.timedelta(days=24),
        "bending": {'water'}
    },
    {
        "name": "aang",
        "age": 112,
        "training": datetime.timedelta(days=6 * 365),