aboutsummaryrefslogtreecommitdiff
path: root/src/ee/kicad
diff options
context:
space:
mode:
Diffstat (limited to 'src/ee/kicad')
-rw-r--r--src/ee/kicad/__init__.py2
-rw-r--r--src/ee/kicad/pcb/__init__.py128
-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))