From 32c489c957fc27d47bdb21eef6d7c971fe7fd0a3 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Sun, 8 Jan 2023 16:44:05 +0100 Subject: [PATCH] basic LL(1) parser for ASCII STL converter --- converters.py | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 converters.py diff --git a/converters.py b/converters.py new file mode 100644 index 0000000..d2e760e --- /dev/null +++ b/converters.py @@ -0,0 +1,95 @@ + +with open("humanoid.stl", "r") as fp: + stl = fp.read() + +#--- + +class Lexer: + def __init__(self, data): + assert(data.startswith("solid")) + self.data = data + self.pos = min(80, data.index("\n")) + + def lex(self): + # Skip leading whitespace + while self.pos < len(self.data) and self.data[self.pos] in " \t\n": + self.pos += 1 + + if self.pos >= len(self.data): + return None + + # Grab a word + i = self.pos + while i < len(self.data) and self.data[i] not in " \t\n": + i += 1 + word = self.data[self.pos:i] + + self.pos = i + return float(word) if word[0] in "+-0123456789." else word + +#--- + +class Parser: + def __init__(self, lexer): + self.lexer = lexer + self.la = "" # look-ahead token + self.feed() + + def at_end(self): + return self.la == None + + def feed(self): + t = self.la + self.la = lexer.lex() + return t + + def expect_keyword(self, keyword): + assert self.la == keyword + self.feed() + + def expect_float(self): + assert isinstance(self.la, float) + return self.feed() + + #--- + + def vec3(self, leading_keyword): + self.expect_keyword(leading_keyword) + x = self.expect_float() + y = self.expect_float() + z = self.expect_float() + return (x, y, z) + + def outer_loop(self): + self.expect_keyword("outer") + self.expect_keyword("loop") + v1 = self.vec3("vertex") + v2 = self.vec3("vertex") + v3 = self.vec3("vertex") + self.expect_keyword("endloop") + return [v1, v2, v3] + + def facet(self): + self.expect_keyword("facet") + normal = self.vec3("normal") + vertices = self.outer_loop() + self.expect_keyword("endfacet") + return {"normal": normal, "vertices": vertices} + + def solid(self): + facets = [] + while self.la == "facet": + facets.append(self.facet()) + self.expect_keyword("endsolid") + self.feed() + assert self.at_end() + return facets + +#--- + +lexer = Lexer(stl) +parser = Parser(lexer) + +solid = parser.solid() +from pprint import pprint +pprint(solid, width=90)