Exemple #1
0
    def parse_and_calculate_constants(self):
        self.lex = lexer.lexer
        try:
            self.pars = parser.Parser(self.nta.declaration, self.lex)
        except Exception:
            opaal.util.emergencyExitUppaalCParser(
                "Error in parsing the model to calculation constants.")
        self.declvisitor = parser.DeclVisitor(self.pars)
        self.declvisitor.visit(self.pars.AST)

        self.constants = {}
        #constant overrides
        for (cident, cval) in self.constant_overrides.iteritems():
            #XXX assumes expression is already python
            self.constants[cident] = eval(cval, {}, self.constants)
        #evaluate constants to values
        for (cident, cval) in self.declvisitor.constants.iteritems():
            if not cident in self.constants:
                self.constants[cident] = eval(util.expression_to_python(cval),
                                              {}, self.constants)

        try:
            #evaluate VarDecl expressions
            for vdecl in self.declvisitor.variables:
                util.eval_vardecl_expressions(vdecl, self.constants)
        except Exception:
            opaal.util.emergencyExitUppaalCParser(
                "Error in evaluating variable properties (e.g. array dimensions), for '%s'."
                % (vdecl.identifier))
Exemple #2
0
    def test_parse_extern_dbm(self):
        test_file = open(os.path.join(os.path.dirname(__file__), 'test_extern_dbm.txt'), "r")

        lex = lexer.lexer
        pars = parser.Parser(test_file.read(), lex)
        res = pars.AST.children

        #pars.AST.visit()

        declvisitor = parser.DeclVisitor(pars)
        #print declvisitor.variables

        self.assertEqual(len(declvisitor.variables), 5)

        self.assertEqual(declvisitor.variables[0], ('dbm', 'DBMFederation', [], None))
        self.assertEqual(declvisitor.variables[1], ('dbm.x', 'DBMClock', [], None))
        self.assertEqual(declvisitor.variables[2], ('dbm.c', 'DBMClock', [], None))
        self.assertEqual(declvisitor.variables[3][0], 'dbm.y') #('dbm.y', 'DBMClock', [10])
        self.assertEqual(declvisitor.variables[3][1], 'DBMClock')
        self.assertEqual(len(declvisitor.variables[3][2]), 1)
        self.assertEqual(declvisitor.variables[3][2][0].children[0].leaf, 10)
        self.assertEqual(declvisitor.variables[4][0], 'dbm.z') #('dbm.z', 'DBMClock', [10, 20])
        self.assertEqual(declvisitor.variables[4][1], 'DBMClock')
        self.assertEqual(len(declvisitor.variables[4][2]), 2)
        self.assertEqual(declvisitor.variables[4][2][0].children[0].leaf, 10)
        self.assertEqual(declvisitor.variables[4][2][1].children[0].leaf, 20)
Exemple #3
0
    def add_template_promote_local_vars(self, nta, temp):
        """Add the template @temp to the nta @nta, promoting local variables
        to uniquely named global variables in the process."""
        lex = lexer.lexer
        try:
            pars = parser.Parser(temp.declaration, lex, typedefDict=self.pars.typedefDict)
        except Exception:
            opaal.util.emergencyExitUppaalCParser("Error parsing template declarations.")

        declvisitor = parser.DeclVisitor(pars)
        declvisitor.visit(pars.AST)

        for (c, _) in declvisitor.clocks:
            newident = "%s_%s" % (temp.name, c)
            assert declvisitor.get_type(newident) == None
            self.rename_var_in_temp(temp, c, newident)
        for (varname, _, _, _) in declvisitor.variables:
            newident = "%s_%s" % (temp.name, varname)
            assert declvisitor.get_type(newident) == None
            self.rename_var_in_temp(temp, varname, newident)
        for const in declvisitor.constants:
            newident = "%s_%s" % (temp.name, const)
            assert declvisitor.get_type(newident) == None
            self.rename_var_in_temp(temp, const, newident)
        for func_ast in declvisitor.functions:
            oldident = func_ast.leaf[1].children[0]
            newident = "%s_%s" % (temp.name, oldident)
            assert declvisitor.get_type(newident) == None
            self.rename_var_in_temp(temp, oldident, newident)

        nta.declaration += "\n/******** Declarations for %s ********/\n%s\n" % (temp.name, temp.declaration)
        temp.declaration = ""
        nta.templates += [temp]
Exemple #4
0
    def test_parse_extern3(self):
        test_file = open(os.path.join(os.path.dirname(__file__), 'test_extern3.txt'), "r")

        lex = lexer.lexer
        pars = parser.Parser(test_file.read(), lex)
        res = pars.AST.children

        pars.AST.visit()

        declvisitor = parser.DeclVisitor(pars)

        self.assertTrue('WideningIntRange' in pars.externList)

        self.assertEqual(declvisitor.get_type('x'), 'WideningIntRange')

        wideningIntRangeTypeNode = pars.typedefDict['WideningIntRange']

        print "typedefdict:"
        wideningIntRangeTypeNode.visit()

        self.assertEqual(wideningIntRangeTypeNode.leaf.type, "Identifier")
        self.assertEqual(wideningIntRangeTypeNode.leaf.leaf, "WideningIntRange")
        
        self.assertEqual(len(wideningIntRangeTypeNode.children), 1)
        self.assertEqual(wideningIntRangeTypeNode.children[0].type, 'FunctionCall')
        parameters = wideningIntRangeTypeNode.children[0].leaf
        self.assertEqual(len(parameters), 4)
        self.assertEqual(parameters[0].leaf, 1)
        self.assertEqual(parameters[1].leaf, 2)
        self.assertEqual(parameters[2].leaf, 3)
        self.assertEqual(parameters[3].leaf, 9)
Exemple #5
0
    def test_parse_extern(self):
        test_file = open(os.path.join(os.path.dirname(__file__), 'test_extern.txt'), "r")

        lex = lexer.lexer
        pars = parser.Parser(test_file.read(), lex)
        res = pars.AST.children

        #pars.AST.visit()

        declvisitor = parser.DeclVisitor(pars)
Exemple #6
0
    def test_parse_declarations2(self):
        test_file = open(os.path.join(os.path.dirname(__file__), 'test_simple_declarations2.txt'), "r")

        lex = lexer.lexer
        pars = parser.Parser(test_file.read(), lex)
        res = pars.AST.children

        pars.AST.visit()

        declvisitor = parser.DeclVisitor(pars)

        self.assertEqual(res[7].type, 'VarDecl')
        self.assertEqual(res[7].leaf.type, 'TypeInt')
        self.assertEqual(res[7].children[0].type, 'Identifier')
        self.assertEqual(res[7].children[0].leaf, 'lalala')
        self.assertEqual(res[7].children[0].children[0].type, 'Assignment')
        self.assertEqual(res[7].children[0].children[0].leaf.type, 'Identifier')
        self.assertEqual(res[7].children[0].children[0].leaf.leaf, 'lalala')


        self.assertEqual(res[12].type, 'VarDecl')
        self.assertEqual(res[12].leaf.type, 'TypeBool')
        self.assertEqual(res[12].children[0].type, 'Identifier')
        self.assertEqual(res[12].children[0].leaf, 'msg')
        self.assertEqual(res[12].children[0].children[0].type, 'Index')
        self.assertEqual(res[12].children[0].children[1].type, 'Index')


        self.assertEqual(declvisitor.variables[0], ('L', 'TypeInt', [], 0))

        #self.assertEqual(declvisitor.variables[1], ('lalala', 'int', [], _))
        self.assertEqual(declvisitor.variables[1][0], 'lalala')
        self.assertEqual(declvisitor.variables[1][1], 'TypeInt')
        self.assertEqual(declvisitor.variables[1][2], [])
        self.assertEqual(declvisitor.variables[1][3].type, 'Expression')
        self.assertEqual(declvisitor.variables[1][3].children[0].type, 'Number')
        self.assertEqual(declvisitor.variables[1][3].children[0].leaf, 3)

        self.assertEqual(declvisitor.variables[3][0], 'lock')
        self.assertEqual(declvisitor.variables[3][1], 'TypeBool')
        self.assertEqual(declvisitor.variables[3][2], [])
        self.assertEqual(declvisitor.variables[3][3].type, 'Expression')
        self.assertEqual(declvisitor.variables[3][3].children[0].type, 'False')

        self.assertEqual(declvisitor.variables[4][0], 'lock2')
        self.assertEqual(declvisitor.variables[4][1], 'TypeBool')
        self.assertEqual(declvisitor.variables[4][2], [])
        self.assertEqual(declvisitor.variables[4][3].children[0].type, 'True')

        self.assertEqual(declvisitor.clocks, [('time', 10), ('y1', 10), ('y2', 10), ('y3', 10), ('y4', 10)])
        self.assertEqual(declvisitor.channels, [('take', []), ('release', [])])
Exemple #7
0
    def test_parse_constants(self):
        test_file = open(os.path.join(os.path.dirname(__file__), 'test_parse_constants.txt'), "r")

        lex = lexer.lexer
        pars = parser.Parser(test_file.read(), lex)
        res = pars.AST.children

        pars.AST.visit()

        declvisitor = parser.DeclVisitor(pars)

        inorder = ["a", "b", "c", "d"]
        #should return the constants in file order
        self.assertEqual(declvisitor.constants.keys(), inorder)
Exemple #8
0
    def test_parse_extern2(self):
        test_file = open(os.path.join(os.path.dirname(__file__), 'test_extern2.txt'), "r")

        lex = lexer.lexer
        pars = parser.Parser(test_file.read(), lex)
        res = pars.AST.children

        pars.AST.visit()

        declvisitor = parser.DeclVisitor(pars)

        self.assertTrue('TestExternalLattice' in pars.externList)

        self.assertEqual(declvisitor.get_type('mylat'), 'TestExternalLattice')
Exemple #9
0
 def parse_and_calculate_constants(self):
     self.lex = lexer.lexer
     try:
         self.pars = parser.Parser(self.nta.declaration, self.lex)
     except Exception:
         opaal.util.emergencyExitUppaalCParser("Error parsing the model for calculating constants.")
     self.declvisitor = parser.DeclVisitor(self.pars)
     self.declvisitor.visit(self.pars.AST)
     
     self.constants = {}
     #constant overrides
     for (cident, cval) in self.constant_overrides.iteritems():
         #XXX assumes expression is already python
         self.constants[cident] = eval(cval, {}, self.constants)
     #evaluate constants to values
     for (cident, cval) in self.declvisitor.constants.iteritems():
         if not cident in self.constants:
             self.constants[cident] = eval(util.expression_to_python(cval), {}, self.constants)
Exemple #10
0
    def test_parse_declarations(self):
        test_file = open(os.path.join(os.path.dirname(__file__), 'test_simple_declarations.txt'), "r")

        lex = lexer.lexer
        pars = parser.Parser(test_file.read(), lex)
        res = pars.AST.children

        #pars.AST.visit()

        declvisitor = parser.DeclVisitor(pars)

        self.assertEqual(declvisitor.variables, [('a', 'TypeInt', [], 0), ('b', 'TypeBool', [], False), ('b1', 'TypeBool', [], False), ('b2', 'TypeBool', [], False)])

        self.assertEqual(len(declvisitor.clocks), 1)
        self.assertEqual(declvisitor.clocks[0][0], 'c')

        self.assertEqual(declvisitor.channels, [('d', [])])
        self.assertEqual(declvisitor.urgent_channels, [('e', [])])
        self.assertEqual(declvisitor.broadcast_channels, [('f', [])])
        self.assertEqual(declvisitor.urgent_broadcast_channels, [('g', [])])
Exemple #11
0
    def test_parse_typedef(self):
        test_file = open(os.path.join(os.path.dirname(__file__), 'test_typedef.txt'), "r")
        lex = lexer.lexer
        pars = parser.Parser(test_file.read(), lex)
        pars.AST.visit()
        self.assertEqual(len(pars.AST.children), 8)

        self.assertEqual(len(pars.typedefDict), 4)
        self.assertTrue('myStructType' in pars.typedefDict)
        self.assertTrue('adr' in pars.typedefDict)
        self.assertTrue('DBMClock' in pars.typedefDict)
        self.assertTrue('clock' in pars.typedefDict)

        ctype = pars.typedefDict['clock']
        self.assertEqual(ctype.type, 'NodeTypedef')
        self.assertEqual(ctype.leaf, 'clock')
        self.assertEqual(len(ctype.children), 1)
        self.assertEqual(ctype.children[0], pars.typedefDict['DBMClock'])

        declvisitor = parser.DeclVisitor(pars)
        #XXX parses to deeply into structs!
        self.assertEqual(len(declvisitor.variables), 5)
        
        pars.AST.visit()
        print declvisitor.variables
        varnames = [x for (x, _, _, _) in declvisitor.variables]
        self.assertTrue('m' in varnames)
        self.assertTrue(('m', 'myStructType', [], None) in declvisitor.variables)
        self.assertTrue('n' in varnames)
        self.assertTrue(('n', 'adr', [], None) in declvisitor.variables)
        self.assertTrue('n2' in varnames)

        for (x, _, _, initval) in declvisitor.variables:
            if x == "n2":
                self.assertEqual(initval.type, "Expression")
                self.assertEqual(initval.children[0].type, "Number")
                self.assertEqual(initval.children[0].leaf, 3)

        self.assertTrue('c' in varnames)
        self.assertTrue(('c', 'DBMClock', [], None) in declvisitor.variables)
Exemple #12
0
    def __init__(self, model, constant_overrides=dict()):
        model = SimplifyModel(model, constant_overrides).simplify()

        self.model = model
        self.transitions = {}
        self.sync_transitions = {}
        self.dynamic_sync_transitions = {}
        self.templatename_to_idx = {}
        self.num_templates = len(self.model.templates)
        self.invariants = {}
        self.externs = {}

        self.analyzer = AnalyzeModel(model, constant_overrides)
        self.analyzer.analyze()

        #mapping from template => location id => nice name
        self.location_labels = defaultdict(dict)

        lex = lexer.lexer
        pars = parser.Parser(model.declaration, lex)

        declvisitor = parser.DeclVisitor(pars)
        declvisitor.visit(pars.AST)
        self.clocks = declvisitor.clocks

        self.constants = self.analyzer.constants

        #evaluate array dimensions to values
        self.variables = []
        for (vident, vtype, vdimensions, initval) in declvisitor.variables:
            for (dim, dim_idx) in zip(vdimensions, range(len(vdimensions))):
                vdimensions[dim_idx] = eval(util.expression_to_python(dim), {},
                                            self.constants)
            if initval:
                initval = eval(util.expression_to_python(initval), {},
                               self.constants)
            elif vtype not in ['DBMFederation', 'DBMClock']:
                initval = 0
            self.variables += [(vident, vtype, vdimensions, initval)]

        #evaluate channel array dimensions to values
        self.channels = []
        self.channel_identifiers = []

        def crossproduct(vdimensions):
            if len(vdimensions) == 1:
                for i in xrange(vdimensions[0]):
                    yield "[%d]" % i
            else:
                for i in xrange(vdimensions[0]):
                    for t in crossproduct(vdimensions[1:]):
                        yield ("[%d]" % i) + t

        for (vident, vdimensions) in declvisitor.channels:
            self.channel_identifiers += [vident]
            if len(vdimensions) == 0:
                self.channels += [vident]
                continue
            for (dim, dim_idx) in zip(vdimensions, range(len(vdimensions))):
                vdimensions[dim_idx] = eval(util.expression_to_python(dim), {},
                                            self.constants)
            for i in crossproduct(vdimensions):
                self.channels += [vident + i]

        #evaluate broadcast channel array dimensions to values
        self.broadcast_channels = []
        for (vident, vdimensions) in declvisitor.broadcast_channels:
            self.channel_identifiers += [vident]
            if len(vdimensions) == 0:
                self.broadcast_channels += [vident]
                continue
            for (dim, dim_idx) in zip(vdimensions, range(len(vdimensions))):
                vdimensions[dim_idx] = eval(util.expression_to_python(dim), {},
                                            self.constants)
            for i in crossproduct(vdimensions):
                self.broadcast_channels += [vident + i]

        #import needed externs
        for ex in pars.externList:
            self._loadExtern(ex, pars)

        logger.info("Constants: %s", self.constants)
        logger.info("Variables: %s", self.variables)
        logger.info("Clocks: %s", self.clocks)
        logger.info("Externs: %s", self.externs)
        logger.info("Typedefs: %s", pars.typedefDict)
        logger.info("Channels: %s", self.channels)
        logger.info("Broadcast Channels: %s", self.broadcast_channels)

        #Calculate invariants
        for (t, t_idx) in zip(self.model.templates,
                              range(len(self.model.templates))):
            self.invariants[t_idx] = {}
            for (loc, l_idx) in zip(t.locations, range(len(t.locations))):
                if (loc.invariant.value != None):
                    #the invariant should have the format:
                    # statement; ... ; statement; expression
                    #the statements are symbolic updates, while the
                    #expression is what determines if the invariant is satisfied
                    #example:
                    # dbm &= (dbm.x <= 5); not dbm.isEmpty()
                    #this should be backwards compatible.
                    s = loc.invariant.value.split(';')
                    statements = ";".join(s[:-1])
                    expression = util.expression_str_to_python(s[-1], self)
                    logger.debug("Invariant: '%s' ==> ('%s', '%s')",
                                 loc.invariant.value, statements, expression)

                    self.invariants[t_idx][l_idx] = (statements, expression)
                else:
                    self.invariants[t_idx][l_idx] = ("", "")

        #calculate transitions
        for (t, t_idx) in zip(self.model.templates,
                              range(len(self.model.templates))):
            self.transitions[t_idx] = {}
            self.sync_transitions[t_idx] = {}
            self.dynamic_sync_transitions[t_idx] = {}
            self.templatename_to_idx[t.name] = t_idx

            for (loc, l_idx) in zip(t.locations, range(len(t.locations))):
                if loc.name.get_value():
                    self.location_labels[t_idx][l_idx] = loc.name.get_value()

                self.transitions[t_idx][l_idx] = []
                self.sync_transitions[t_idx][l_idx] = {}
                self.dynamic_sync_transitions[t_idx][l_idx] = []
                for chan_name in self.channels:
                    self.sync_transitions[t_idx][l_idx][chan_name + "!"] = []
                    self.sync_transitions[t_idx][l_idx][chan_name + "?"] = []
                for chan_name in self.broadcast_channels:
                    self.sync_transitions[t_idx][l_idx][chan_name + "!"] = []
                    self.sync_transitions[t_idx][l_idx][chan_name + "?"] = []
                for tr in [tr for tr in t.transitions if tr.source == loc]:
                    target_idx = t.locations.index(tr.target)
                    debug_info = {}

                    guard_code = None
                    debug_info['guard_code'] = ''
                    if tr.guard.value != '':
                        logger.debug("Guard: %s", tr.guard.value)
                        logger.debug(
                            "==> %s",
                            util.expression_str_to_python(
                                tr.guard.value, self))
                        guard_code = compile(
                            util.expression_str_to_python(
                                tr.guard.value, self), "<guard>", 'eval')
                        debug_info['guard_code'] = tr.guard.value

                    update_code = None
                    debug_info['update_code'] = ''
                    if tr.assignment.value != '':
                        update_code = compile(
                            util.statement_str_to_python(tr.assignment.value),
                            "<update>", 'exec')
                        debug_info['update_code'] = tr.assignment.value

                    static_sync = False
                    sync_chan = None
                    sync_way = None
                    if tr.synchronisation.value != "":
                        logger.debug("Sync: %s", tr.synchronisation.value)
                        sync_way = tr.synchronisation.value.strip()[-1]
                        static_sync, sync_chan = util.channame_str_to_python_format_string(
                            tr.synchronisation.value.strip()[:-1], self)
                        sync_chan += sync_way
                        logger.debug("==> (%s, %s)", static_sync, sync_chan)

                    list_curtrans = [(target_idx, guard_code, update_code,
                                      sync_chan, debug_info)]

                    self.transitions[t_idx][l_idx] += list_curtrans

                    if static_sync:
                        self.sync_transitions[t_idx][l_idx][
                            sync_chan] += list_curtrans
                    else:
                        self.dynamic_sync_transitions[t_idx][
                            l_idx] += list_curtrans