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 shock_periods_list(self) -> CompoundASTList: """ A single shock period can either be a single integer, signifying a one period deterministic shock, or a range of periods from a:b shock_periods_list : ((NUM | NUM:NUM) (COMMA))+ """ shock_periods = ast.CompoundASTList() while self.current_token.type in (base.COMMA, base.NUMBER): if self.current_token.type == base.COMMA: self.eat(base.COMMA) start = self.current_token self.eat(base.NUMBER) if self.current_token.type == base.COLON: self.eat(base.COLON) end = self.current_token self.eat(base.NUMBER) single_period = ast.DeterministicShockPeriod(start=start, end=end) else: single_period = ast.DeterministicShockPeriod(start=start, end=start) shock_periods.append(single_period) return shock_periods
def optional_argument_list(self) -> CompoundASTList: """ dynare allows for both keyword arguments and placement arguments, whereas matlab only uses the presence of arguments to signifiy deviations from the default optional_argument_list : LPARE (ID | ID EQUALS (ID | STRING | expr))+ RPARE | empty """ if self.current_token.type != base.LPARE: return ast.CompoundASTList() return self.argument_list()
def argument_list(self) -> CompoundASTList: self.eat(base.LPARE) arg_list = ast.CompoundASTList() first_arg = self.single_argument() arg_list.append(first_arg) while self.current_token.type == base.COMMA: self.eat(base.COMMA) single_arg = self.single_argument() arg_list.append(single_arg) self.eat(base.RPARE) return arg_list
def tag_list(self) -> CompoundASTList: """ tag_list : LBRACKET single_tag (COMMA single_tag)* RBRACKET """ self.eat(base.LBRACKET) tags = ast.CompoundASTList() tags.append(self.single_tag()) while self.current_token.type == base.COMMA: self.eat(base.COMMA) tags.append(self.single_tag()) self.eat(base.RBRACKET) return tags
def variable_preamble(self) -> VariablePreamble: """ The variable preamble is the entirety of mod file that comes before the model definition. Two main things are done in that section: 1) Declaring variable and their types 2) Assigning values to the parameters The parser doesn't do any type checks - it doesn't ensure variables being assigned values are actually parameters, nor does it ensure that any endogenous variables are declared variable_preamble : variable_type_declaration (variable_preamble)* | parameter assignment (variable_preamble)* | empty """ # the change_type command that's listed in the same section of the dynare # module is not included here - I really don't know how that's used yet dynare_variable_types = [ dyn.VAR, dyn.VAREXO, dyn.VAREXO_DET, dyn.PARAMETERS, dyn.PREDETERMINED, dyn.TREND_VAR, dyn.LOG_TREND_VAR ] declaration_list = ast.CompoundASTList() parameter_list = ast.CompoundASTList() while self.current_token.type is not dyn.MODEL: if self.current_token.type in dynare_variable_types: declared_variables = self.variable_type_declaration() declaration_list.extend(declared_variables) elif self.current_token.type == base.ID: assigned_parameter = self.variable_assignment() parameter_list.append(assigned_parameter) return ast.VariablePreamble(declared_variables=declaration_list, assigned_parameters=parameter_list)