from .. import sexpr def auto_str(cls): def __str__(self): return str({k: [str(x) for x in v] if isinstance(v, list) else str(v) for k, v in vars(self).items()}) cls.__str__ = __str__ return cls @auto_str class KicadPcb(object): def __init__(self, **kwargs): for k, v in kwargs.items(): setattr(self, k, v) @auto_str class General(object): def __init__(self, **kwargs): for k, v in kwargs.items(): setattr(self, k, v) @auto_str class Module(object): def __init__(self, **kwargs): for k, v in kwargs.items(): setattr(self, k, v) def parse(path): count = 0 p = sexpr.parse(path) p = sexpr.logging_parser(p) (event, token) = next(p) assert event == sexpr.EVENT_LPAREN (event, token) = next(p) assert event == sexpr.EVENT_TEXT and token == "kicad_pcb" idx = 0 def _consume(): nonlocal idx idx = idx + 1 # print("consume: idx={}".format(idx)) (event, token) = next(p) # print("consume: event={}".format(event)) while event != sexpr.EVENT_RPAREN: if event == sexpr.EVENT_LPAREN: _consume() elif event == sexpr.EVENT_TEXT: pass (event, token) = next(p) # print("consume: event={}".format(event)) # print("consume: done".format()) idx = idx - 1 def _parse_kicad_pcb(): modules = [] args = {"modules": modules} (event, token) = next(p) while event == sexpr.EVENT_LPAREN: (event, token) = next(p) if token == "version": args[token] = _parse_text(rparen = True) elif token == "general": args[token] = _parse_general() elif token == "module": modules.append(_parse_module()) else: _consume() (event, token) = next(p) return KicadPcb(**args) def _parse_text(optional = False, rparen = False): (event, token) = next(p) if not optional: assert event == sexpr.EVENT_TEXT else: assert event == sexpr.EVENT_TEXT or event == sexpr.EVENT_RPAREN if event == sexpr.EVENT_RPAREN: return None text = token if rparen: (event, token) = next(p) assert event == sexpr.EVENT_RPAREN return text def _parse_general(): args = {} (event, token) = next(p) while event == sexpr.EVENT_LPAREN: (event, token) = next(p) if token == "no_connects": args[token] =_parse_text(rparen = True) elif token == "area": args[token] = (_parse_text(), _parse_text(), _parse_text(), _parse_text(rparen = True)) elif token == "thickness": args[token] = _parse_text(rparen = True) else: _consume() (event, token) = next(p) return General(**args) def _parse_module(): args = {} args["footprint"] = _parse_text() (event, token) = next(p) while event == sexpr.EVENT_LPAREN: (event, token) = next(p) if token == "layer": args[token] = _parse_text(rparen = True) elif token == "at": x = _parse_text() y = _parse_text() rot = _parse_text(optional = True, rparen = True) args[token] = (x, y, rot or 0) else: _consume() (event, token) = next(p) return Module(**args) kicad_pcb = _parse_kicad_pcb() # (event, token) = next(p) # assert event == sexpr.EVENT_END return kicad_pcb