diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2017-12-07 23:48:02 +0100 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2017-12-07 23:48:02 +0100 |
commit | efe5d835eaa26d8696c3352c4e1ed42da16fe27b (patch) | |
tree | d91a0273618e274278da77d01a20c183320f0940 /src/ee/kicad | |
parent | 1fba999bec5a589e4785594fb1a6fbfab9129097 (diff) | |
download | ee-python-efe5d835eaa26d8696c3352c4e1ed42da16fe27b.tar.gz ee-python-efe5d835eaa26d8696c3352c4e1ed42da16fe27b.tar.bz2 ee-python-efe5d835eaa26d8696c3352c4e1ed42da16fe27b.tar.xz ee-python-efe5d835eaa26d8696c3352c4e1ed42da16fe27b.zip |
wip
Diffstat (limited to 'src/ee/kicad')
-rw-r--r-- | src/ee/kicad/__init__.py | 2 | ||||
-rw-r--r-- | src/ee/kicad/pcb/__init__.py | 128 | ||||
-rw-r--r-- | src/ee/kicad/sexpr/__init__.py (renamed from src/ee/kicad/_parse_kicad_pcb.py) | 51 |
3 files changed, 142 insertions, 39 deletions
diff --git a/src/ee/kicad/__init__.py b/src/ee/kicad/__init__.py index efc20a2..8d5acd1 100644 --- a/src/ee/kicad/__init__.py +++ b/src/ee/kicad/__init__.py @@ -4,12 +4,10 @@ from ee import EeException from ee.kicad.read_schematic import read_schematic, read_schematics from ee.kicad.to_bom import to_bom, to_bom_xml from .model import * -from ._parse_kicad_pcb import parse_kicad_pcb __all__ = [ "Component", "ComponentField", - "parse_kicad_pcb", "Position", "read_schematic", "read_schematics", diff --git a/src/ee/kicad/pcb/__init__.py b/src/ee/kicad/pcb/__init__.py new file mode 100644 index 0000000..bfd352f --- /dev/null +++ b/src/ee/kicad/pcb/__init__.py @@ -0,0 +1,128 @@ +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 diff --git a/src/ee/kicad/_parse_kicad_pcb.py b/src/ee/kicad/sexpr/__init__.py index 5ea4d1b..a8604dc 100644 --- a/src/ee/kicad/_parse_kicad_pcb.py +++ b/src/ee/kicad/sexpr/__init__.py @@ -17,7 +17,15 @@ def state_to_str(s): return "EVENT_TEXT" return "UNKNOWN STATE" -def parse_kicad_pcb(path): +def logging_parser(parser): + for (event, token) in parser: + if token: + print("SEXPR: event={}, token={}".format(state_to_str(event), token or "")) + else: + print("SEXPR: event={}".format(state_to_str(event))) + yield (event, token) + +def parse(path): class state(object): def __init__(self): self.f = open(path, "r")#, 128 * 1024) @@ -37,32 +45,17 @@ def parse_kicad_pcb(path): # TODO: count lines and characters if self.buffer: c = self.buffer[0] - while c == '\n': - del self.buffer[0] - c = self.buffer[0] - return c - - c = self.f.read(1024) - if not c: + del self.buffer[0] return c - self.buffer.extend(c) - return self._read_c() - -# if self.buffer: -# c = self.buffer[0] -# del self.buffer[0] -# return c -# -# c = self.f.read(1) -# while c and c == '\n': -# c = self.f.read(1) -# return c + c = self.f.read(1) + while c and c == '\n': + c = self.f.read(1) + return c def _unread(self, s): for c in s: self.buffer.append(c) -# print("unreading: '{}', buffer={}".format(s, str(self.buffer))) def _read_token(self): s = "" @@ -101,13 +94,11 @@ def parse_kicad_pcb(path): def next(self): s = self.state -# print("next: current state={}, buffer={}".format(self.state_to_str(s), self.buffer)) self._text = None if s == EVENT_END: raise Exception("Invalid state, state=END") token = self._read_token() -# print("token={}".format(token)) if token is None: self.state = EVENT_END @@ -130,17 +121,3 @@ def parse_kicad_pcb(path): while event != EVENT_END: yield (event, token) (event, token) = s.next() - -#indent = 0 -#for (event_type, text) in parse_kicad_pcb("alpha.kicad_pcb"): -# if event_type == EVENT_LPAREN: -# prefix = " " * indent -# indent = indent + 1 -# print(prefix + "(") -# elif event_type == EVENT_RPAREN: -# indent = indent - 1 -# prefix = " " * indent -# print(prefix + ")") -# elif event_type == EVENT_TEXT: -# prefix = " " * indent -# print("{}{}".format(prefix, text)) |