1import lcapy.grammar as grammar 2from lcapy.parser import Parser 3 4 5class NetfileMixin(object): 6 7 def _init_parser(self, cpts): 8 self.parser = Parser(cpts, grammar) 9 self.namespace = '' 10 self._anon = {} 11 12 def _make_anon(self, kind): 13 """Make identifier for anonymous component""" 14 15 if kind not in self._anon: 16 self._anon[kind] = 0 17 self._anon[kind] += 1 18 return 'anon' + str(self._anon[kind]) 19 20 def _include(self, string): 21 22 parts = string.split(' ') 23 if len(parts) < 2 or parts[0] != '.include': 24 raise ValueError('Expecting include filename in %s' % string) 25 filename = parts[1] 26 if len(parts) == 2: 27 return self._netfile_add(filename, self.namespace) 28 29 if len(parts) != 4 and parts[2] != 'as': 30 raise ValueError('Expecting include filename as name in %s' % string) 31 name = parts[3] 32 namespace = self.namespace 33 self.namespace = name + '.' + namespace 34 ret = self._netfile_add(filename, self.namespace) 35 self.namespace = namespace 36 return ret 37 38 def _parse(self, string, namespace=''): 39 """The general form is: 'Name Np Nm symbol' 40 where Np is the positive node and Nm is the negative node. 41 42 A positive current is defined to flow from the positive node 43 to the negative node. 44 """ 45 46 if string == '': 47 return None 48 49 if string[0] == ';': 50 if hasattr(self, 'opts'): 51 self.opts.add(string[1:]) 52 return None 53 54 if string[0:9] == '.include ': 55 self._include(string) 56 return None 57 58 cpt = self.parser.parse(namespace + string, self) 59 return cpt 60 61 def add(self, string): 62 """Add a component to the netlist. 63 The general form is: 'Name Np Nm args' 64 where Np is the positive node and Nm is the negative node. 65 66 A positive current is defined to flow from the positive node 67 to the negative node. 68 """ 69 70 self._add(string) 71 self._invalidate() 72 73 def _add(self, string, namespace=''): 74 """The general form is: 'Name Np Nm symbol' 75 where Np is the positive node and Nm is the negative node. 76 77 A positive current is defined to flow from the positive node 78 to the negative node. 79 """ 80 81 if '\n' in string: 82 lines = string.split('\n') 83 for line in lines: 84 self._add(line.strip(), namespace) 85 return 86 87 cpt = self._parse(string, namespace) 88 if cpt is not None: 89 self._cpt_add(cpt) 90 91 def _netfile_add(self, filename, namespace=''): 92 """Add the nets from file with specified filename""" 93 94 file = open(filename, 'r') 95 96 lines = file.readlines() 97 98 for line in lines: 99 self._add(line, namespace) 100