Re: Parser stl et regexp

Pàgina inicial

Reply to this message
Autor: Jérémy Bobbio
Data:  
A: guilde
Assumpte: Re: Parser stl et regexp
Frédéric:
> Petite questions aux guru regexp...
>
> Je voudrais parser un fichier stl. […]


Pourquoi vouloir se limiter aux regexp ? Il existe plein de
bibliothèques bien plus intéressantes pour écrire ce genre de chose.

Tu disais bosser en Python, alors j'ai pris une demi-heure pour jouer
avec pyparsing, ça donne ça :

--- 8< ---
from pyparsing import (Literal, CaselessLiteral, Word, Optional, OneOrMore,
                       LineEnd, Combine, Group, nums, alphas)


point = Literal(".")
e = CaselessLiteral("E")
fnumber = Combine(Word("+-" + nums, nums) +
                  Optional(point + Optional(Word(nums))) +
                  Optional(e + Word("+-" + nums, nums)))
ident = Word(alphas + nums + "_")


class Vertex:
    def __init__(self, coords):
        self.x, self.y, self.z = map(float, coords)
    def __repr__(self):
        return "V(%f, %f, %f)" % (self.x, self.y, self.z)
def make_vertex(coords):
    return Vertex(coords)


class OuterLoop:
    def __init__(self, vertices):
        self.vertices = vertices
    def __repr__(self):
        return "OuterLoop(%s)" % self.vertices
def make_outer_loop(vertices):
    return OuterLoop(vertices)


vertex = (Literal("vertex").suppress() +
          fnumber + fnumber + fnumber +
          LineEnd().suppress()).setParseAction(make_vertex)
outer_loop = (Literal("outer").suppress() + Literal("loop").suppress() + LineEnd().suppress() +
              vertex + vertex + vertex +
              Literal("endloop").suppress() + LineEnd().suppress()).setParseAction(make_outer_loop)
facet = Group(Literal("facet") +
              Word(alphas) +
              fnumber + fnumber + fnumber +
              LineEnd().suppress() +
              outer_loop +
              Literal("endfacet").suppress() + LineEnd().suppress())
solid = (Literal("solid") + ident + LineEnd().suppress() +
         OneOrMore(facet) +
         Literal("endsolid").suppress() + ident.suppress() + LineEnd().suppress())


import sys
print solid.parseString(sys.stdin.read())
--- >8 ---

$ python parse.py < stl
['solid', '_40x10',
 ['facet', 'normal', '0.000000E+000', '0.000000E+000', '1.000000E+000',
  OuterLoop([V(12.868030, 29.579900, 12.000000),
             V(11.736480, 29.848080, 12.000000),
             V(11.157150, 29.530010, 12.000000)])],
 ['facet', 'normal', '0.000000E+000', '0.000000E+000', '1.000000E+000',
  OuterLoop([V(11.157150, 29.530010, 12.000000),
             V(11.736480, 29.848080, 12.000000),
             V(10.581450, 29.983080, 12.000000)]])]]




Je ne suis pas allé très loin dans la transformation de l'arbre en
objets utilisables et sûrement que le parser est très incomplet par
rapport au langage, mais l'idée est là. Je connais pas bien la
bibliothèque, alors c'est possible que ce soit possible de faire ça plus
joliement…

-- 
Jérémy Bobbio                        .''`. 
lunar@???                    : :Ⓐ  :  # apt-get install anarchism
                                    `. `'` 
                                      `-