Пример #1
0
 def test_value(self):
     assert evaluator.Evaluator(['x']).eval() == 'x'
Пример #2
0
 def test_op_or(self):
     or_ = evaluator.OP_OR
     assert not evaluator.Evaluator([False, or_, False]).eval()
     assert evaluator.Evaluator([False, or_, True]).eval()
     assert evaluator.Evaluator([True, or_, False]).eval()
     assert evaluator.Evaluator([True, or_, True]).eval()
Пример #3
0
 def test_op_and(self):
     and_ = evaluator.OP_AND
     assert not evaluator.Evaluator([False, and_, False]).eval()
     assert not evaluator.Evaluator([False, and_, True]).eval()
     assert not evaluator.Evaluator([True, and_, False]).eval()
     assert evaluator.Evaluator([True, and_, True]).eval()
Пример #4
0
 def test_op_neq(self):
     neq_ = evaluator.OP_NE
     assert evaluator.Evaluator(['a', neq_, 'b']).eval()
     assert not evaluator.Evaluator(['a', neq_, 'a']).eval()
Пример #5
0
 def test_op_eq(self):
     eq_ = evaluator.OP_EQ
     assert evaluator.Evaluator(['a', eq_, 'a']).eval()
     assert not evaluator.Evaluator(['a', eq_, 'b']).eval()
Пример #6
0
 def test_op_plus(self):
     plus_ = evaluator.OP_PLUS
     assert evaluator.Evaluator(['a', plus_, 'b']).eval() == 'ab'
Пример #7
0
 def test_op_not(self):
     not_ = evaluator.OP_NOT
     assert evaluator.Evaluator([not_, '']).eval()
     assert not evaluator.Evaluator([not_, [not_, '']]).eval()
Пример #8
0
def parse_str(spec: str) -> Optional[Dict[str, Union[str, int, TreeType]]]:
    """ Given a string with an optimizer template definition,
    parses it and return a python object as a result.
    If any error is detected, fname will be used as filename.
    """
    # States
    ST_INITIAL = 0
    ST_REGION = 1

    result: Dict[str, Any] = defaultdict(list)
    state = ST_INITIAL
    line_num = 0
    region_name = None
    is_ok = True

    def add_entry(key: str, val: Union[str, int, TreeType]) -> bool:
        key = key.upper()
        if key in result:
            src.api.errmsg.warning(line_num,
                                   "duplicated definition {0}".format(key))
            return False

        if key not in REGIONS and key not in SCALARS:
            src.api.errmsg.warning(
                line_num, "unknown definition parameter '{0}'".format(key))
            return False

        if key in NUMERIC:
            assert isinstance(val, str)
            if not RE_INT.match(val):
                src.api.errmsg.warning(
                    line_num, "field '{0} must be integer".format(key))
                return False
            val = int(val)

        result[key] = val
        return True

    def check_entry(key: str) -> bool:
        if key not in result:
            src.api.errmsg.warning(line_num,
                                   "undefined section {0}".format(key))
            return False

        return True

    for line in spec.split('\n'):
        line = line.strip()
        line_num += 1

        if not line:
            continue  # Ignore blank lines

        if state == ST_INITIAL:
            if line.startswith(COMMENT):
                continue

            x = RE_REGION.match(line)
            if x:
                region_name = x.groups()[0]
                state = ST_REGION
                add_entry(region_name, [])
                continue

            x = RE_DEF.match(line)
            if x:
                if not add_entry(*x.groups()):
                    is_ok = False
                    break
                continue
        elif state == ST_REGION:
            if line.endswith('}}'):
                line = line[:-2].strip()
                state = ST_INITIAL

            if line:
                result[region_name].append(SourceLine(line_num,
                                                      line))  # type: ignore

            if state == ST_INITIAL:
                region_name = None
            continue

        src.api.errmsg.warning(line_num, "syntax error. Cannot parse file")
        is_ok = False
        break

    defines = []
    defined_vars = set()
    for source_line in result[REG_DEFINE]:
        var_, expr = parse_define_line(source_line)
        if var_ is None or expr is None:
            is_ok = False
            break
        if var_ in defined_vars:
            src.api.errmsg.warning(source_line.lineno,
                                   "duplicated variable '{0}'".format(var_))
            is_ok = False
            break
        defines.append([
            var_,
            DefineLine(expr=evaluator.Evaluator(expr),
                       lineno=source_line.lineno)
        ])
        defined_vars.add(var_)
    result[REG_DEFINE] = defines

    if is_ok:
        for reg in [x for x in REGIONS if x != REG_DEFINE]:
            result[reg] = [x.line for x in result[reg]]

    if is_ok:
        reg_if = parse_ifline(' '.join(x for x in result[REG_IF]), line_num)
        if reg_if is None:
            is_ok = False
        else:
            result[REG_IF] = reg_if

    is_ok = is_ok and all(check_entry(x) for x in REQUIRED)

    if is_ok:
        if not result[REG_REPLACE]:  # Empty REPLACE region??
            src.api.errmsg.warning(line_num,
                                   "empty region {0}".format(REG_REPLACE))
            is_ok = False

    if not is_ok:
        src.api.errmsg.warning(
            line_num, "this optimizer template will be ignored due to errors")
        return None

    return result