def shock_values_list(self) -> CompoundASTList: """ The values of the shocks can be single numbers or general expressions. If the latter, the whole expression must be in parantheses shocK_values_list : ((NUM | LPARE expr RPARE) (COMMA))+ """ shock_values = ast.CompoundASTList() while self.current_token.type in (base.COMMA, base.NUMBER, base.LPARE): if self.current_token.type == base.COMMA: self.eat(base.COMMA) if self.current_token.type == base.NUMBER: token = self.current_token self.eat(base.NUMBER) single_value = ast.Num(token) else: self.eat(base.LPARE) single_value = self.expr() self.eat(base.RPARE) shock_values.append(single_value) return shock_values
def atom(self) -> AST: """ atom : ID | NUMBER | LPARE expr RPARE | (NIMUS | PLUS) term """ token = self.current_token if token.type == base.ID: self.eat(base.ID) return ast.Var(token) elif token.type == base.NUMBER: self.eat(base.NUMBER) return ast.Num(token) elif token.type == base.LPARE: self.eat(base.LPARE) node = self.expr() self.eat(base.RPARE) return node elif token.type in (base.MINUS, base.PLUS): self.eat(token.type) # sending 'expr' to term() instead of expr() is what ensures # the proper unary operation functionality return ast.UnaryOp(op=token, expr=self.term()) self.error()
def model_expression(self) -> ModelExpression: """ model_expression : mexpr | mexpr EQUALS mexpr """ left = self.mexpr() if self.peek_type() == base.EQUALS: self.eat(base.EQUALS) right = self.mexpr() else: # if there's no equals sign, it's assumed this is a homogenous equation zero = Token(base.NUMBER, 0) right = ast.Num(zero) return ast.ModelExpression(left=left, right=right)
def matom(self) -> AST: token = self.current_token if token.type == base.ID: var = self.maybe_period_variable() return var elif token.type == base.NUMBER: self.eat(base.NUMBER) return ast.Num(token) elif token.type == base.LPARE: self.eat(base.LPARE) node = self.mexpr() self.eat(base.RPARE) return node elif token.type in (base.MINUS, base.PLUS): self.eat(token.type) node = ast.UnaryOp(op=token, expr=self.mterm()) return node self.error()
def substitute(self, node, var_value): var_name = node.value token = Token(NUMBER, var_value) return ast.Num(token)