Esempio n. 1
0
    def _semantic_analysis(cls, prefixes, query):
        # no query
        if len(query) == 0:
            return None

        # analyse prefixes
        prefix_from = None
        save_files = 0
        delete_files = 0
        print_files = 0
        prefixes_iter = iter(prefixes)
        for token in prefixes_iter:
            if type(token[0]) is not str:
                raise error.SyntaxError(token)
            token = token[0]
            # save files
            if token in Exp.FROM:
                prefix_from = next(prefixes_iter)
                prefix_from = Token.from_var(''.join(prefix_from))
            elif token in Exp.SAVE:
                save_files += 1
            # delete files
            elif token in Exp.DELETE:
                delete_files += 1
            # print variables
            elif token in Exp.PRINT:
                print_files += 1
            # check overlap
            if save_files + delete_files + print_files >= 2:
                raise error.SyntaxError(token)

        query = query.to_data()

        # (save, delete, print) files
        for op, test, func in zip(
            [Exp.SAVE[0], Exp.DELETE[0], Exp.PRINT[0]],
            [save_files, delete_files, print_files],
            [Token.from_save, Token.from_delete, Token.from_print]):
            if not test:
                continue
            if query.data_type == Token.TYPE_VARIABLE:
                return func(prefix_from, query)
            if query.data_type == Token.TYPE_TUPLE:
                return func(prefix_from, *query.args)
            else:
                raise error.SyntaxError(op)
        # just data
        return query
Esempio n. 2
0
 def check_sizeof(self):
     if self.head in [
             Exp.NUMBER,
             Exp.VARIABLE,
     ]:
         pass
     elif self.head in Exp.Tokens_Shell:
         pass
     elif self.head in Exp.IDX:
         if 1 <= len(self) <= 3:
             pass
         else:
             raise error.SyntaxError(self.head)
     elif len(self) != 2:
         raise error.SyntaxError(self.head)
     for token in self:
         if type(token) is TokenTree:
             token.check_sizeof()
Esempio n. 3
0
    def append(self, target):
        super().append(target)
        if type(target) is TokenTree:
            self.pointer += 1

        # check subject is numeric
        if self.head == Exp.VARIABLE and len(self) == 1:
            if type(target) is str:
                if len(self._is_number(self[0])[1]) > 0:
                    raise error.SyntaxError(self[0])
Esempio n. 4
0
 def close(self, token_end: str):
     # make shell shape
     shell = self.head + token_end
     if shell not in Exp.Tokens_Shell:
         raise error.SyntaxError(token_end)
     if shell in Exp.SHELL_RR and not self.has_subject and len(self) == 1:
         item = self[0]
         # remove shell () if shell is tuple, and the only item is an operator or shells
         if item.head in Exp.Tokens_Operator + Exp.SHELL_RR + [
                 Exp.VARIABLE
         ]:
             last_object = self.pop()
             self.__iadd__(last_object)
             self.head = last_object.head
             self.has_subject = item.has_subject
             self.breakpoint = item.breakpoint
             return
     self.head = shell
     return
Esempio n. 5
0
    def _parser(cls, tokens):
        prefixes = TokenTree(None, Exp.SHELL_RR[0])

        query = TokenTree(None, Exp.VARIABLE)
        object_attr = query
        for w in tokens:
            # comments
            if w == Exp.COMMENT:
                break

            # indents
            if w in Exp.INDENT:
                if object_attr.head == Exp.VARIABLE:
                    # start with character
                    if len(object_attr) > 0:
                        object_attr.append(w)
                elif len(object_attr) > 0:
                    # start with character
                    if type(object_attr[-1]) is str:
                        object_attr.append(w)
                continue

            # exp
            if w in Exp.ADD + Exp.SUB:
                if type(object_attr[-1]) is str:
                    if object_attr[-1].endswith(
                            'e') and object_attr[-1][0].isdigit():
                        object_attr.append(w)
                        continue

            # subjects
            # check operator overlap
            if len(object_attr) == 0:
                if w in Exp.Signs_All and w not in Exp.IDX:
                    # not shell
                    if object_attr.head in Exp.Tokens_Open and w in Exp.Tokens_Open + Exp.Tokens_Close:
                        pass
                    # not variable or shell
                    elif object_attr.head in Exp.VARIABLE and w in Exp.Tokens_Open:
                        pass
                    # not unary operator (-)
                    elif w in Exp.SUB:
                        pass
                    else:
                        raise error.SyntaxError(w)

            # attribute
            if w == Exp.COMMA:
                # move to shell
                while object_attr.head not in Exp.Tokens_Open:
                    object_attr.tokenize()
                    last_object = object_attr.parent
                    # indices
                    if object_attr.head in Exp.IDX:
                        if last_object is None:
                            raise error.SyntaxError(object_attr.head)
                        object_attr = last_object
                        break
                    # new tuple
                    if last_object is None:
                        # variable -> tuple
                        if object_attr.head == Exp.VARIABLE:
                            object_attr.head = Exp.SHELL_RR[0]
                            break
                        # =
                        if object_attr.head in Exp.IS:
                            if object_attr[-1].head not in Exp.SHELL_RR:
                                object_attr = object_attr.insert_upper(
                                    Exp.SHELL_RR[0])
                            else:
                                object_attr = object_attr[-1]
                            break
                        # is tuple
                        object_attr.breakpoint = object_attr.pointer
                        break
                    # else : goto upper
                    object_attr = last_object
                object_attr.tokenize()
                object_attr.breakpoint = object_attr.pointer

            # prefixes
            elif w in Exp.Tokens_Prefix:
                # not from- prefix
                if w not in Exp.FROM:
                    if object_attr.parent is None and object_attr.head == Exp.VARIABLE:
                        if len(query) > 0:
                            prefixes.append(query)
                        prefixes.append(w)
                        prefixes.tokenize()
                        query = TokenTree(None, Exp.SHELL_RR[0])
                        object_attr = query
                        continue
                # from- prefix
                elif object_attr.parent is None and len(object_attr) == 0:
                    prefixes.append(w)
                    prefixes.tokenize()
                    continue
                raise error.SyntaxError(w)

            # open shells
            elif w in Exp.Tokens_Open:
                object_attr.tokenize()
                # in ()
                if object_attr.head in Exp.RBO:
                    # if empty shell : tuple
                    if len(object_attr) == 0:
                        # only ()
                        if w not in Exp.RBO:
                            raise error.SyntaxError(w)
                        object_attr = object_attr.insert_inner(w)
                        object_attr.has_subject = False
                        continue
                    # if comma ahead
                    if len(object_attr) == object_attr.breakpoint:
                        # only ()
                        if w not in Exp.RBO:
                            raise error.SyntaxError(w)
                        object_attr = object_attr.insert_inner(w)
                        object_attr.has_subject = False
                        continue
                    # else : decorate subject
                    object_attr = object_attr.insert_upper(w)
                    object_attr.has_subject = True
                    object_attr.breakpoint = object_attr.pointer
                    continue
                # =
                if object_attr.head in Exp.IS + Exp.DIS:
                    # tuple
                    if len(object_attr) == 1:
                        # only ()
                        if w not in Exp.RBO:
                            raise error.SyntaxError(w)
                        object_attr = object_attr.insert_inner(w)
                        object_attr.has_subject = False
                        continue
                    # decorate object
                    if len(object_attr) == 2:
                        object_attr = object_attr.insert_upper(w)
                        object_attr.has_subject = True
                        object_attr.breakpoint = object_attr.pointer
                        continue
                    raise error.SyntaxError(w)
                # just operators
                if object_attr.head in Exp.Tokens_Operator:
                    # parent is operator
                    if len(object_attr
                           ) == 2 and object_attr.head in Exp.Tokens_Operator:
                        object_attr = object_attr.insert_upper(w)
                        object_attr.has_subject = True
                        continue
                    # must be tuple
                    if len(object_attr) != 1:
                        raise error.SyntaxError(w)
                    # only ()
                    if w not in Exp.RBO:
                        raise error.SyntaxError(w)
                    object_attr = object_attr.insert_inner(w)
                    object_attr.has_subject = False
                    continue
                # exception : null query
                if len(query) == 0:
                    # only ()
                    if w not in Exp.RBO:
                        raise error.SyntaxError(w)
                    query = object_attr = object_attr.insert_inner(w)
                    object_attr.has_subject = False
                    continue
                raise error.SyntaxError(w)

            # close shells
            elif w in Exp.Tokens_Close:
                object_attr.tokenize()
                # move to shell pair
                find_shell = False
                while not find_shell:
                    for shell_opens, shell_closes in Exp.Tokens_Shell_Pair.items(
                    ):
                        if object_attr.head in shell_opens:
                            if w in shell_closes:
                                find_shell = True
                                break
                    # opening not found
                    if not find_shell:
                        object_attr = object_attr.parent
                        if object_attr is None:
                            raise error.SyntaxError(w)
                        object_attr.tokenize()
                # close shell
                object_attr.close(w)
                object_attr = object_attr.parent
                if object_attr is None:
                    raise error.SyntaxError(w)

            # indices
            elif w in Exp.IDX:
                # move to indices shell '('
                while object_attr.head not in Exp.RBO:
                    # not other shells
                    if object_attr.head in Exp.Tokens_Open:
                        raise error.SyntaxError(w)
                    object_attr.tokenize()
                    object_attr = object_attr.parent
                    if object_attr is None:
                        raise error.SyntaxError(w)
                object_attr.tokenize()
                # no begin values
                if len(object_attr) == object_attr.breakpoint:
                    object_attr = object_attr.insert_inner(w)
                    last_object = TokenTree(object_attr, Exp.NUMBER)
                    last_object += [False, Exp.BOOL]
                    object_attr.append(last_object)
                    continue
                # has start values
                if len(object_attr) == object_attr.breakpoint + 1:
                    # has stop values
                    last_object = object_attr[-1]
                    if last_object.head == w:
                        # not stop value defined
                        if len(last_object) == 1:
                            object_attr = object_attr[-1]
                            last_object = TokenTree(object_attr, Exp.NUMBER)
                            last_object += [False, Exp.BOOL]
                            object_attr.append(last_object)
                            continue
                        if len(last_object) == 2:
                            object_attr = last_object
                            continue
                        raise error.SyntaxError(w)
                    # no stop values
                    object_attr = object_attr.insert_upper(w)
                    continue
                raise error.SyntaxError(w)

            # operators
            elif w in Exp.Tokens_Operator:
                # 'n'umber, 'v'ariable, 't'uple
                if w in Exp.ABSTRACT_TYPES:
                    object_attr.append(w)
                    continue
                object_attr.tokenize()
                # unary operators (-)
                if w in Exp.SUB:
                    # =
                    if len(object_attr) == 1:
                        if object_attr.head in Exp.IS:
                            object_attr.append(w)
                            continue
                    # if shell
                    if len(object_attr) == 0:
                        if object_attr.head in Exp.Tokens_Open:
                            object_attr.append(w)
                            continue
                # variable overlap
                if object_attr.head == Exp.VARIABLE and len(object_attr) == 1:
                    new_object = object_attr[0]
                    new_object.parent = object_attr.parent
                    if new_object.parent is None:
                        query = new_object
                    object_attr = new_object
                # higher order
                if Exp.Tokens_Order[object_attr.head] < Exp.Tokens_Order[w]:
                    object_attr = object_attr.insert_upper(w)
                    continue
                # lower order
                # if in shell
                if object_attr.head in Exp.Tokens_Open:
                    # put operators into shell
                    object_attr = object_attr.insert_upper(w)
                    continue
                last_object = object_attr.parent
                if last_object is None:
                    query = object_attr = object_attr.insert_root(w)
                    continue
                object_attr = last_object.insert_upper(w)
                if object_attr.parent is None:
                    query = object_attr
            # not operators
            elif w[0] in Exp.Signs_DoubleSingle:
                raise error.SyntaxError(w)
            # append text
            elif object_attr.head == Exp.VARIABLE and len(object_attr) == 1:
                object_attr[0] += w
            # add content
            else:
                object_attr.append(w)

        prefixes.tokenize()
        object_attr.tokenize()

        # variable overlap
        if object_attr.head == Exp.VARIABLE and len(object_attr) == 1:
            last_object = object_attr.pop(0)
            object_attr += last_object
            object_attr.head = last_object.head

        # check size of operators
        prefixes.check_sizeof()
        query.check_sizeof()

        # check prefixes
        prefix_from_pair = True
        prefixes_new = TokenTree(None, Exp.SHELL_RR[0])
        for token in prefixes:
            if token.head != Exp.VARIABLE:
                raise error.SyntaxError(token[0])
            # has 'from'
            if token[0] in Exp.FROM:
                prefix_from_pair = False
                if len(prefixes_new) != 0:
                    raise error.SyntaxError(token[0])
            elif token[0] in Exp.Tokens_Prefix:
                prefix_from_pair = True
                if len(prefixes_new) != 0:
                    if prefixes_new[-1][0] in Exp.Tokens_Prefix:
                        raise error.SyntaxError(token[0])
            if len(prefixes_new) > 3:
                raise error.SyntaxError(token[0])
            prefixes_new.append(token)
        if not prefix_from_pair:
            raise error.SyntaxError(Exp.FROM[0])
        prefixes = prefixes_new

        return prefixes, query