1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4# 5# Copyright 2017, Data61 6# Commonwealth Scientific and Industrial Research Organisation (CSIRO) 7# ABN 41 687 119 230. 8# 9# This software may be distributed and modified according to the terms of 10# the BSD 2-Clause license. Note that NO WARRANTY is provided. 11# See "LICENSE_BSD2.txt" for details. 12# 13# @TAG(DATA61_BSD) 14# 15 16''' 17Stage 5 parser. The following parser is designed to accept a stage 4 parser, 18whose output it consumes. This parser's purpose is to remove Groups from the 19lifted AST, adding their implied information as the address space of component 20instances. 21''' 22 23from __future__ import absolute_import, division, print_function, \ 24 unicode_literals 25from camkes.internal.seven import cmp, filter, map, zip 26 27from .base import Transformer 28from camkes.ast import Composition, Group, Instance, Reference, TraversalAction 29 30def precondition(ast_lifted): 31 ''' 32 Precondition of this transformation. At this point, no references should be 33 left in the AST. 34 ''' 35 return all(not isinstance(x, Reference) for x in ast_lifted) 36 37def postcondition(ast_lifted): 38 ''' 39 Postcondition of this transformation. Afterwards, no groups should remain 40 and every instance should have an assigned address space. 41 ''' 42 return all(not isinstance(x, Group) and 43 (not isinstance(x, Instance) or x.address_space is not None) for 44 x in ast_lifted) 45 46def collapse_groups(ast_lifted): 47 class Collapser(TraversalAction): 48 def __init__(self): 49 self.counter = 0 50 def __call__(self, item): 51 if isinstance(item, Composition): 52 # Remove the groups which should have all been resolved. 53 [item.instances.extend(g.instances) for g in item.groups] 54 item.groups = [] 55 item.claim_children() 56 elif isinstance(item, Group): 57 # Assign an address space to all instances in this group. 58 if item.name is None: 59 name = 'unamed_group_%d' % self.counter 60 self.counter += 1 61 else: 62 name = item.name 63 for i in item.instances: 64 i.address_space = name 65 return item 66 67 c = Collapser() 68 ast_lifted.postorder(c) 69 70 return ast_lifted 71 72class Parse5(Transformer): 73 def precondition(self, ast_lifted, _): 74 return precondition(ast_lifted) 75 76 def postcondition(self, ast_lifted, _): 77 return postcondition(ast_lifted) 78 79 def transform(self, ast_lifted, read): 80 return collapse_groups(ast_lifted), read 81