def visitConstantTimeLiteral(self, ctx): const_name = ctx.Identifier().getText() if const_name not in self.spec.const_val_dict: raise STLParseException('Bound {} not declared'.format(const_name)) val = self.spec.const_val_dict[const_name] out = Fraction(Decimal(val)) if ctx.unit() == None: # default time unit is seconds - conversion of the bound to ps unit = self.spec.unit else: unit = ctx.unit().getText() out = out * self.spec.U[unit] sp = Fraction(self.spec.get_sampling_period()) out = out / sp if out.numerator % out.denominator > 0: raise STLParseException( 'The STL operator bound must be a multiple of the sampling period' ) out = int(out / self.spec.sampling_period) return out
def visitExprId(self, ctx): id = ctx.Identifier().getText() # Identifier is a constant if id in self.spec.const_val_dict: val = self.spec.const_val_dict[id] node = Constant(float(val)) # Identifier is either an input variable or a sub-formula elif id in self.spec.var_subspec_dict: node = self.spec.var_subspec_dict[id] return node else: id_tokens = id.split('.') id_head = id_tokens[0] id_tokens.pop(0) id_tail = '.'.join(id_tokens) try: var = self.spec.create_var_from_name(id_head) if (not id_tail): if (not isinstance(var, (int, float))): raise STLParseException( 'Variable {} is not of type int or float'.format( id)) else: try: value = operator.attrgetter(id_tail)(var) if (not isinstance(value, (int, float))): raise STLParseException( 'The field {0} of the variable {1} is not of type int or float' .format(id, id_head)) except AttributeError as err: raise STLParseException(err) except KeyError: if id_tail: raise STLParseException( '{0} refers to undeclared variable {1} of unknown type' .format(id, id_head)) else: var = float() self.spec.var_object_dict[id] = var self.spec.add_var(id) logging.warning( 'The variable {} is not explicitely declared. It is implicitely declared as a ' 'variable of type float'.format(id)) var_io = self.spec.var_io_dict[id_head] node = Variable(id_head, id_tail, var_io) node.horizon = int(0) return node
def visitAssertion(self, ctx): out = self.visit(ctx.expression()) implicit = False if not ctx.Identifier(): id = 'out' implicit = True else: id = ctx.Identifier().getText() self.spec.var_subspec_dict[id] = out id_tokens = id.split('.') id_head = id_tokens[0] id_tokens.pop(0) id_tail = '.'.join(id_tokens) try: #var = self.spec.var_object_dict[id_head] var = self.spec.create_var_from_name(id_head) if (not id_tail): if (not isinstance(var, (int, float))): raise STLParseException( 'Variable {} is not of type int or float'.format(id)) else: try: value = operator.attrgetter(id_tail)(var) if (not isinstance(value, (int, float))): raise STLParseException( 'The field {0} of the variable {1} is not of type int or float' .format(id, id_head)) except AttributeError as err: raise STLParseException(err) except KeyError: if id_tail: raise STLParseException( '{0} refers to undeclared variable {1} of unknown type'. format(id, id_head)) else: var = float() self.spec.var_object_dict[id] = var self.spec.add_var(id) if not implicit: logging.warning( 'The variable {} is not explicitly declared. It is implicitly declared as a ' 'variable of type float'.format(id)) self.spec.out_var = id_head self.spec.out_var_field = id_tail self.spec.free_vars.discard(id_head) return out
def parse(self): if self.spec is None: raise STLParseException('STL specification if empty') # Parse the STL spec - ANTLR4 magic entire_spec = self.modular_spec + self.spec input_stream = InputStream(entire_spec) lexer = StlLexer(input_stream) stream = CommonTokenStream(lexer) parser = StlParser(stream) parser._listeners = [STLParserErrorListener()] ctx = parser.specification_file() # Create the visitor for the actual spec nodes visitor = STLSpecificationParser(self) self.top = visitor.visitSpecification_file(ctx) # print('Hello') # print(self.unit) # print('sampling period unit: ' + str(self.sampling_period_unit)) # print(self.U[self.unit]) # print(self.U[self.sampling_period_unit]) self.normalize = float(self.U[self.unit]) / float( self.U[self.sampling_period_unit])
def import_module(self, from_name, module_name): try: module = importlib.import_module(from_name) self.modules[module_name] = module except ImportError: raise STLParseException( 'The module {} cannot be loaded'.format(from_name))
def declare_const(self, const_name, const_type, const_val): if const_name in self.vars: raise STLParseException( 'Constant {} already declared'.format(const_name)) self.const_type_dict[const_name] = const_type self.const_val_dict[const_name] = const_val self.vars.add(const_name)
def op_cpp(self, op): if op == CompOp.GEQ: return StlComparisonOperator.GEQ elif op == CompOp.GREATER: return StlComparisonOperator.GREATER elif op == CompOp.LEQ: return StlComparisonOperator.LEQ elif op == CompOp.LESS: return StlComparisonOperator.LESS elif op == CompOp.NEQ: return StlComparisonOperator.NEQ elif op == CompOp.EQUAL: return StlComparisonOperator.EQUAL else: raise STLParseException('Could not find operator {}!'.format(op))
def parse(self): if self.spec is None: raise STLParseException('STL specification if empty') # Parse the STL spec - ANTLR4 magic entire_spec = self.modular_spec + self.spec input_stream = InputStream(entire_spec) lexer = LtlLexer(input_stream) stream = CommonTokenStream(lexer) parser = LtlParser(stream) parser._listeners = [LTLParserErrorListener()] ctx = parser.specification_file() # Create the visitor for the actual spec nodes visitor = LTLSpecificationParser(self) self.top = visitor.visitSpecification_file(ctx)
def create_var_from_name(self, var_name): var = None var_type = self.var_type_dict[var_name] if var_type.encode('utf-8') == 'float'.encode('utf-8'): var = float() elif var_type.encode('utf-8') == 'int'.encode('utf-8'): var = int() elif var_type.encode('utf-8') == 'complex'.encode('utf-8'): var = complex() else: try: var_module = self.modules[var_type] class_ = getattr(var_module, var_type) var = class_() except KeyError: raise STLParseException( 'The type {} does not seem to be imported.'.format( var_type)) return var
def visitIntervalFloatTimeLiteral(self, ctx): text = ctx.literal().getText() out = Fraction(Decimal(text)) if ctx.unit() == None: # default time unit is seconds - conversion of the bound to ps unit = self.spec.unit else: unit = ctx.unit().getText() out = out * self.spec.U[unit] sp = Fraction(self.spec.get_sampling_period()) out = out / sp if out.numerator % out.denominator > 0: raise STLParseException( 'The STL operator bound must be a multiple of the sampling period' ) out = int(out / self.spec.sampling_period) return out
def reportAmbiguity(self, recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs): raise STLParseException("Ambiguity ERROR, " + str(configs))
def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e): raise STLParseException( str(line) + ":" + str(column) + ": Syntax ERROR, " + str(msg))
def reportContextSensitivity(self, recognizer, dfa, startIndex, stopIndex, prediction, configs): raise STLParseException("Context ERROR, " + str(configs))
def reportAttemptingFullContext(self, recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs): raise STLParseException("Attempting full context ERROR, " + str(configs))