Example #1
0
def interpret_fourcode_read(code):
    """(READ, None, None, VAR)"""
    id, isarr = get_id(code[3])
    symbol = get_symbol_in_table(id)
    symbol.declare_line = code.line
    i = input()
    if i.startswith('"') and i.startswith('"'):  # 输入为字符串
        if symbol.type != 'string':
            raise RunningError(
                'Line %d: should input a number to a number variable %s' %
                (code.line, symbol.name))
        if isarr:
            index = is_index_valid(symbol, isarr)
            symbol.arr[index] = i
        else:
            symbol.value = i
    elif is_num(i):
        if symbol.type == 'string':
            raise RunningError(
                'Line %d: should input a string to a string variable %s' %
                (code.line, symbol.name))
        value = eval(i) * 1.0 if symbol.type == 'float' else int(eval(i))
        if isarr:
            index = is_index_valid(symbol, isarr)
            symbol.arr[index] = value
        else:
            symbol.value = value
    else:
        raise RunningError('Line %d: input is invalid' % code.line)
Example #2
0
def interpret_fourcode(code):
    """四元式核心主函数,遇到错误则记录并跳到下一条四元式"""
    global cur_code, level_count
    try:
        type = code[0]
        if type == 'JMP':
            if code[1] is None or not get_symbol_in_table(code[1]).value:
                cur_code = code[3] - 1
                return
        elif type == 'IN':
            level_count += 1
        elif type == 'OUT':
            level_count -= 1
        elif type == 'READ':
            interpret_fourcode_read(code)
        elif type == 'WRITE':
            interpret_fourcode_write(code)
        elif type == 'ASSIGN':
            interpret_fourcode_assign(code)
        elif type in ['int', 'float', 'string']:
            interpret_fourcode_declare(code)
        else:
            interpret_fourcode_op(code)
    except Exception as e:
        skip_exception(RunningError, e)
    finally:
        cur_code += 1
Example #3
0
def is_index_valid(symbol, index):
    """检查四元式中数组的下标是否合法,合法则返回实际的下标值"""
    if match(r'\d+', index):
        value = eval(index)
        if value < len(symbol.arr):  #判断数组是否越界
            return value
        else:
            raise RunningError(
                'Line %d: index %d out of bound in variable %s' %
                (symbol.declare_line, value, symbol.name))
    else:
        index_symbol = get_symbol_in_table(index)
        if index_symbol.type in ['NUM', 'int', 'float', 'temp']:
            if int(index_symbol.value) != index_symbol.value:  #判断下标是否为整数
                raise RunningError(
                    'Line %d: index %s of variable %s is float point number' %
                    (symbol.declare_line, index_symbol.value, symbol.name))
            if -1 < index_symbol.value < len(symbol.arr):  #判断数组是否越界
                return int(index_symbol.value)
            else:
                raise RunningError(
                    'Line %d: index %s out of bound in variable %s' %
                    (symbol.declare_line, str(
                        index_symbol.value), symbol.name))
        else:
            raise RunningError(
                'Line %d: variable %s\'s index should be a non-negetive integer'
                % (symbol.declare_line, symbol.name))
Example #4
0
def get_var_value(varname):
    """传入一个变量名a或带下标的变量a[i],返回该变量对应的符号和其值"""
    id, isarr = get_id(varname)
    symbol = get_symbol_in_table(id)
    value = symbol.arr[is_index_valid(symbol,
                                      isarr)] if isarr else symbol.value
    return symbol, value
Example #5
0
def interpret_fourcode_op(code):
    """(OP, left, right|None, result)"""
    op = code[0]
    v1, v2 = get_value(code[1]), get_value(code[2])
    if type(v1) == str or type(v2) == str:
        raise RunningError('Line %d: string cannot in expression!' % code.line)
    value = None
    if op == '!':
        value = not v1  #逻辑取反
    elif op == '-':
        if v2 is None: value = -v1  #取负数
        else: value = eval(str(v1) + '-' + str(v2))
    elif op == '/':
        if v2 == 0:
            raise RunningError('Line %d: divisor cannot be zero!' % code.line)
        value = v1 / v2
    elif op == '&&':
        if not v1: value = False  # 考虑短路运算
        else: value = v2
    elif op == '||':
        if v1: value = True
        else: value = v2
    elif op == '<>':
        value = v1 != v2
    else:
        value = eval(str(v1) + op + str(v2))
    symbol = get_symbol_in_table(code[3])
    symbol.value = value
Example #6
0
def interpret_fourcode_assign(code):
    """(ASSIGN, VAR, 0/1, STR/VAR/NUM)"""
    to_id, to_isarr = get_id(code[1])
    to_symbol = get_symbol_in_table(to_id)
    if code[2]:  #赋值内容为变量的值
        from_symbol, value = get_var_value(code[3])
    else:  #直接将四元式第四项的内容赋给变量
        value = code[3]
    if is_num(str(value)) and to_symbol.type == 'string':
        raise RunningError('Line %d: not match type in assignment statement' %
                           code.line)
    if to_symbol.type == 'int': value = int(value)
    if to_isarr:
        to_symbol.declare_line = code.line
        to_index = is_index_valid(to_symbol, to_isarr)
        to_symbol.arr[to_index] = value
    else:
        to_symbol.value = value