Exemplo n.º 1
0
    def __call__(self, commands, step=False):

        i = 0
        length = len(commands)

        while i < length:

            cmd = commands[i]

            # print(cmd.op, cmd.arg0, cmd.arg1, cmd.result)

            if cmd.op == 'step' and not step:
                i += 1
                continue
            if cmd.op == 'check' and step:
                i += 1
                continue

            operation = running_actions[cmd.op]

            # debug_cmd = commands[i]
            # print("command {}: {}, {}".format(i, commands[i].op, commands[i].result))

            arg1, arg2, arg3 = address_search(cmd.arg0, cmd.arg1, cmd.result)

            try:
                address = operation(arg1, arg2, arg3)
            except KeyError as ke:
                rtm_err = ParseErrData(
                    RTM_ERR, None,
                    "Undefined variable: '{}'".format(ke.args[0]))
                print(rtm_err)
                exit(1)
            except Exception as e:
                rtm_err = ParseErrData(RTM_ERR, None,
                                       "Run-time Error: {}".format(e))
                print(rtm_err)
                exit(1)

            if address == -1:
                step = False
            elif address == -2:
                step = True
            elif address is not None:
                i = address
                continue
            i += 1
Exemplo n.º 2
0
def reduce_15(*args):
    E = args[0]
    d = args[1]
    n = args[3]

    if int(n.value) <= 0:
        raise ParseErrData(
            SEM_ERR, int(n.line),
            "The size of array must be positive but got {}".format(n.value),
            Token(idt="F"))

    for i in range(int(n.value)):
        gen('new', E.value, None, "{}+{}".format(d.place, i))
        gen('=', '0', None, "{}+{}".format(d.place, i))

    return Token(idt="F")
Exemplo n.º 3
0
def reduce_13(*args):
    E = args[0]
    d = args[1]
    n0 = args[3]
    n1 = args[7]
    N = args[8]
    d.place = d.name
    for i in range(int(n0.value)):
        gen('new', E.value, None, "{}+{}".format(d.place, i))
        gen('=', '0', None, "{}+{}".format(d.place, i))
    gen('=', n1.value, None, "{}+{}".format(d.place, 0))
    for index, n in enumerate(N.value):
        gen('=', n, None, "{}+{}".format(d.place, index+1))

    if int(n.value) <= 0:
        raise ParseErrData(SEM_ERR, int(n.line), 
            "The size of array must be positive but got {}".format(n.value), 
            Token(idt="F"))

    return Token(idt="F")
Exemplo n.º 4
0
    def parse_sentence(self, sentence):

        err_list = []

        tokens = []
        line = 1

        length = len(sentence)
        # for i in range(len(sentence)):
        i = 0
        while i < length:

            char = sentence[i]

            if str.isalpha(char) or char is '_':
                word = ""

                def is_alpha_ul_num(char):

                    return str.isalpha(char) or char is '_' or str.isdigit(
                        char)

                while is_alpha_ul_num(char):

                    word += char
                    i += 1

                    if i >= length:
                        break

                    char = sentence[i]

                if word in STD.keys():
                    token = Token(idt=STD[word], line=line)
                else:
                    token = Token(idt=STD['identity'], name=word, line=line)

                tokens.append(token)

                i -= 1
            elif str.isdigit(char):
                number_str = ""
                flag = False

                def is_num_dot(char):

                    return str.isdigit(char) or char is '.'

                while is_num_dot(char):

                    number_str += char

                    if char is '.':
                        flag = True

                    i += 1

                    if i >= length:
                        break

                    char = sentence[i]

                # TODO 数字开头,后跟没空白符
                if is_alpha_ul_num(char):
                    self.err_mark = True
                    err_list.append(
                        ParseErrData(LEX_ERR, int(line),
                                     "Variable shouldn't begin with number"))
                    i += 1
                    continue

                token = Token(idt=STD["constnum"], value=number_str, line=line)
                tokens.append(token)

                i -= 1
            elif str.isspace(char):
                if char is '\n':
                    line += 0.5  # 这里注意!!! 我真是服了,windows下结尾两个\n
                pass
            elif char in r"+-(){}[];,":
                sig_token = Token(idt=STD[char], line=line)
                tokens.append(sig_token)
            elif char in r"*/=<>":
                sig_str = char + sentence[i + 1]

                token = None

                if sig_str in ("/*", ):
                    i += 1
                    find_right_comment = False
                    while i < length - 1:
                        two_char = sentence[i:i + 2]

                        if two_char == "\n\n":
                            line += 1

                        if two_char in ("*/", ):
                            find_right_comment = True
                            i += 2
                            break
                        i += 1
                    if find_right_comment:
                        continue
                    else:
                        self.err_mark = True
                        self.err_list.append(
                            ParseErrData(LEX_ERR, int(line),
                                         "Unpaired comment"))
                        i += 1
                        exit(1)
                elif sig_str in STD.keys():
                    token = Token(idt=STD[sig_str], line=line)
                    i += 1
                else:
                    token = Token(idt=STD[char], line=line)

                tokens.append(token)
            else:
                self.err_mark = True
                err_list.append(
                    ParseErrData(LEX_ERR, int(line), "Unexpected character"))
                i += 1
                continue

            i += 1

        for err in err_list:
            print(err)

        tokens.append(Token(idt=STD['#'], line=line))
        return tokens
Exemplo n.º 5
0
    def __call__(self, commands, step=False):

        i = 0
        length = len(commands)

        line = func_dict['main']
        for j in range(length):
            temp_cmd = commands[j]
            if temp_cmd.op == 'step' and temp_cmd.result == line:
                i = j
                break

        while i < length:

            cmd = commands[i]

            # print(cmd.op, cmd.arg0, cmd.arg1, cmd.result)

            if cmd.op == 'step' and not step:
                i += 1
                continue
            elif cmd.op == 'check' and step:
                i += 1
                continue
            elif cmd.op == 'call':
                line = func_dict[cmd.result]

                register_dict['addr'] = i + 1
                for j in range(length):
                    temp_cmd = commands[j]
                    if temp_cmd.op == 'step' and temp_cmd.result == line:
                        i = j
                        break

                while commands[i].op != 'new':
                    i += 1

                # 虚参赋值
                init_param_cmd = commands[i + 1]
                init_param_cmd.op = '=r'
                init_param_cmd.arg0 = 'rdx'
                init_param_cmd.result = commands[i].result

                continue
            elif cmd.op == 'ret':
                register_dict['rax'] = eval(get_val_from_table(cmd.arg0))
                i = register_dict['addr']
                continue

            operation = running_actions[cmd.op]

            # debug_cmd = commands[i]
            # print("command {}: {}, {}".format(i, commands[i].op, commands[i].result))

            arg1, arg2, arg3 = address_search(cmd.arg0, cmd.arg1, cmd.result)

            try:
                address = operation(arg1, arg2, arg3)
            except KeyError as ke:
                rtm_err = ParseErrData(
                    RTM_ERR, None,
                    "Undefined variable: '{}'".format(ke.args[0]))
                print(rtm_err)
                exit(1)
            except Exception as e:
                rtm_err = ParseErrData(RTM_ERR, None,
                                       "Run-time Error: {}".format(e))
                print(rtm_err)
                raise e

            if address == -1:
                step = False
            elif address == -2:
                step = True
            elif address is not None:
                i = address
                continue
            i += 1

        win32gui.SendMessage(hwnd, data_type, None, -1)
Exemplo n.º 6
0
    def parse_tokens(self,
                     tokens,
                     show_syntax=False,
                     file_name=None,
                     draw_graph=False,
                     checkpoints=[]):

        err_list = []
        sem_err_mark = False

        succeeded = False

        dot.clear()

        table = ActionTable(action_table_data)

        analysis_stack = []
        # TODO 赋予结束标志token更有意义的值
        analysis_stack.append((0, Token(idt="#")))

        i = 0
        length = len(tokens)

        if file_name:
            fout = open(file_name + ".syn", 'w')
            outstream = fout
        else:
            outstream = sys.stdout

        line = 1
        temp_str = ""

        while i < length:
            token = tokens[i]

            current_line = token.line

            state = analysis_stack[-1][0]

            # 加入断点
            if int(token.line) in checkpoints:
                gen('check', None, None, int(current_line))
                checkpoints.remove(token.line)

            if line != token.line:
                gen('step', None, None, int(current_line))
                line = token.line
            # end

            try:
                action = table.action(state, token)
            except:
                # TODO 这种处理不妥

                mark = ""
                mark_type = ""
                if token.idt == 'constnum':
                    mark_type = 'const num'
                    mark = token.value
                elif token.idt == 'identity':
                    mark_type = 'variable'
                    mark = token.name
                else:
                    mark_type = 'key word'
                    mark = token.idt

                parse_err = ParseErrData(
                    SYN_ERR,
                    int(token.line),
                    message="Action failed. Unexpected {}: '{}'.".format(
                        mark_type, mark))
                print(parse_err)
                exit(1)

            if show_syntax:

                def show_stack():
                    print("analysis stack:", end="\t", file=outstream)
                    print(" ".join([
                        "{}:{}".format(elem[0], elem[1].idt)
                        for elem in analysis_stack
                    ]),
                          file=outstream)

                show_stack()
                print("token incoming: {}".format(token.idt), file=outstream)
                print("action: {}".format(action[0]), file=outstream)
                print(file=outstream)
                # input() 单步好像没啥意义

            if 's' is action[0]:
                analysis_stack.append((action[1], action[2]))
                i += 1
            elif 'r' is action[0]:
                num2reduce = action[1]

                reduce_action_args = []

                new_nodes = []

                for _ in range(num2reduce):
                    pop_token = analysis_stack.pop()[1]
                    # reduce_action_args[replace_symbol_reverse(pop_token.idt)] = pop_token
                    reduce_action_args.append(pop_token)

                    new_nodes.append(pop_token)

                reduce_action_args.reverse()

                try:
                    token = action[2](*reduce_action_args)
                except ParseErrData as ped:
                    ped.line = int(current_line)
                    err_list.append(ped)
                    sem_err_mark = True
                    token = ped.token

                # TODO 一种很简单的处理
                try:
                    state = table.goto(analysis_stack[-1][0], token)
                except Exception:
                    parse_err = ParseErrData(
                        SYN_ERR,
                        int(current_line),
                        message=
                        "Reduction failed. Thers's something wrong with the forms usually."
                    )
                    print(parse_err)
                    exit(1)

                analysis_stack.append((state, token))

                if draw_graph:
                    dot.node(str(token.count), token.idt)
                    new_nodes.reverse()
                    for child in new_nodes:
                        dot.node(str(child.count), child.idt)
                        dot.edge(str(token.count), str(child.count))

            elif '#' in action[0]:
                if draw_graph:
                    print(file_name)
                    dot.render(file_name)

                succeeded = True
                break
            else:
                succeeded = False
                break

        if sem_err_mark:
            for err in err_list:
                print(err)
            exit(1)

        if outstream is not sys.stdout:
            outstream.close()
            outstream = sys.stdout

        return succeeded