60 lines
2.2 KiB
Python
60 lines
2.2 KiB
Python
import re, sys, json
|
|
def tokenize(s):
|
|
tok=[]; i=0; n=len(s)
|
|
while i<n:
|
|
c=s[i]
|
|
if c.isspace(): i+=1; continue
|
|
if c=='(' or c==')': tok.append(c); i+=1; continue
|
|
if c=='"':
|
|
j=i+1; buf=[]
|
|
while j<n:
|
|
if s[j]=='\\' and j+1<n: buf.append(s[j+1]); j+=2; continue
|
|
if s[j]=='"': break
|
|
buf.append(s[j]); j+=1
|
|
tok.append(('STR',''.join(buf))); i=j+1; continue
|
|
j=i
|
|
while j<n and not s[j].isspace() and s[j] not in '()': j+=1
|
|
tok.append(('SYM',s[i:j])); i=j
|
|
return tok
|
|
def parse(tok):
|
|
stack=[[]]
|
|
for t in tok:
|
|
if t=='(': stack.append([])
|
|
elif t==')': l=stack.pop(); stack[-1].append(l)
|
|
else: stack[-1].append(t[1])
|
|
return stack[0][0]
|
|
def find(node, key):
|
|
return [x for x in node if isinstance(x,list) and x and x[0]==key]
|
|
def first(node,key,default=None):
|
|
f=find(node,key); return f[0] if f else default
|
|
def load(path):
|
|
tree=parse(tokenize(open(path).read()))
|
|
comps={}
|
|
for c in find(first(tree,'components'),'comp'):
|
|
ref=first(c,'ref')[1]; val=first(c,'value',[None,''])[1]; fp=first(c,'footprint',[None,''])[1]
|
|
fields={}
|
|
fl=first(c,'fields')
|
|
if fl:
|
|
for f in find(fl,'field'):
|
|
nm=first(f,'name')[1]; fields[nm]=f[2] if len(f)>2 and isinstance(f[2],str) else ''
|
|
props={}
|
|
for p in find(c,'property'):
|
|
nm=first(p,'name')[1]; v=first(p,'value'); props[nm]=v[1] if v else ''
|
|
comps[ref]=dict(value=val, fp=fp, fields=fields, props=props, dnp=bool(find(c,'dnp')) or props.get('dnp') is not None)
|
|
nets={}
|
|
for nt in find(first(tree,'nets'),'net'):
|
|
name=first(nt,'name')[1]
|
|
nodes=[]
|
|
for nd in find(nt,'node'):
|
|
ref=first(nd,'ref')[1]; pin=first(nd,'pin')[1]; pf=first(nd,'pinfunction',[None,''])[1]; pt=first(nd,'pintype',[None,''])[1]
|
|
nodes.append((ref,pin,pf,pt))
|
|
nets[name]=nodes
|
|
# pin->net map
|
|
pinnet={}
|
|
for name,nodes in nets.items():
|
|
for ref,pin,pf,pt in nodes: pinnet[(ref,pin)]=name
|
|
return comps,nets,pinnet
|
|
if __name__=="__main__":
|
|
comps,nets,pinnet=load(sys.argv[1])
|
|
print(len(comps),"components,",len(nets),"nets")
|