Skip to content

Commit

Permalink
Move code from __init__ to main_parser.py
Browse files Browse the repository at this point in the history
Actually, parse_io is quite close to a yet another parser which just
calls other parsers. So let's implement parse_io as as MainParser, which
is called a single time from gmshparser.parse.
  • Loading branch information
ahojukka5 committed May 9, 2020
1 parent f376523 commit eeba2c6
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 33 deletions.
3 changes: 3 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ function `parse`, which is responsible of parsing a section.
.. autoclass:: gmshparser.abstract_parser.AbstractParser
:members:

.. autoclass:: gmshparser.main_parser.MainParser
:members:

.. autoclass:: gmshparser.mesh_format_parser.MeshFormatParser
:members:

Expand Down
40 changes: 7 additions & 33 deletions gmshparser/__init__.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,12 @@
from typing import TextIO
from .mesh import Mesh
from .mesh_format_parser import MeshFormatParser
from .nodes_parser import NodesParser
from .elements_parser import ElementsParser


DEFAULT_PARSERS = {
"$MeshFormat": MeshFormatParser,
"$Nodes": NodesParser,
"$Elements": ElementsParser,
}


def parse_io(io: TextIO, mesh=Mesh(), parsers=DEFAULT_PARSERS) -> Mesh:
"""Parse input stream using `parsers` to `mesh` object. """
for line in io:
line = line.strip()
if not line.startswith("$"):
continue
if line.startswith("$End"):
continue
if line not in parsers:
continue
try:
parsers[line]().parse(mesh, io)
except Exception:
print("Unable to parse section %s from mesh!" % line)
raise
return mesh
from .main_parser import MainParser


def parse(filename: str) -> Mesh:
"""Parse Gmsh .msh file and return `Mesh` object."""
with open(filename, "r") as fid:
mesh = parse_io(fid)
mesh.set_name(filename)
return mesh
mesh = Mesh()
mesh.set_name(filename)
parser = MainParser()
with open(filename, "r") as io:
parser.parse(mesh, io)
return mesh
32 changes: 32 additions & 0 deletions gmshparser/main_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from typing import TextIO
from .mesh import Mesh
from .mesh_format_parser import MeshFormatParser
from .nodes_parser import NodesParser
from .elements_parser import ElementsParser
from .abstract_parser import AbstractParser


DEFAULT_PARSERS = [
MeshFormatParser,
NodesParser,
ElementsParser,
]


class MainParser(AbstractParser):

""" The main parser class, using other parsers. """

def __init__(self, parsers=DEFAULT_PARSERS):
self.parsers = parsers

def parse(self, mesh: Mesh, io: TextIO) -> None:
for line in io:
line = line.strip()
for parser in self.parsers:
if parser.get_section_name() == line:
try:
parser.parse(mesh, io)
except Exception:
print("Unable to parse section %s from mesh!" % line)
raise
2 changes: 2 additions & 0 deletions tests/test_abstract_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@


def test_abstract_parser():
with pytest.raises(NotImplementedError):
AbstractParser.get_section_name()
p = AbstractParser()
with pytest.raises(NotImplementedError):
p.parse(1, 2)
39 changes: 39 additions & 0 deletions tests/test_main_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from gmshparser import MainParser
from gmshparser.mesh import Mesh
from io import StringIO
from pytest import raises


__content__ = StringIO("""
$MeshFormat
4.1 0 8
$EndMeshFormat
$Unknown
my custom data
$EndUnknown
""")


__bad_content__ = StringIO("""
$MeshFormat
4.1 0 8 MSH4.1, ASCII
$EndMeshFormat
$Nodes
1 6 1 6 1 entity bloc, 6 nodes total, min/max node tags: 1 and 6
2 1 0 6 2D entity (surface) 1, no parametric coordinates, 6 nodes
$EndNodes
""".strip())


def test_mainparser():
parser = MainParser()
mesh = Mesh()
parser.parse(mesh, __content__)
assert mesh.get_version() == 4.1


def test_parse_io_bad_content():
parser = MainParser()
mesh = Mesh()
with raises(Exception):
parser.parse(mesh, __bad_content__)

0 comments on commit eeba2c6

Please sign in to comment.