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["$"])
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 __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 __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 = {}
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]
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
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)
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]
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)
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]