コード例 #1
0
 def token_or(self, result):
     result = self.token_and(result)
     hold = TTree()
     while not self.token == 'end' and self.token == 'or':
         self.get_token()
         hold = self.token_and(hold)
         result = TTree(result, 'or', hold)
     return result
コード例 #2
0
 def token_pow(self, result):
     result = self.token_un(result)
     hold = TTree()
     while self.token != 'end' and (self.token == '^'):
         self.get_token()
         hold = self.token_brackets(hold)
         result = TTree(result, '^', hold)
     return result
コード例 #3
0
 def token_mul(self, result):
     result = self.token_pow(result)
     hold = TTree()
     while self.token != 'end' and (self.token == '*' or self.token == '/'):
         sign = self.token
         self.get_token()
         hold = self.token_pow(hold)
         result = TTree(result, sign, hold)
     return result
コード例 #4
0
 def token_add(self, result):
     result = self.token_mul(result)
     hold = TTree()
     while not self.token == 'end' and (self.token == '+' or self.token == '-' or self.token == '>' or
                                        self.token == '<' or self.token == '>=' or self.token == '<=' or
                                        self.token == '<>' or self.token == '='):
         sign = self.token
         self.get_token()
         hold = self.token_mul(hold)
         result = TTree(result, sign, hold)
     return result
コード例 #5
0
 def token_prim(self, result):
     if self.token_type == 'digit':
         val = float(self.token)
         result = TTree(val)
     elif self.token_type == 'function':
         result = self.token_func(result)
     elif self.token_type == 'variable':
         result = TTree(self.variables[self.token])
     else:
         self.say_error('syntax_err')
     self.get_token()
     return result
コード例 #6
0
 def token_un(self, result):
     sign = self.token
     if (self.token_type == 'delimiter') and (sign == '+' or sign == '-'):
         self.get_token()
     result = self.token_brackets(result)
     if sign == '+' or sign == '-':
         result = TTree(sign, result)
     return result
コード例 #7
0
 def token_not(self, result):
     sign = self.token
     if (self.token_type == 'delimiter') and sign == 'not':
         self.get_token()
     result = self.token_add(result)
     if sign == 'not':
         result = TTree(sign, result)
     return result
コード例 #8
0
 def token_func(self, result):
     fun_token = self.token
     hold = TTree()
     self.get_token()
     if self.token == 'end' or self.token != '(':
         self.say_error('syntax_err')
     self.get_token()
     result = self.token_add(result)
     if fun_token == 'atan2':
         if self.token != ',':
             self.say_error('syntax_err')
         self.get_token()
         hold = self.token_add(hold)
         result = TTree(result, 'atan2', hold)
     else:
         result = TTree(fun_token, result)
     if self.token != ')':
         self.say_error('syntax_err')
     return result
コード例 #9
0
 def __init__(self):
     self.error = self.code = self.token = self.token_type = ''
     self.result = TTree()
     self.variables = {}
コード例 #10
0
class TParser:
    def __init__(self):
        self.error = self.code = self.token = self.token_type = ''
        self.result = TTree()
        self.variables = {}

    def add_variable(self, var, val=0.0):
        if var in self.variables:
            self.say_error('redefinition_err')
        self.variables.setdefault(var, val)

    def set_variable(self, var, val):
        if var not in self.variables:
            self.say_error('undef_err')
        self.variables[var] = val

    def set_code(self, c):
        # Удаление пробелов ...
        # self.code = re.sub(r'\s', '', c)
        self.code = c
        self.compile()
#        try:
#            self.compile()
#        except TFEMException as e:
#            e.print_error()

    def get_exp(self, result):
        self.get_token()
        if len(self.token) == 0:
            self.say_error('syntax_err')
        result = self.token_or(result)
#        result = self.token_add(result)
        return result

    def token_or(self, result):
        result = self.token_and(result)
        hold = TTree()
        while not self.token == 'end' and self.token == 'or':
            self.get_token()
            hold = self.token_and(hold)
            result = TTree(result, 'or', hold)
        return result

    def token_and(self, result):
        result = self.token_not(result)
        hold = TTree()
        while not self.token == 'end' and self.token == 'and':
            self.get_token()
            hold = self.token_not(hold)
            result = TTree(result, 'and', hold)
        return result

    def token_not(self, result):
        sign = self.token
        if (self.token_type == 'delimiter') and sign == 'not':
            self.get_token()
        result = self.token_add(result)
        if sign == 'not':
            result = TTree(sign, result)
        return result

    def token_add(self, result):
        result = self.token_mul(result)
        hold = TTree()
        while not self.token == 'end' and (self.token == '+' or self.token == '-' or self.token == '>' or
                                           self.token == '<' or self.token == '>=' or self.token == '<=' or
                                           self.token == '<>' or self.token == '='):
            sign = self.token
            self.get_token()
            hold = self.token_mul(hold)
            result = TTree(result, sign, hold)
        return result

    def token_mul(self, result):
        result = self.token_pow(result)
        hold = TTree()
        while self.token != 'end' and (self.token == '*' or self.token == '/'):
            sign = self.token
            self.get_token()
            hold = self.token_pow(hold)
            result = TTree(result, sign, hold)
        return result

    def token_pow(self, result):
        result = self.token_un(result)
        hold = TTree()
        while self.token != 'end' and (self.token == '^'):
            self.get_token()
            hold = self.token_brackets(hold)
            result = TTree(result, '^', hold)
        return result

    def token_un(self, result):
        sign = self.token
        if (self.token_type == 'delimiter') and (sign == '+' or sign == '-'):
            self.get_token()
        result = self.token_brackets(result)
        if sign == '+' or sign == '-':
            result = TTree(sign, result)
        return result

    def token_brackets(self, result):
        if self.token != 'end' and self.token == '(' and self.token_type == 'delimiter':
            self.get_token()
            result = self.token_or(result)
            if self.token != ')':
                self.say_error('brackets_err')
            self.get_token()
        else:
            result = self.token_prim(result)
        return result

    def token_prim(self, result):
        if self.token_type == 'digit':
            val = float(self.token)
            result = TTree(val)
        elif self.token_type == 'function':
            result = self.token_func(result)
        elif self.token_type == 'variable':
            result = TTree(self.variables[self.token])
        else:
            self.say_error('syntax_err')
        self.get_token()
        return result

    def token_func(self, result):
        fun_token = self.token
        hold = TTree()
        self.get_token()
        if self.token == 'end' or self.token != '(':
            self.say_error('syntax_err')
        self.get_token()
        result = self.token_add(result)
        if fun_token == 'atan2':
            if self.token != ',':
                self.say_error('syntax_err')
            self.get_token()
            hold = self.token_add(hold)
            result = TTree(result, 'atan2', hold)
        else:
            result = TTree(fun_token, result)
        if self.token != ')':
            self.say_error('syntax_err')
        return result

    def get_token(self):
        self.token_type = self.token = ''
        # Обработка пустой строки
        if len(self.code) == 0:
            self.token = 'end'
            self.token_type = 'delimiter'
            return
        # Удаление ведущих пробелов ...
        i = 0
        while i < len(self.code) and (self.code[i] == ' ' or self.code[i] == '\t'):
            i += 1
        self.code = self.code[i:]
        if len(self.code) == 0:
            self.token = 'end'
            self.token_type = 'delimiter'
            return
        # Обработка разделителей
        if '+-*/()^=><,'.find(self.code[0]) != -1:
            self.token = self.code[0]
            self.code = self.code[1:len(self.code)]
            # Проверка на наличие двойного разделителя
            if len(self.code) and '+-*/()^=><,'.find(self.code[0]) != -1:
                if self.token + self.code[0] in operation:
                    self.token += self.code[0]
                    self.code = self.code[1:len(self.code)]
            self.token_type = 'delimiter'
            return
        # Обработка чисел
        if self.code[0].isdigit():
            i = 0
            while i < len(self.code) and self.code[i].isdigit():
                i += 1
            self.token = self.code[0:i] if (i < len(self.code)) else self.code[0:]
            self.code = self.code[i:]
            if len(self.code) > 0 and self.code[0] == '.':
                self.token += '.'
                self.code = self.code[1:]
                i = 0
                while i < len(self.code) and self.code[i].isdigit():
                    i += 1
                self.token += self.code[0:i] if (i < len(self.code)) else self.code[0:]
                self.code = self.code[i:]
            if len(self.code) > 0 and (self.code[0] == 'E' or self.code[0] == 'e'):
                self.code = self.code[1:]
                self.token += 'E'
                if self.code[0] != '+' and self.code[0] != '-':
                    self.say_error('syntax_err')
                self.token += self.code[0]
                self.code = self.code[1:]
                i = 0
                while i < len(self.code) and self.code[i].isdigit():
                    i += 1
                self.token += self.code[0:i]
                self.code = self.code[i:]
            self.token_type = 'digit'
            return
        # Обработка функкций и переменных
        if self.code[0].isalpha():
            self.token = self.code[0]
            self.code = self.code[1:]
            i = 0
            while i < len(self.code) and (self.code[i].isalpha() or self.code[i] == '_' or self.code[i].isdigit()):
                i += 1
            self.token += self.code[0:i] if (i < len(self.code)) else self.code[0:]
            self.code = self.code[i:]
            if self.token in function:
                self.token_type = 'function'
            elif self.token in boolean:
                self.token_type = 'delimiter'
            elif self.token in self.variables:
                self.token_type = 'variable'
            else:
                self.say_error('undef_err')
            return

    def run(self):
        return self.result.value()

    def say_error(self, err):
        self.error = err
        raise TFEMException(self.error)

    def compile(self):
        self.result = self.get_exp(self.result)
        if self.token_type == 'delimiter' and self.token != 'end':
            if self.token == '(' or self.token == ')':
                self.say_error('brackets_err')
            else:
                self.say_error('syntax_err')