Exemple #1
0
def parse_from_lexer(lexer, symbol_table, engine, passed_token):
    rotated = False
    while True:
        if passed_token is None or rotated:
            token = utils.get_token_skipping_whitespace(lexer)
        else:
            token = passed_token
            rotated = True
        if token.token_type == TokenType.eof:
            return
        if token.token_type != TokenType.keyword or token.token_value != 'rule':
            raise ValueError("This error should not have occurred. rule keyword is expected, Sir")
        token = utils.get_token_skipping_whitespace(lexer)
        if token.token_type == TokenType.given_name:
            parsed_file = open(token.token_value)
            new_lexer = Lexer(parsed_file)
            parse_from_lexer(new_lexer, symbol_table, engine, None)
        elif token.token_type == TokenType.structure_operator_start:
            rid = get_id(lexer, symbol_table)
            prio = get_priority(lexer)
            condition = condParser.get_condition(lexer, symbol_table, engine)
            actions = get_actions(lexer, symbol_table, engine)
            utils.expect_otherchar(lexer, TokenType.structure_operator_end, '}')
            rule = Rule(rid, prio, condition, actions)
            symbol_table.add_rule_id(rid)
            engine.rules[rid] = rule
        else:
            raise ValueError("Either a given_name of a file containing a rule or { are expected, Sir")
        rotated = True
Exemple #2
0
def get_condition(lexer, symbol_table, engine):
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type != TokenType.keyword or token.token_value != 'condition':
        raise ValueError("Keyword condition expected Sir. Found: " + str(token.token_value))
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type != TokenType.definition_operator:
        raise ValueError('Expected : ,found ' + str(token.token_value), " Sir.")
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type == TokenType.instr_end:
        return TrueCondition()
    elif token.token_type == TokenType.keyword or token.token_type == TokenType.list_start:
        return _build_conditions(token, lexer, symbol_table, engine, 0)
    else:
        raise ValueError("Inappropriate token found " + str(token.token_value))
Exemple #3
0
def get_priority(lexer):
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type != TokenType.keyword or token.token_value != 'priority':
        raise ValueError('Expected priority keyword, Sir. Found ' + str(token.token_value))
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type != TokenType.definition_operator:
        raise ValueError('Expected : ,found ' + str(token.token_value), " Sir.")
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type != TokenType.number:
        raise ValueError('Rule id must be a number, found ' + str(token.token_value))
    rule_id = token.token_value
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type != TokenType.instr_end:
        raise ValueError('Expected ; found ' + str(token.token_value) + " ,Sir.")
    return rule_id
Exemple #4
0
def _parse_comparison_cond(token, lexer, symbol_table, engine, is_negated):
    access_method1, symbol_id1, date_str1, num1 = _get_numeric_comparison_argument(token, lexer, symbol_table, engine)
    operator = _get_comparison_operator(lexer)
    token = utils.get_token_skipping_whitespace(lexer)
    access_method2, symbol_id2, date_str2, num2 = _get_numeric_comparison_argument(token, lexer, symbol_table, engine)
    return _build_comparison_condition(access_method1, symbol_id1, date_str1, num1, operator, access_method2,
                                       symbol_id2, date_str2, num2, is_negated)
Exemple #5
0
def get_actions(lexer, symbol_table, engine):
    last_was_action = False
    actions = []
    utils.expect_keyword(lexer, 'actions')
    utils.expect_otherchar(lexer, TokenType.definition_operator, ':')
    while True:
        if last_was_action:
            token = utils.get_token_skipping_whitespace(lexer)
            if token.token_type == TokenType.list_separator:
                last_was_action = False
                continue
            if token.token_type == TokenType.instr_end:
                break
        else:
            actions.append(parse_action(lexer, symbol_table, engine))
            last_was_action = True
    return actions
Exemple #6
0
def get_id(lexer, symbol_table):
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type != TokenType.keyword or token.token_value != 'id':
        raise ValueError('Expected id keyword, Sir. Found ' + str(token.token_value))
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type != TokenType.definition_operator:
        raise ValueError('Expected : ,found ' + str(token.token_value), " Sir.")
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type != TokenType.number:
        raise ValueError('Rule id must be a number, found ' + str(token.token_value))
    rule_id = token.token_value
    if symbol_table.is_rule_id_busy(rule_id):
        raise ValueError('Id' + str(rule_id) + 'for rule is already taken, Sir')
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type != TokenType.instr_end:
        raise ValueError('Expected ; found ' + str(token.token_value) + " ,Sir.")
    return rule_id
Exemple #7
0
 def parse(self):
     state = 0  # 0 - config, 1 - events, 2 - start, 3 - rules, 4 - done
     while True:
         token = ut.get_token_skipping_whitespace(self.lexer)
         state = self.change_state_on_token(token, state)
         if state == 0:
             file_name = ut.expect_given_name(self.lexer)
             parse_results = config_parser.parse_file(
                 file_name, self.symbol_table)
             currencies = parse_results['currencies']
             stocks = parse_results['stocks']
             for curr in currencies:
                 self.engine.add_currency(curr)
             for st in stocks:
                 self.engine.add_stock(st)
         elif state == 1:
             file_name = ut.expect_given_name(self.lexer)
             parse_results = events_parser.parse_file(
                 file_name, self.symbol_table)
             for event in parse_results:
                 self.engine.add_event(event)
         elif state == 2:
             file_name = ut.expect_given_name(self.lexer)
             parse_results = start_parser.parse_file(
                 file_name, self.symbol_table)
             currencies = parse_results['currencies']
             stocks = parse_results['stocks']
             for curr in currencies:
                 self.engine.add_start_cond(curr)
             for st in stocks:
                 self.engine.add_start_cond(st)
         elif state == 3:
             rule_parser.parse_from_lexer(self.lexer, self.symbol_table,
                                          self.engine, token)
         elif state == 4:
             return
         else:
             raise ValueError("Something went blood wrong, Sir")
Exemple #8
0
def _get_date_arg(lexer, engine):
    token = lexer.get_token()
    if token.token_type != TokenType.list_start:
        if token.token_type == TokenType.whitespace:
            return dateConv.to_str(engine.world.current_day)
        else:
            raise ValueError(
                "Forbidden token found, expected whitespace or ( amount" + str(token.token_value) + " ,Sir.")
    else:
        token = utils.get_token_skipping_whitespace(lexer)
        if token.token_type == TokenType.number:
            result = dateConv.get_date_back_x(dateConv.to_str(engine.world.current_day), math.fabs(token.token_value))
            token = utils.get_token_skipping_whitespace(lexer)
            if token.token_type != TokenType.list_end:
                raise ValueError("Expected ) , found: " + str(token.token_value) + " ,Sir.")
            return dateConv.to_str(result)
        if token.token_type == TokenType.date:
            result = token.token_value
            token = utils.get_token_skipping_whitespace(lexer)
            if token.token_type != TokenType.list_end:
                raise ValueError("Expected ) , found: " + str(token.token_value) + " ,Sir.")
            return dateConv.to_str(result)
        raise ValueError(" Expected Number or @date@, found neither, Sir")
Exemple #9
0
def _build_conditions(token, lexer, symbol_table, engine, depth):
    master = MasterCondition()
    last_was_condition = False
    while True:
        is_negated = False
        if token.token_type == TokenType.logical_operator and token.token_value != '!':
            if last_was_condition:
                master.operators.append(token.token_value)
                last_was_condition = False
                token = utils.get_token_skipping_whitespace(lexer)
                continue
            else:
                raise ValueError("Logical operator was found not following a logical condition, Sir")
        if token.token_type == TokenType.keyword or token.token_type == TokenType.number or (
                        token.token_type == TokenType.logical_operator and token.token_value == '!') \
                and not last_was_condition:
            if token.token_type == TokenType.logical_operator and token.token_value == '!':
                is_negated = True
            if token.token_value == 'currency' or token.token_value == 'stock' or token.token_type == TokenType.number:
                cond = _parse_comparison_cond(token, lexer, symbol_table, engine, is_negated)
                master.conditions.append(cond)
                last_was_condition = True
                token = utils.get_token_skipping_whitespace(lexer)
                continue
            if token.token_value == 'rule':
                cond = _parse_rule_cond(token, lexer, symbol_table, engine, is_negated)
                master.conditions.append(cond)
                last_was_condition = True
                token = utils.get_token_skipping_whitespace(lexer)
                continue
            if token.token_value == 'inc' or token.token_value == 'dec':
                cond = _parse_trend_cond(token, lexer, symbol_table, engine, is_negated)
                master.conditions.append(cond)
                last_was_condition = True
                token = utils.get_token_skipping_whitespace(lexer)
                continue
        if token.token_type == TokenType.list_end and last_was_condition:
            return master
        if token.token_type == TokenType.list_start and not last_was_condition:
            cond = _build_conditions(utils.get_token_skipping_whitespace(lexer), lexer, symbol_table, engine, depth + 1)
            last_was_condition = True
            master.conditions.append(cond)
            token = utils.get_token_skipping_whitespace(lexer)
            continue
        if token.token_type == TokenType.instr_end and last_was_condition:
            if depth == 0:
                break
            else:
                raise ValueError("Unclosed group is present, Sir")
        raise ValueError(
            "Condition should be build by alternating between condition " +
            "or condition groups and || or && symbols, please adhere, Sir. It must also end in a condition."
            " Please check for ; also")
    return master
Exemple #10
0
def _parse_rule_cond(token, lexer, symbol_table, engine, is_negated):
    if token.token_type != TokenType.keyword and token.token_value != 'rule':
        raise ValueError('Rule keyword expected, found: ' + str(token.token_value) + " ,Sir.")
    utils.expect_access_operator(lexer)
    rule_id = int(utils.expect_given_name(lexer))
    if not symbol_table.is_rule_id_busy(rule_id):
        raise ValueError("Trying to check execution or non existant rule: " + str(rule_id) + " ,Sir.")
    rule = engine.rules.get(rule_id)
    utils.expect_access_operator(lexer)
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type != TokenType.keyword or token.token_value != 'executed':
        raise ValueError('Expected executed keyword, found: ' + str(token.token_value) + " ,Sir.")
    return RuleExecCondition(rule, is_negated)
Exemple #11
0
def _get_numeric_comparison_argument(token, lexer, symbol_table, engine):
    if token.token_type == TokenType.number:
        return None, None, None, token.token_value
    if token.token_value == 'currency':
        utils.expect_access_operator(lexer)
        symbol_id = symbol_table.get_currency(utils.expect_given_name(lexer))
        utils.expect_access_operator(lexer)
        token = lexer.get_token()
        if token.token_type == TokenType.keyword and token.token_value == 'rate':
            access_method = engine.world.get_currency_rate
            date_str = _get_date_arg(lexer, engine)
            return access_method, symbol_id, date_str, None
        elif token.token_type == TokenType.keyword and token.token_value == 'have':
            utils.expect_access_operator(lexer)
            token = lexer.get_token()
            if token.token_type == TokenType.keyword and token.token_value == 'amount':
                access_method = engine.investor.has_currency
                return access_method, symbol_id, None, None
            else:
                raise ValueError("Forbidden token found, expected keyword amount " + str(token.token_value) + " ,Sir.")
        else:
            raise ValueError(
                "Forbidden token found, expected keywords rate or have found: " + str(token.token_value) + " ,Sir.")
    else:
        utils.expect_access_operator(lexer)
        symbol_id = symbol_table.get_stock(utils.expect_given_name(lexer))
        utils.expect_access_operator(lexer)
        token = lexer.get_token()
        if token.token_type == TokenType.keyword and token.token_value == 'value':
            access_method = engine.world.get_stock_price
            date_str = _get_date_arg(lexer, engine)
            return access_method, symbol_id, date_str, None
        elif token.token_type == TokenType.keyword and token.token_value == 'have':
            utils.expect_access_operator(lexer)
            token = lexer.get_token()
            if token.token_type == TokenType.keyword and token.token_value == 'amount':
                access_method = engine.investor.has_stock
                return access_method, symbol_id, None, None
            else:
                raise ValueError(
                    "Forbidden token found, expected keyword amount not " + str(token.token_value) + " ,Sir.")
        else:
            raise ValueError("Forbidden token found, expected keyword value or have keywords not " + str(
                token.token_value) + " ,Sir.")
Exemple #12
0
def _parse_trend_cond(token, lexer, symbol_table, engine, is_negated):
    is_inc = False
    symbol_id = None
    access_method = None
    if token.token_value != 'inc' and token.token_value != 'desc':
        raise ValueError('Either of [inc, desc] expected, none found, Sir')
    if token.token_value == 'inc':
        is_inc = True
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type == TokenType.keyword and token.token_value == 'currency':
        utils.expect_access_operator(lexer)
        symbol_id = symbol_table.get_currency(utils.expect_given_name(lexer))
        utils.expect_access_operator(lexer)
        utils.expect_keyword(lexer, 'rate')
        access_method = engine.world.get_currency_rate
    elif token.token_type == TokenType.keyword and token.token_value == 'stock':
        utils.expect_access_operator(lexer)
        symbol_id = symbol_table.get_stock(utils.expect_given_name(lexer))
        utils.expect_access_operator(lexer)
        utils.expect_keyword(lexer, 'value')
        access_method = engine.world.get_stock_price
    else:
        raise ValueError('Either stock or currency keywords expected, found: ' + str(token.token_value) + " ,Sir.")
    utils.expect_keyword(lexer, 'by')
    percent_growth = utils.expect_number(lexer)
    utils.expect_keyword(lexer, 'in')
    days_num = utils.expect_number(lexer)
    trendCond = TrendCondition(engine.world)
    trendCond.accessor_method = access_method
    trendCond.growth_percent = percent_growth
    trendCond.number_of_days = days_num
    trendCond.is_inc = is_inc
    trendCond.is_negated = is_negated
    return trendCond
Exemple #13
0
def _get_comparison_operator(lexer):
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type != TokenType.relations_operator:
        raise ValueError("Relations operator expected, found: " + str(token.token_value) + " ,Sir.")
    return token.token_value
Exemple #14
0
def parse_action(lexer, symbol_table, engine):
    is_buy = False
    is_stock = False
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type != TokenType.keyword and token.token_value not in ['buy', 'sell']:
        raise ValueError('Buy or sell expected to start action, found something else, Sir')
    if token.token_value == 'buy':
        is_buy = True
    token = utils.get_token_skipping_whitespace(lexer)
    if token.token_type != TokenType.keyword and token.token_value not in ['stock', 'currency']:
        raise ValueError('An action requires you to choose either stock or currency, nothing else, Sir')
    if token.token_value == 'stock':
        is_stock = True
    utils.expect_access_operator(lexer)
    symbol_name = utils.expect_given_name(lexer)
    symbol_id = -1
    if is_stock:
        symbol_id = symbol_table.get_stock(symbol_name)
    else:
        symbol_id = symbol_table.get_currency(symbol_name)
    if not is_buy:
        token = utils.get_token_skipping_whitespace(lexer)
        if token.token_type == TokenType.keyword and token.token_value == 'amount':
            token = utils.get_token_skipping_whitespace(lexer)
            if token.token_type == TokenType.number:
                if token.token_value < 0:
                    raise ValueError("You can only sell a positive amount, Sir")
                return build_action(engine, is_buy, is_stock, symbol_id, amount=token.token_value)
            elif token.token_type == TokenType.keyword and token.token_value == 'ALL':
                return build_action(engine, is_buy, is_stock, symbol_id, amount='ALL')
            else:
                raise ValueError("Expecting a number or ALL keyword, found neither of them, Sir")
        elif token.token_type == TokenType.keyword and token.token_value == 'part':
            amount = utils.expect_number(lexer)
            if not 1 <= amount <= 100:
                raise ValueError("Part must be 1 to 100 no more no less, Sir")
            return build_action(engine, is_buy, is_stock, symbol_id, part=amount)
        elif token.token_type == TokenType.keyword and token.token_value == 'for':
            curr_amount = utils.expect_number(lexer)
            if curr_amount < 0:
                raise ValueError("You can only sell for a positive price, Sir")
            return build_action(engine, is_buy, is_stock, symbol_id, curr_amount=curr_amount)
        else:
            raise ValueError("Expecting either amount, part, for, none of those were found, Sir")
    else:
        token = utils.get_token_skipping_whitespace(lexer)
        if token.token_type != TokenType.keyword or token.token_value != 'amount':
            raise ValueError("Expecting keyword amount, Sir")
        token = utils.get_token_skipping_whitespace(lexer)
        buy_amount = 0
        if token.token_type == TokenType.keyword or token.token_value == 'MAX':
            buy_amount = 'MAX'
        elif token.token_type == TokenType.number:
            buy_amount = token.token_value
            if buy_amount < 0:
                raise ValueError("You can only buy a positive amount, Sir")
        else:
            raise ValueError("Unexpected Token, Sir")
        utils.expect_keyword(lexer, 'for')
        currency_used_id = None
        token = utils.get_token_skipping_whitespace(lexer)
        if token.token_type == TokenType.keyword and token.token_value == 'OWN':
            currency_used_id = 'OWN'
        elif token.token_type == TokenType.keyword and token.token_value == 'ANY':
            currency_used_id = 'ANY'
        elif token.token_type == TokenType.keyword and token.token_value == 'currency':
            utils.expect_access_operator(lexer)
            currency_name = utils.expect_given_name(lexer)
            currency_used_id = symbol_table.get_currency(currency_name)
        else:
            raise ValueError("Unexpected token, Sir")
        return build_action(engine, is_buy, is_stock, symbol_id, buy_amount=buy_amount, curr_used=currency_used_id)