Le code pour la présentation du 7 mai sur Sly et Numba.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

107 lines
2.4 KiB

import pprint
from dataclasses import dataclass
from typing import List, Tuple
from sly import Lexer, Parser
@dataclass
class Vertex:
coords: Tuple[float, float, float]
def __repr__(self):
return "VERTEX(%f,%f,%f)" % self.coords
@dataclass
class Facet:
vertices: Tuple[Vertex, Vertex, Vertex]
normal: Vertex
def __repr__(self):
return "\t FACET({normal})\n\t\t{vertices}".format(
normal=repr(self.normal),
vertices="\n\t\t".join(repr(vertex) for vertex in self.vertices)
)
@dataclass
class Solid:
name: str
facets: List[Facet]
def __repr__(self):
return "SOLID({name})\n{facets}\n".format(
name=self.name,
facets="\n".join(repr(facet) for facet in self.facets)
)
class STLLexer(Lexer):
tokens = {"SOLID_START", "SOLID_END",
"FACET_START", "FACET_END", "NAME_LITERAL",
"LOOP_START", "LOOP_END",
"NAME_LITERAL", "VERTEX_TAG", "FLOAT"}
@_(r"[ \t\n]+")
def ignore_whitespace(self, t):
self.lineno += t.value.count("\n")
SOLID_START = r"solid"
SOLID_END = r"endsolid"
FACET_START = r"facet normal"
FACET_END = r"endfacet"
LOOP_START = r"outer loop"
LOOP_END = r"endloop"
VERTEX_TAG = r"vertex"
@_("[+-]?\d+(\.\d*(e[+-]?\d+)?)?")
def FLOAT(self, t):
t.value = float(t.value)
return t
NAME_LITERAL = r"\w+"
class STLParser(Parser):
tokens = STLLexer.tokens
start = "stl"
@_("solid")
def stl(self, p):
return p.solid
@_("SOLID_START NAME_LITERAL { facet } SOLID_END")
@_("SOLID_START NAME_LITERAL { facet } SOLID_END NAME_LITERAL")
def solid(self, p):
return Solid(name=p[1], facets=p.facet)
@_("FACET_START triplet loop FACET_END")
def facet(self, p):
return Facet(vertices=p.loop, normal=Vertex(p.triplet))
@_("LOOP_START vertex vertex vertex LOOP_END")
def loop(self, p):
return p[1], p[2], p[3]
@_("VERTEX_TAG triplet")
def vertex(self, p):
return Vertex(p.triplet)
@_("FLOAT FLOAT FLOAT")
def triplet(self, p):
return p[0], p[1], p[2]
def error(self, token):
pass
if __name__ == "__main__":
lexer = STLLexer()
parser = STLParser()
with open("star.stl") as stl_file:
# pprint.pprint(list(lexer.tokenize(stl_file.read())))
solid = parser.parse(lexer.tokenize(stl_file.read()))
print(solid)