Exemple #1
0
    def parse2(self):
        self.op_stack = Stack()
        self.val_stack = Stack()
        self.node_stack = Stack()

        self.op_stack.push("$")
        self.val_stack.push("$")

        return self.parse_token_list_rec(self.op_priority["$"])
Exemple #2
0
    def __init__(self, id_, component, parent = None):
        Reflective.__init__(self)

        self.uid = Runnable.uid_count
        Runnable.uid_count += 1

        self.id = id_
        self.component = component
        self.parent = parent

        self.time_step = 0
        self.time_completed = 0
        self.time_total = 0

        self.plastic = True

        self.state_stack = Stack()

        self.children = {}
        self.uchildren = {}

        self.recorded_variables = []

        self.event_out_ports = []
        self.event_in_ports = []

        self.event_out_callbacks = {}
        self.event_in_counters = {}

        self.attachments = {}

        self.new_regime = ''
        self.current_regime = ''
        self.last_regime = ''
        self.regimes = {}
Exemple #3
0
    def __init__(self, id, parent=None):
        Reflective.__init__(self)

        self.id = id
        self.parent = parent

        self.time_step = 0
        self.time_completed = 0
        self.time_total = 0

        self.plastic = True

        self.state_stack = Stack()

        self.children = {}

        self.recorded_variables = {}

        self.event_out_callbacks = {}
        self.event_in_counters = {}
Exemple #4
0
    def __init__(self, id, parent = None):
        Reflective.__init__(self)

        self.id = id
        self.parent = parent
        
        self.time_step = 0
        self.time_completed = 0
        self.time_total = 0

        self.plastic = True

        self.state_stack = Stack()

        self.children = {}

        self.recorded_variables = {}

        self.event_out_callbacks = {}
        self.event_in_counters = {}
Exemple #5
0
class Runnable(Reflective):
    uid_count = 0

    def __init__(self, id_, component, parent = None):
        Reflective.__init__(self)

        self.uid = Runnable.uid_count
        Runnable.uid_count += 1

        self.id = id_
        self.component = component
        self.parent = parent

        self.time_step = 0
        self.time_completed = 0
        self.time_total = 0

        self.plastic = True

        self.state_stack = Stack()

        self.children = {}
        self.uchildren = {}

        self.recorded_variables = []

        self.event_out_ports = []
        self.event_in_ports = []

        self.event_out_callbacks = {}
        self.event_in_counters = {}

        self.attachments = {}

        self.new_regime = ''
        self.current_regime = ''
        self.last_regime = ''
        self.regimes = {}

    def add_child(self, id_, runnable):
        self.uchildren[runnable.uid] = runnable
        
        self.children[id_] = runnable
        self.children[runnable.id] = runnable

        self.__dict__[id_] = runnable
        self.__dict__[runnable.id] = runnable

        runnable.configure_time(self.time_step, self.time_total)

    def add_child_to_group(self, group_name, child):
        if group_name not in self.__dict__:
            self.__dict__[group_name] = []
        self.__dict__[group_name].append(child)

    def make_attachment(self, type_, name):
        self.attachments[type_] = name
        self.__dict__[name] = []

    def add_attachment(self, runnable):
        component_type = runnable.component.context.lookup_component_type(
            runnable.component.component_type)

        for ctype in component_type.types:
            if ctype in self.attachments:
                name = self.attachments[ctype]
                runnable.id = runnable.id + str(len(self.__dict__[name]))
                self.__dict__[name].append(runnable)

                return

        raise SimBuildError('Unable to find appropriate attachment')

    def add_event_in_port(self, port):
        self.event_in_ports.append(port)
        if port not in self.event_in_counters:
            self.event_in_counters[port] = 0

    def inc_event_in(self, port):
        self.event_in_counters[port] += 1

    def add_event_out_port(self, port):
        self.event_out_ports.append(port)
        if port not in self.event_out_callbacks:
            self.event_out_callbacks[port] = []

    def register_event_out_link(self, port, runnable, remote_port):
        self.event_out_callbacks[port].append((runnable, remote_port))

    def register_event_out_callback(self, port, callback):
        if port in self.event_out_callbacks:
            self.event_out_callbacks[port].append(callback)
        else:
            raise SimBuildError('No event out port \'{0}\' in '
                                'component \'{1}\''.format(port, self.id))

    def add_regime(self, regime):
        self.regimes[regime.name] = regime

    def resolve_path(self, path):
        if path == '':
            return self
        if path[0] == '/':
            return self.parent.resolve_path(path)
        elif path.find('../') == 0:
            return self.parent.resolve_path(path[3:])
        elif path.find('..') == 0:
            return self.parent
        else:
            if path.find('/') >= 1:
                (child, new_path) = path.split('/', 1)
            else:
                child = path
                new_path = ''

            idxbegin = child.find('[')
            idxend = child.find(']')
            if idxbegin != 0 and idxend > idxbegin:
                idx = int(child[idxbegin+1:idxend])
                child = child[:idxbegin]
            else:
                idx = -1

            if child in self.children:
                childobj = self.children[child]
                if idx != -1:
                    childobj = childobj.array[idx]
            elif child in self.component.context.parameters:
                ctx = self.component.context
                p = ctx.parameters[child]
                return self.resolve_path('../' + p.value)
            else:
                raise SimBuildError('Unable to find child \'{0}\' in '
                                    '\'{1}\''.format(child, self.id))

            if new_path == '':
                return childobj
            else:
                return childobj.resolve_path(new_path)

    def add_variable_recorder(self, data_output, recorder):
        self.add_variable_recorder2(data_output, recorder, recorder.quantity)

    def add_variable_recorder2(self, data_output, recorder, path):
        if path[0] == '/':
            self.parent.add_variable_recorder2(data_output, recorder, path)
        elif path.find('../') == 0:
            self.parent.add_variable_recorder2(data_output, recorder, path[3:])
        elif path.find('/') >= 1:
            (child, new_path) = path.split('/', 1)

            idxbegin = child.find('[')
            idxend = child.find(']')
            if idxbegin != 0 and idxend > idxbegin:
                idx = int(child[idxbegin+1:idxend])
                child = child[:idxbegin]
            else:
                idx = -1

            if child in self.children:
                childobj = self.children[child]
                if idx == -1:
                    childobj.add_variable_recorder2(data_output,
                                                    recorder,
                                                    new_path)
                else:
                    childobj.array[idx].add_variable_recorder2(data_output,
                                                               recorder,
                                                               new_path)
            else:
                raise SimBuildError('Unable to find child \'{0}\' in '
                                    '\'{1}\''.format(child, self.id))
        else:
            self.recorded_variables.append(Recording(path, data_output, recorder))


    def configure_time(self, time_step, time_total):
        self.time_step = time_step
        self.time_total = time_total

        for cn in self.uchildren:
            self.uchildren[cn].configure_time(self.time_step, self.time_total)

        for c in self.array:
            c.configure_time(self.time_step, self.time_total)

        ## for type_ in self.attachments:
        ##     components = self.__dict__[self.attachments[type_]]
        ##     for component in components:
        ##         component.configure_time(self.time_step, self.time_total)


    def reset_time(self):
        self.time_completed = 0

        for cid in self.uchildren:
            self.uchildren[cid].reset_time()

        for c in self.array:
            c.reset_time()

        ## for type_ in self.attachments:
        ##     components = self.__dict__[self.attachments[type_]]
        ##     for component in components:
        ##         component.reset_time()

    def single_step(self, dt):
        #return self.single_step2(dt)

        # For debugging
        try:
            return self.single_step2(dt)
        #except Ex1 as e:
        #    print self.rate
        #    print self.midpoint
        #    print self.scale
        #    print self.parent.parent.parent.parent.v
        #    # rate * exp((v - midpoint)/scale)
        #    sys.exit(0)
        except Exception as e:
            r = self
            name = r.id
            while r.parent:
                r = r.parent
                name = "{0}.{1}".format(r.id, name)

            print("Error in '{0} ({2})': {1}".format(name, e,
                                                     self.component.component_type))
            print(type(e))
            keys = self.__dict__.keys()
            keys.sort()
            for k in keys:
                print('{0} -> {1}'.format(k, self.__dict__[k]))
            print('')
            print('')

            if isinstance(e, ArithmeticError):
                print(('This is an arithmetic error. Consider reducing the '
                       'integration time step.'))

            sys.exit(0)

    def single_step2(self, dt):
        for cid in self.uchildren:
            self.uchildren[cid].single_step(dt)

        for child in self.array:
            child.single_step(dt)

        ## for type_ in self.attachments:
        ##     components = self.__dict__[self.attachments[type_]]
        ##     for component in components:
        ##         component.single_step(dt)

        if self.new_regime != '':
            self.current_regime = self.new_regime
            self.new_regime = ''

        self.update_kinetic_scheme(self, dt)

        if self.time_completed == 0:
            self.run_startup_event_handlers(self)

        self.run_preprocessing_event_handlers(self)
        self.update_shadow_variables()

        self.update_derived_variables(self)
        self.update_shadow_variables()

        self.update_state_variables(self, dt)
        self.update_shadow_variables()

        self.run_postprocessing_event_handlers(self)
        self.update_shadow_variables()

        if self.current_regime != '':
            regime = self.regimes[self.current_regime]

            regime.update_kinetic_scheme(self, dt)

            #if self.time_completed == 0:
            #    self.run_startup_event_handlers(self)

            regime.run_preprocessing_event_handlers(self)
            self.update_shadow_variables()

            regime.update_derived_variables(self)
            self.update_shadow_variables()

            regime.update_state_variables(self, dt)
            self.update_shadow_variables()

            regime.run_postprocessing_event_handlers(self)
            self.update_shadow_variables()

        self.record_variables()

        self.time_completed += dt
        if self.time_completed >= self.time_total:
            return 0
        else:
            return dt


    def record_variables(self):
        for recording in self.recorded_variables:
            recording.add_value(self.time_completed,
                               self.__dict__[recording.variable])

    def push_state(self):
        vars = []
        for varname in self.instance_variables:
            vars += [self.__dict__[varname],
                     self.__dict__[varname + '_shadow']]
        self.state_stack.push(vars)

        for cid in self.uchildren:
            self.uchildren[cid].push_state()

        for c in self.array:
            c.push_state()

    def pop_state(self):
        vars = self.state_stack.pop()
        for varname in self.instance_variables:
            self.__dict_[varname] = vars[0]
            self.__dict_[varname + '_shadow'] = vars[1]
            vars = vars[2:]

        for cid in self.uchildren:
            self.uchildren[cid].pop_state()

        for c in self.array:
            c.pop_state()

    def update_shadow_variables(self):
        if self.plastic:
            for var in self.instance_variables:
                self.__dict__[var + '_shadow'] = self.__dict__[var]
            for var in self.derived_variables:
                self.__dict__[var + '_shadow'] = self.__dict__[var]
Exemple #6
0
    def parse_token_list_rec(self):
        """
        Parses a tokenized arithmetic expression into a parse tree. It calls
        itself recursively to handle bracketed subexpressions.

        @return: Returns a token string.
        @rtype: lems.parser.expr.ExprNode

        @attention: Does not handle unary minuses at the moment. Needs to be
        fixed.
        """
        
        op_stack = Stack()
        val_stack = Stack()
        node_stack = Stack()
        
        op_stack.push('$')
        val_stack.push('$')

        exit_loop = False

        while self.token_list and not exit_loop:
            token = self.token_list[0]
            self.token_list = self.token_list[1:]
            
            #print '###> ', token,op_stack,node_stack,val_stack
            
            if token == '(':
                node_stack.push(self.parse_token_list_rec())
                val_stack.push('$')
            elif self.is_func(token):
                op_stack.push(token)
            elif self.is_op(token):
                if self.op_priority[op_stack.top()] >= \
                       self.op_priority[token]:

                    op = op_stack.pop()
                    if self.is_func(op):
                        rval = val_stack.pop()
                        if rval == '$':
                            right = node_stack.pop()
                        else:
                            right = ValueNode(rval)
                
                        node_stack.push(Func1Node(op, right))
                        val_stack.push('$')
                    elif op == '~':
                        rval = val_stack.pop()

                        if rval == '$':
                            right = node_stack.pop()
                        else:
                            right = ValueNode(rval)
                
                        node_stack.push(OpNode('-', ValueNode('0'), right))
                        val_stack.push('$')
                    else:
                        rval = val_stack.pop()
                        lval = val_stack.pop()
                        
                        if lval == '$':
                            left = node_stack.pop()
                        else:
                            left = ValueNode(lval)

                        if rval == '$':
                            right = node_stack.pop()
                        else:
                            right = ValueNode(rval)
                
                        node_stack.push(OpNode(op, left, right))
                        val_stack.push('$')
                    
                op_stack.push(token)
            elif token == ')':
                exit_loop = True
            else:
                val_stack.push(token)
                
        rval = val_stack.pop()
        if rval == '$':
            right = node_stack.pop()
        else:
            right = ValueNode(rval)

        while op_stack.top() != '$':
            op = op_stack.pop()

            if self.is_func(op):
                right = Func1Node(op, right)
            elif op == '~':
                lval = val_stack.pop()

                right = OpNode('-', ValueNode('0'), right)
            else:
                lval = val_stack.pop()
                if lval == '$':
                    if node_stack.is_empty():
                        left = ValueNode('0')
                    else:
                        left = node_stack.pop()
                else:
                    left = ValueNode(lval)

                right = OpNode(op, left, right)
                
        return right
Exemple #7
0
    def parse_token_list_rec(self):
        """
        Parses a tokenized arithmetic expression into a parse tree. It calls
        itself recursively to handle bracketed subexpressions.

        @return: Returns a token string.
        @rtype: lems.parser.expr.ExprNode

        @attention: Does not handle unary minuses at the moment. Needs to be
        fixed.
        """

        op_stack = Stack()
        val_stack = Stack()
        node_stack = Stack()

        op_stack.push('$')
        val_stack.push('$')

        exit_loop = False

        while self.token_list and not exit_loop:
            token = self.token_list[0]
            self.token_list = self.token_list[1:]

            #print '###> ', token,op_stack,node_stack,val_stack

            if token == '(':
                node_stack.push(self.parse_token_list_rec())
                val_stack.push('$')
            elif self.is_func(token):
                op_stack.push(token)
            elif self.is_op(token):
                if self.op_priority[op_stack.top()] >= \
                       self.op_priority[token]:

                    op = op_stack.pop()
                    if self.is_func(op):
                        rval = val_stack.pop()
                        if rval == '$':
                            right = node_stack.pop()
                        else:
                            right = ValueNode(rval)

                        node_stack.push(Func1Node(op, right))
                        val_stack.push('$')
                    elif op == '~':
                        rval = val_stack.pop()

                        if rval == '$':
                            right = node_stack.pop()
                        else:
                            right = ValueNode(rval)

                        node_stack.push(OpNode('-', ValueNode('0'), right))
                        val_stack.push('$')
                    else:
                        rval = val_stack.pop()
                        lval = val_stack.pop()

                        if lval == '$':
                            left = node_stack.pop()
                        else:
                            left = ValueNode(lval)

                        if rval == '$':
                            right = node_stack.pop()
                        else:
                            right = ValueNode(rval)

                        node_stack.push(OpNode(op, left, right))
                        val_stack.push('$')

                op_stack.push(token)
            elif token == ')':
                exit_loop = True
            else:
                val_stack.push(token)

        rval = val_stack.pop()
        if rval == '$':
            right = node_stack.pop()
        else:
            right = ValueNode(rval)

        while op_stack.top() != '$':
            op = op_stack.pop()

            if self.is_func(op):
                right = Func1Node(op, right)
            elif op == '~':
                lval = val_stack.pop()

                right = OpNode('-', ValueNode('0'), right)
            else:
                lval = val_stack.pop()
                if lval == '$':
                    if node_stack.is_empty():
                        left = ValueNode('0')
                    else:
                        left = node_stack.pop()
                else:
                    left = ValueNode(lval)

                right = OpNode(op, left, right)

        return right
Exemple #8
0
class ExprParser(LEMSBase):
    """
    Parser class for parsing an expression and generating a parse tree.
    """

    op_priority = {
        "$": -5,
        "func": 8,
        "+": 5,
        "-": 5,
        "*": 6,
        "/": 6,
        "^": 7,
        "~": 8,
        "exp": 8,
        ".and.": 1,
        ".or.": 1,
        ".gt.": 2,
        ".ge.": 2,
        ".geq.": 2,
        ".lt.": 2,
        ".le.": 2,
        ".eq.": 2,
        ".ne.": 2,
    }

    depth = 0

    """ Dictionary mapping operators to their priorities.
    @type: dict(string -> Integer) """

    def __init__(self, parse_string):
        """
        Constructor.

        @param parse_string: Expression to be parsed.
        @type parse_string: string
        """

        self.parse_string = parse_string
        """ Expression to be parsed.
        @type: string """

        self.token_list = None
        """ List of tokens from the expression to be parsed.
        @type: list(string) """

    def is_op(self, str):
        """
        Checks if a token string contains an operator.

        @param str: Token string to be checked.
        @type str: string

        @return: True if the token string contains an operator.
        @rtype: Boolean
        """

        return str in self.op_priority

    def is_func(self, str):
        """
        Checks if a token string contains a function.

        @param str: Token string to be checked.
        @type str: string

        @return: True if the token string contains a function.
        @rtype: Boolean
        """

        return str in ["exp", "ln"]

    def is_sym(self, str):
        """
        Checks if a token string contains a symbol.

        @param str: Token string to be checked.
        @type str: string

        @return: True if the token string contains a symbol.
        @rtype: Boolean
        """

        return str in ["+", "-", "~", "*", "/", "^", "(", ")"]

    def priority(self, op):
        if self.is_op(op):
            return self.op_priority[op]
        elif self.is_func(op):
            return self.op_priority["func"]
        else:
            return self.op_priority["$"]

    def tokenize(self):
        """
        Tokenizes the string stored in the parser object into a list
        of tokens.
        """

        self.token_list = []
        ps = self.parse_string.strip()

        i = 0
        last_token = None

        while i < len(ps) and ps[i].isspace():
            i += 1

        while i < len(ps):
            token = ""

            if ps[i].isalpha():
                while i < len(ps) and (ps[i].isalnum() or ps[i] == "_"):
                    token += ps[i]
                    i += 1
            elif ps[i].isdigit():
                while i < len(ps) and (ps[i].isdigit() or ps[i] == "."):
                    token += ps[i]
                    i += 1
            elif ps[i] == ".":
                if ps[i + 1].isdigit():
                    while i < len(ps) and (ps[i].isdigit() or ps[i] == "."):
                        token += ps[i]
                        i += 1
                else:
                    while i < len(ps) and (ps[i].isalpha() or ps[i] == "."):
                        token += ps[i]
                        i += 1
            else:
                token += ps[i]
                i += 1

            if token == "-" and (last_token == None or last_token == "(" or self.is_op(last_token)):
                token = "~"

            self.token_list += [token]
            last_token = token

            while i < len(ps) and ps[i].isspace():
                i += 1

    def make_op_node(self, op, right):
        if self.is_func(op):
            return Func1Node(op, right)
        elif op == "~":
            return OpNode("-", ValueNode("0"), right)
        else:
            left = self.val_stack.pop()
            if left == "$":
                left = self.node_stack.pop()
            else:
                left = ValueNode(left)

            return OpNode(op, left, right)

    def cleanup_stacks(self):
        right = self.val_stack.pop()
        if right == "$":
            right = self.node_stack.pop()
        else:
            right = ValueNode(right)

        while self.op_stack.top() != "$":
            # print '4>', self.op_stack, self.val_stack, self.node_stack
            op = self.op_stack.pop()

            right = self.make_op_node(op, right)

            # print '5>', self.op_stack, self.val_stack, self.node_stack
            # print '6', right
            # print ''

        return right

    def parse_token_list_rec(self, min_precedence):
        """
        Parses a tokenized arithmetic expression into a parse tree. It calls
        itself recursively to handle bracketed subexpressions.

        @return: Returns a token string.
        @rtype: lems.parser.expr.ExprNode

        @attention: Does not handle unary minuses at the moment. Needs to be
        fixed.
        """

        exit_loop = False

        ExprParser.depth = ExprParser.depth + 1
        # print ''
        # print '>>>>>', ExprParser.depth

        precedence = min_precedence

        while self.token_list:
            token = self.token_list[0]
            la = self.token_list[1] if len(self.token_list) > 1 else None

            # print '0>', self.token_list
            # print '1>', token, la, self.op_stack, self.val_stack, self.node_stack

            self.token_list = self.token_list[1:]

            if token == "(":
                np = ExprParser("")
                np.token_list = self.token_list

                nexp = np.parse2()

                self.node_stack.push(nexp)
                self.val_stack.push("$")

                self.token_list = np.token_list
            elif token == ")":
                break
            elif self.is_func(token):
                self.op_stack.push(token)
            elif self.is_op(token):
                stack_top = self.op_stack.top()
                # print 'HELLO0', token, stack_top
                # print 'HELLO1', self.priority(token), self.priority(stack_top)
                if self.priority(token) < self.priority(stack_top):
                    self.node_stack.push(self.cleanup_stacks())
                    self.val_stack.push("$")

                self.op_stack.push(token)
            else:
                stack_top = self.op_stack.top()
                if stack_top == "$":
                    self.node_stack.push(ValueNode(token))
                    self.val_stack.push("$")
                else:
                    if self.is_op(la) and self.priority(stack_top) < self.priority(la):

                        self.node_stack.push(ValueNode(token))
                        self.val_stack.push("$")
                    else:
                        op = self.op_stack.pop()

                        right = ValueNode(token)
                        op_node = self.make_op_node(op, right)

                        self.node_stack.push(op_node)
                        self.val_stack.push("$")

            # print '2>', token, la, self.op_stack, self.val_stack, self.node_stack
            # print ''

        # print '3>', self.op_stack, self.val_stack, self.node_stack
        ret = self.cleanup_stacks()

        # print '<<<<<', ExprParser.depth, ret
        ExprParser.depth = ExprParser.depth - 1
        # print ''
        return ret

    def parse(self):
        """
        Tokenizes and parses an arithmetic expression into a parse tree.

        @return: Returns a token string.
        @rtype: lems.parser.expr.ExprNode
        """

        self.tokenize()
        return self.parse2()

    def parse2(self):
        self.op_stack = Stack()
        self.val_stack = Stack()
        self.node_stack = Stack()

        self.op_stack.push("$")
        self.val_stack.push("$")

        return self.parse_token_list_rec(self.op_priority["$"])
        # return self.parse_token_list_rec()

    def __str__(self):
        return str(self.token_list)
Exemple #9
0
class Runnable(Reflective):
    def __init__(self, id, parent=None):
        Reflective.__init__(self)

        self.id = id
        self.parent = parent

        self.time_step = 0
        self.time_completed = 0
        self.time_total = 0

        self.plastic = True

        self.state_stack = Stack()

        self.children = {}

        self.recorded_variables = {}

        self.event_out_callbacks = {}
        self.event_in_counters = {}

    def add_child(self, id, runnable):
        self.children[id] = runnable
        runnable.configure_time(self.time_step, self.time_total)

    def add_event_in_port(self, port):
        if port not in self.event_in_counters:
            self.event_in_counters[port] = 0

    def inc_event_in(self, port):
        self.event_in_counters[port] += 1

    def add_event_out_port(self, port):
        if port not in self.event_out_callbacks:
            self.event_out_callbacks[port] = []

    def register_event_out_link(self, port, runnable, remote_port):
        self.event_out_callbacks[port].append((runnable, remote_port))

    def register_event_out_callback(self, port, callback):
        if port in self.event_out_callbacks:
            self.event_out_callbacks[port].append(callback)
        else:
            raise SimBuildError('No event out port \'{0}\' in '
                                'component \'{1}\''.format(port, self.name))

    def add_variable_recorder(self, path):
        if path[0] == '/':
            self.parent.add_variable_recorder(path)
        elif path.find('../') == 0:
            self.parent.add_variable_recorder(path[3:])
        elif path.find('/') >= 1:
            (child, new_path) = path.split('/', 1)

            idxbegin = child.find('[')
            idxend = child.find(']')
            if idxbegin != 0 and idxend > idxbegin:
                idx = int(child[idxbegin + 1:idxend])
                child = child[:idxbegin]
            else:
                idx = -1

            if child in self.children:
                childobj = self.children[child]
                if idx == -1:
                    childobj.add_variable_recorder(new_path)
                else:
                    childobj.array[idx].add_variable_recorder(new_path)
            else:
                raise SimBuildError('Unable to find child \'{0}\' in '
                                    '\'{1}\''.format(child, self.id))
        else:
            self.recorded_variables[path] = []

    def configure_time(self, time_step, time_total):
        self.time_step = time_step
        self.time_total = time_total

        for cn in self.children:
            self.children[cn].configure_time(self.time_step, self.time_total)

    def reset_time(self):
        self.time_completed = 0

        for cid in self.children:
            self.children[cid].reset_time()

    def single_step(self, dt):
        # For debugging
        try:
            return self.single_step2(dt)
        except Exception as e:
            r = self
            name = r.id
            while r.parent:
                name = "{0}.{1}".format(r.id, name)
                r = r.parent

            print "Error in '{0}': {1}".format(name, e)
            sys.exit(0)

    def single_step2(self, dt):
        #print 'Single stepping {0}'.format(self.id)

        self.run_preprocessing_event_handlers(self)
        self.update_shadow_variables()

        self.update_state_variables(self, dt)
        self.update_shadow_variables()

        self.run_postprocessing_event_handlers(self)
        self.update_shadow_variables()

        self.record_variables()

        for cid in self.children:
            self.children[cid].single_step(dt)

        self.time_completed += self.time_step
        if self.time_completed >= self.time_total:
            return 0
        else:
            return self.time_step

    def record_variables(self):
        for variable in self.recorded_variables:
            self.recorded_variables[variable].append(\
                (self.time_completed, self.__dict__[variable]))
            #print self.id
            #print self.time_completed, self.__dict__[variable]

    def push_state(self):
        vars = []
        for varname in self.instance_variables:
            vars += [
                self.__dict__[varname], self.__dict__[varname + '_shadow']
            ]
        self.state_stack.push(vars)

        for cid in self.children:
            self.children[cid].push_state()

    def pop_state(self):
        vars = self.state_stack.pop()
        for varname in self.instance_variables:
            self.__dict_[varname] = vars[0]
            self.__dict_[varname + '_shadow'] = vars[1]
            vars = vars[2:]

        for cid in self.children:
            self.children[cid].pop_state()

    def update_shadow_variables(self):
        if self.plastic:
            for var in self.instance_variables:
                self.__dict__[var + '_shadow'] = self.__dict__[var]
Exemple #10
0
class ExprParser(LEMSBase):
    """
    Parser class for parsing an expression and generating a parse tree.
    """

    op_priority = {
        '$':-5,

        'func':8,

        '+':5,
        '-':5,
        '*':6,
        '/':6,
        '^':7,

        '~':8,

        'exp':8,

        '.and.':1,
        '.or.':1,
        '.gt.':2,
        '.ge.':2,
        '.geq.':2,
        '.lt.':2,
        '.le.':2,
        '.eq.':2,
        '.ne.':2}

    depth = 0

    """ Dictionary mapping operators to their priorities.
    @type: dict(string -> Integer) """

    def __init__(self, parse_string):
        """
        Constructor.

        @param parse_string: Expression to be parsed.
        @type parse_string: string
        """

        self.parse_string = parse_string
        """ Expression to be parsed.
        @type: string """

        self.token_list = None
        """ List of tokens from the expression to be parsed.
        @type: list(string) """

    def is_op(self, str):
        """
        Checks if a token string contains an operator.

        @param str: Token string to be checked.
        @type str: string

        @return: True if the token string contains an operator.
        @rtype: Boolean
        """

        return str in self.op_priority

    def is_func(self, str):
        """
        Checks if a token string contains a function.

        @param str: Token string to be checked.
        @type str: string

        @return: True if the token string contains a function.
        @rtype: Boolean
        """

        return str in ['exp', 'ln']

    def is_sym(self, str):
        """
        Checks if a token string contains a symbol.

        @param str: Token string to be checked.
        @type str: string

        @return: True if the token string contains a symbol.
        @rtype: Boolean
        """

        return str in ['+', '-', '~', '*', '/', '^', '(', ')']

    def priority(self, op):
        if self.is_op(op):
            return self.op_priority[op]
        elif self.is_func(op):
            return self.op_priority['func']
        else:
            return self.op_priority['$']

    def tokenize(self):
        """
        Tokenizes the string stored in the parser object into a list
        of tokens.
        """

        self.token_list = []
        ps = self.parse_string.strip()

        i = 0
        last_token = None

        while i < len(ps) and ps[i].isspace():
            i += 1

        while i < len(ps):
            token = ''

            if ps[i].isalpha():
                while i < len(ps) and (ps[i].isalnum() or ps[i] == '_'):
                    token += ps[i]
                    i += 1
            elif ps[i].isdigit():
                while i < len(ps) and (ps[i].isdigit() or
                                       ps[i] == '.' or
                                       ps[i] == 'e' or
                                       ps[i] == '+' or
                                       ps[i] == '-'):
                    token += ps[i]
                    i += 1
            elif ps[i] == '.':
                if ps[i+1].isdigit():
                    while i < len(ps) and (ps[i].isdigit() or ps[i] == '.'):
                        token += ps[i]
                        i += 1
                else:
                    while i < len(ps) and (ps[i].isalpha() or ps[i] == '.'):
                        token += ps[i]
                        i += 1
            else:
                token += ps[i]
                i += 1

            if token == '-' and \
               (last_token == None or last_token == '(' or self.is_op(last_token)):
                token = '~'

            self.token_list += [token]
            last_token = token

            while i < len(ps) and ps[i].isspace():
                i += 1

    def make_op_node(self, op, right):
        if self.is_func(op):
            return Func1Node(op, right)
        elif op == '~':
            return OpNode('-', ValueNode('0'), right)
        else:
            left = self.val_stack.pop()
            if left == '$':
                left = self.node_stack.pop()
            else:
                left = ValueNode(left)

            return OpNode(op, left, right)

    def cleanup_stacks(self):
        right = self.val_stack.pop()
        if right == '$':
            right = self.node_stack.pop()
        else:
            right = ValueNode(right)

        while self.op_stack.top() != '$':
            #print '4>', self.op_stack, self.val_stack, self.node_stack
            op = self.op_stack.pop()

            right = self.make_op_node(op, right)

            #print '5>', self.op_stack, self.val_stack, self.node_stack
            #print '6', right
            #print ''

        return right

    def parse_token_list_rec(self, min_precedence):
        """
        Parses a tokenized arithmetic expression into a parse tree. It calls
        itself recursively to handle bracketed subexpressions.

        @return: Returns a token string.
        @rtype: lems.parser.expr.ExprNode

        @attention: Does not handle unary minuses at the moment. Needs to be
        fixed.
        """

        exit_loop = False

        ExprParser.depth = ExprParser.depth + 1
        #print ''
        #print '>>>>>', ExprParser.depth

        precedence = min_precedence

        while self.token_list:
            token = self.token_list[0]
            la = self.token_list[1] if len(self.token_list) > 1 else None

            #print '0>', self.token_list
            #print '1>', token, la, self.op_stack, self.val_stack, self.node_stack

            self.token_list = self.token_list[1:]

            if token == '(':
                np = ExprParser('')
                np.token_list = self.token_list

                nexp = np.parse2()

                self.node_stack.push(nexp)
                self.val_stack.push('$')

                self.token_list = np.token_list
            elif token == ')':
                break
            elif self.is_func(token):
                self.op_stack.push(token)
            elif self.is_op(token):
                stack_top = self.op_stack.top()
                #print 'HELLO0', token, stack_top
                #print 'HELLO1', self.priority(token), self.priority(stack_top)
                if self.priority(token) < self.priority(stack_top):
                    self.node_stack.push(self.cleanup_stacks())
                    self.val_stack.push('$')

                self.op_stack.push(token)
            else:
                stack_top = self.op_stack.top()
                if stack_top == '$':
                    self.node_stack.push(ValueNode(token))
                    self.val_stack.push('$')
                else:
                    if (self.is_op(la) and
                        self.priority(stack_top) < self.priority(la)):

                        self.node_stack.push(ValueNode(token))
                        self.val_stack.push('$')
                    else:
                        op = self.op_stack.pop()

                        right = ValueNode(token)
                        op_node = self.make_op_node(op,right)

                        self.node_stack.push(op_node)
                        self.val_stack.push('$')

            #print '2>', token, la, self.op_stack, self.val_stack, self.node_stack
            #print ''

        #print '3>', self.op_stack, self.val_stack, self.node_stack
        ret = self.cleanup_stacks()

        #print '<<<<<', ExprParser.depth, ret
        ExprParser.depth = ExprParser.depth - 1
        #print ''
        return ret

    def parse(self):
        """
        Tokenizes and parses an arithmetic expression into a parse tree.

        @return: Returns a token string.
        @rtype: lems.parser.expr.ExprNode
        """

        self.tokenize()
        return self.parse2()

    def parse2(self):
        self.op_stack = Stack()
        self.val_stack = Stack()
        self.node_stack = Stack()

        self.op_stack.push('$')
        self.val_stack.push('$')

        return self.parse_token_list_rec(self.op_priority['$'])
        #return self.parse_token_list_rec()

    def __str__(self):
        return str(self.token_list)
Exemple #11
0
class Runnable(Reflective):
    def __init__(self, id, parent = None):
        Reflective.__init__(self)

        self.id = id
        self.parent = parent
        
        self.time_step = 0
        self.time_completed = 0
        self.time_total = 0

        self.plastic = True

        self.state_stack = Stack()

        self.children = {}

        self.recorded_variables = {}

        self.event_out_callbacks = {}
        self.event_in_counters = {}

    def add_child(self, id, runnable):
        self.children[id] = runnable
        runnable.configure_time(self.time_step, self.time_total)

    def add_event_in_port(self, port):
        if port not in self.event_in_counters:
            self.event_in_counters[port] = 0

    def inc_event_in(self, port):
        self.event_in_counters[port] += 1
        
    def add_event_out_port(self, port):
        if port not in self.event_out_callbacks:
            self.event_out_callbacks[port] = []

    def register_event_out_link(self, port, runnable, remote_port):
        self.event_out_callbacks[port].append((runnable, remote_port))
        
    def register_event_out_callback(self, port, callback):
        if port in self.event_out_callbacks:
            self.event_out_callbacks[port].append(callback)
        else:
            raise SimBuildError('No event out port \'{0}\' in '
                                'component \'{1}\''.format(port, self.name))
                                    
    def add_variable_recorder(self, path):
        if path[0] == '/':
            self.parent.add_variable_recorder(path)
        elif path.find('../') == 0:
            self.parent.add_variable_recorder(path[3:])
        elif path.find('/') >= 1:
            (child, new_path) = path.split('/', 1)

            idxbegin = child.find('[')
            idxend = child.find(']')
            if idxbegin != 0 and idxend > idxbegin:
                idx = int(child[idxbegin+1:idxend])
                child = child[:idxbegin]
            else:
                idx = -1

            if child in self.children:
                childobj = self.children[child]
                if idx == -1:
                    childobj.add_variable_recorder(new_path)
                else:
                    childobj.array[idx].add_variable_recorder(new_path)
            else:
                raise SimBuildError('Unable to find child \'{0}\' in '
                                    '\'{1}\''.format(child, self.id))
        else:
            self.recorded_variables[path] = []

    def configure_time(self, time_step, time_total):
        self.time_step = time_step
        self.time_total = time_total

        for cn in self.children:
            self.children[cn].configure_time(self.time_step, self.time_total)

        
    def reset_time(self):
        self.time_completed = 0
        
        for cid in self.children:
            self.children[cid].reset_time()

    def single_step(self, dt):
        # For debugging
        try:
            return self.single_step2(dt)
        except Exception as e:
            r = self
            name = r.id
            while r.parent:
                name = "{0}.{1}".format(r.id, name)
                r = r.parent
                
            print "Error in '{0}': {1}".format(name, e)
            sys.exit(0)
            
    def single_step2(self, dt):
        #print 'Single stepping {0}'.format(self.id)
        
        self.run_preprocessing_event_handlers(self)
        self.update_shadow_variables()

        self.update_state_variables(self, dt)
        self.update_shadow_variables()

        self.run_postprocessing_event_handlers(self)
        self.update_shadow_variables()

        self.record_variables()

        for cid in self.children:
            self.children[cid].single_step(dt)

        self.time_completed += self.time_step
        if self.time_completed >= self.time_total:
            return 0
        else:
            return self.time_step

    def record_variables(self):
        for variable in self.recorded_variables:
            self.recorded_variables[variable].append(\
                (self.time_completed, self.__dict__[variable]))
            #print self.id
            #print self.time_completed, self.__dict__[variable]
            
    def push_state(self):
        vars = []
        for varname in self.instance_variables:
            vars += [self.__dict__[varname],
                     self.__dict__[varname + '_shadow']]
        self.state_stack.push(vars)

        for cid in self.children:
            self.children[cid].push_state()

    def pop_state(self):
        vars = self.state_stack.pop()
        for varname in self.instance_variables:
            self.__dict_[varname] = vars[0]
            self.__dict_[varname + '_shadow'] = vars[1]
            vars = vars[2:]

        for cid in self.children:
            self.children[cid].pop_state()

    def update_shadow_variables(self):
        if self.plastic:
            for var in self.instance_variables:
                self.__dict__[var + '_shadow'] = self.__dict__[var]