Skip to content

parser

parser

GerberX3 format parser.

Parser

Gerber X3 parser object.

Source code in src/pygerber/gerberx3/parser/parser.py
class Parser:
    """Gerber X3 parser object."""

    def __init__(
        self,
        options: Optional[ParserOptions] = None,
    ) -> None:
        """Initialize parser.

        Parameters
        ----------
        options : ParserOptions | None
            Additional options for modifying parser behavior.
        """
        self.options = ParserOptions() if options is None else options

    @property
    def backend(self) -> Backend:
        """Get reference to backend object."""
        return self.options.backend

    def parse(self, tokens: TokenStack) -> DrawCommandsHandle:
        """Parse token stack."""
        for _ in self.parse_iter(tokens):
            pass

        return self.get_draw_commands_handle()

    def parse_iter(self, tokens: TokenStack) -> Generator[Token, None, None]:
        """Iterate over tokens in stack and parse them."""
        self.state = (
            State()
            if self.options.initial_state is None
            else self.options.initial_state
        )
        self.draw_actions: list[DrawCommand] = []

        for token in tokens:
            self._update_drawing_state(token)

            yield token

    def get_draw_commands_handle(self) -> DrawCommandsHandle:
        """Return handle to drawing commands."""
        return self.backend.get_draw_commands_handle_cls()(
            self.draw_actions,
            self.backend,
        )

    def _update_drawing_state(self, token: Token) -> None:
        try:
            self.state, actions = token.update_drawing_state(self.state, self.backend)
            if actions is not None:
                self.draw_actions.extend(actions)

        except ExitParsingProcessInterrupt:
            return

        except Exception as e:  # noqa: BLE001
            if self.options.on_update_drawing_state_error == ParserOnErrorAction.Ignore:
                pass

            elif (
                self.options.on_update_drawing_state_error == ParserOnErrorAction.Raise
            ):
                if not isinstance(e, ParserError):
                    raise OnUpdateDrawingStateError(token) from e

                raise

            elif self.options.on_update_drawing_state_error == ParserOnErrorAction.Warn:
                logging.warning(
                    "Encountered fatal error during call to update_drawing_state() "
                    "of '%s' token. Parser will skip this token and continue.",
                    token,
                )
            else:
                self.options.on_update_drawing_state_error(e, self, token)

backend property

backend: Backend

Get reference to backend object.

__init__

__init__(options: Optional[ParserOptions] = None) -> None

Initialize parser.

Parameters:

Name Type Description Default
options ParserOptions | None

Additional options for modifying parser behavior.

None
Source code in src/pygerber/gerberx3/parser/parser.py
def __init__(
    self,
    options: Optional[ParserOptions] = None,
) -> None:
    """Initialize parser.

    Parameters
    ----------
    options : ParserOptions | None
        Additional options for modifying parser behavior.
    """
    self.options = ParserOptions() if options is None else options

parse

parse(tokens: TokenStack) -> DrawCommandsHandle

Parse token stack.

Source code in src/pygerber/gerberx3/parser/parser.py
def parse(self, tokens: TokenStack) -> DrawCommandsHandle:
    """Parse token stack."""
    for _ in self.parse_iter(tokens):
        pass

    return self.get_draw_commands_handle()

parse_iter

parse_iter(
    tokens: TokenStack,
) -> Generator[Token, None, None]

Iterate over tokens in stack and parse them.

Source code in src/pygerber/gerberx3/parser/parser.py
def parse_iter(self, tokens: TokenStack) -> Generator[Token, None, None]:
    """Iterate over tokens in stack and parse them."""
    self.state = (
        State()
        if self.options.initial_state is None
        else self.options.initial_state
    )
    self.draw_actions: list[DrawCommand] = []

    for token in tokens:
        self._update_drawing_state(token)

        yield token

get_draw_commands_handle

get_draw_commands_handle() -> DrawCommandsHandle

Return handle to drawing commands.

Source code in src/pygerber/gerberx3/parser/parser.py
def get_draw_commands_handle(self) -> DrawCommandsHandle:
    """Return handle to drawing commands."""
    return self.backend.get_draw_commands_handle_cls()(
        self.draw_actions,
        self.backend,
    )

ParserOnErrorAction

Bases: Enum

Possible error actions.

Source code in src/pygerber/gerberx3/parser/parser.py
class ParserOnErrorAction(Enum):
    """Possible error actions."""

    Ignore = "ignore"
    """Ignore parser errors. Errors which occurred will not be signaled. May yield
    unexpected results for broken files, with missing draw commands or even more
    significant errors."""

    Warn = "warn"
    """Warn on parser error. Parser will log warning message about what went wrong.
    Best for supporting wide range of files without silently ignoring errors in code."""

    Raise = "raise"
    """Raise exception whenever parser encounters error. Will completely break out of
    parsing process, making it impossible to render slightly malformed files."""

Ignore class-attribute instance-attribute

Ignore = 'ignore'

Ignore parser errors. Errors which occurred will not be signaled. May yield unexpected results for broken files, with missing draw commands or even more significant errors.

Warn class-attribute instance-attribute

Warn = 'warn'

Warn on parser error. Parser will log warning message about what went wrong. Best for supporting wide range of files without silently ignoring errors in code.

Raise class-attribute instance-attribute

Raise = 'raise'

Raise exception whenever parser encounters error. Will completely break out of parsing process, making it impossible to render slightly malformed files.

ParserOptions

Container class for Gerber parser options.

Source code in src/pygerber/gerberx3/parser/parser.py
class ParserOptions:
    """Container class for Gerber parser options."""

    def __init__(
        self,
        backend: Backend | None = None,
        initial_state: State | None = None,
        on_update_drawing_state_error: Callable[[Exception, Parser, Token], None]
        | ParserOnErrorAction = ParserOnErrorAction.Raise,
    ) -> None:
        """Initialize options."""
        self.backend = Rasterized2DBackend() if backend is None else backend
        self.initial_state = initial_state
        self.on_update_drawing_state_error = on_update_drawing_state_error

__init__

__init__(
    backend: Backend | None = None,
    initial_state: State | None = None,
    on_update_drawing_state_error: Callable[
        [Exception, Parser, Token], None
    ]
    | ParserOnErrorAction = ParserOnErrorAction.Raise,
) -> None

Initialize options.

Source code in src/pygerber/gerberx3/parser/parser.py
def __init__(
    self,
    backend: Backend | None = None,
    initial_state: State | None = None,
    on_update_drawing_state_error: Callable[[Exception, Parser, Token], None]
    | ParserOnErrorAction = ParserOnErrorAction.Raise,
) -> None:
    """Initialize options."""
    self.backend = Rasterized2DBackend() if backend is None else backend
    self.initial_state = initial_state
    self.on_update_drawing_state_error = on_update_drawing_state_error