Skip to content

Commit

Permalink
Add parser level hooks support with Parser2 (#108)
Browse files Browse the repository at this point in the history
This pull request introduces brand new Parser2 class which can be used
in cooperation with old Tokenizer class and provides hooks interface
based on visitor pattern.

> [!NOTE]
> It was preferable to introduce new Parser class, as it was not
possible to effectively implement hook interface for existing Parser
class. Additionally this approach smooths transition between those two
for any possible users, as they should be able to keep using old parser.
When time will be right we will deprecate and remove old parser.
Currently exisiting drawing backend interface is also not compatible
with Parser2 and will have to be recreated following similar principles
as parser.

We can customize parser hooks by creating new hook class inheriting from
IHooks or Parser2Hooks and providing it to Parser2 constructor via
Parser2Options. Difference between those two is that all IHooks hooks
are NOOP while Parser2Hooks actually implement Gerber AST parser logic.

For example if we were to implement a parser only to print all comments
from Gerber file we could do it following way:

```python
from pygerber.gerberx3.parser2.context2 import Parser2Context
from pygerber.gerberx3.parser2.ihooks import IHooks
from pygerber.gerberx3.parser2.parser2 import Parser2, Parser2Options
from pygerber.gerberx3.tokenizer.tokens.g04_comment import Comment

class PrintComments(IHooks):

    class CommentTokenHooks(IHooks.CommentTokenHooks):
        
        def on_parser_visit_token(self, token: Comment, context: Parser2Context) -> None:
            print(token.content)
            return super().on_parser_visit_token(token, context)
``` 

All operations except visiting Comment tokens will be NOOP.

As you might notice we are creating class within a class body. This
nesting mechanism allows us to reduce amount of boilderplate required to
define hooks and simplify process of adding new hooks in the future.

All hooks specific to some particular token are defined as classes
within a class inheriting from IHooks. They must follow particular
naming scheme, for now please refer to source code in
`pygerber.gerberx3.parser2.ihooks` module.

There are also hooks which are not tied to tokens, eg. for error
handling, `on_parser_error(self, context: Parser2Context, error:
Parser2Error)` which are then defined directly within master hook class.

It should be possible to extend hook interface in the future to add
tokenizer level hooks and possibly others if needed.
  • Loading branch information
Argmaster authored Jan 11, 2024
2 parents c81a9c1 + 5b6c61a commit 6556538
Show file tree
Hide file tree
Showing 113 changed files with 9,332 additions and 517 deletions.
237 changes: 9 additions & 228 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,234 +233,13 @@ Official documentations is hosted on Github Pages and can be found

## Gerber features support

This section outlines the support for various Gerber format features in PyGerber's core
components: [**Tokenizer**](#tokenizer), [**Parser**](#parser), and
[**Rasterized2DBackend**](#rasterized2dbackend). We use checkboxes to indicate which
features are currently implemented. Checked boxes represent supported features, while
unchecked boxes denote features still under development or not available.

### Tokenizer

Supported Gerber X3 features:

- [x] G04 - Comment - A human readable comment, does not affect the image.
- [x] MO - Mode - Sets the unit to mm or inch.
- [x] FS - Format specification - Sets the coordinate format, e.g. the number of
decimals.
- [x] FS (Deprecated modes)
- [x] AD - Aperture define - Defines a template-based aperture, assigns a D code to it.
- [x] AM - Aperture macro - Defines a macro aperture template.
- [x] Dnn (nn≥10) - Sets the current aperture to D code nn.
- [x] D01 - Plot operation - Outside a region statement D01 creates a draw or arc object
with the current aperture. Inside it adds a draw/arc segment to the contour under
construction. The current point is moved to draw/arc end point after the creation
of the draw/arc.
- [x] D02 - Move operation - D02 moves the current point to the coordinate in the
command. It does not create an object.
- [x] D03 - Flash operation - Creates a flash object with the current aperture. The
current point is moved to the flash point.
- [x] G01 - Sets linear/circular mode to linear.
- [x] G02 - Sets linear/circular mode to clockwise circular.
- [x] G03 - Sets linear/circular mode to counterclockwise circular.
- [x] G75 - A G75 must be called before creating the first arc.
- [x] LP - Load polarity - Loads the polarity object transformation parameter.
- [x] LM - Load mirroring - Loads the mirror object transformation parameter.
- [x] LR - Load rotation - Loads the rotation object transformation parameter.
- [x] LS - Load scaling - Loads the scale object transformation parameter.
- [x] G36 - Starts a region statement which creates a region by defining its contours.
- [x] G37 - Ends the region statement.
- [x] AB - Aperture block - Opens a block aperture statement and assigns its aperture
number or closes a block aperture statement.
- [x] SR - Step and repeat - Open or closes a step and repeat statement.
- [x] TF - Attribute on file - Set a file attribute.
- [x] TA - Attribute on aperture - Add an aperture attribute to the dictionary or modify
it.
- [x] TO - Attribute on object - Add an object attribute to the dictionary or modify it.
- [x] TD - Attribute delete - Delete one or all attributes in the dictionary.
- [x] M02 - End of file.

Supported **DEPRECATED** Gerber features:

- [x] G54 - Select aperture - This historic code optionally precedes an aperture
selection Dnn command. It has no effect. Sometimes used. Deprecated in 2012.
- [ ] G55 - Prepare for flash - This historic code optionally precedes D03 code. It has
no effect. Very rarely used nowadays. Deprecated in 2012.
- [x] G70 - Set the 'Unit' to inch - These historic codes perform a function handled by
the MO command. See 4.2.1. Sometimes used. Deprecated in 2012.
- [x] G71 - Set the 'Unit' to mm - This is part of the historic codes that perform a
function handled by the MO command.
- [x] G90 - Set the 'Coordinate format' to 'Absolute notation' - These historic codes
perform a function handled by the FS command. Very rarely used nowadays.
Deprecated in 2012.
- [x] G91 - Set the 'Coordinate format' to 'Incremental notation' - Part of the historic
codes handled by the FS command.

- **Important**: _Incremental notation itself is not supported and is not planned due
to lack of test assets and expected complications during implementation._

- [x] G74 - Sets single quadrant mode - Rarely used, and then typically without effect.
Deprecated in 2020. (Spec. 8.1.10)
- [x] M00 - Program stop - This historic code has the same effect as M02. Very rarely,
if ever, used nowadays. Deprecated in 2012.
- [x] M01 - Optional stop - This historic code has no effect. Very rarely, if ever, used
nowadays. Deprecated in 2012.
- [x] IP - Sets the 'Image polarity' graphics state parameter - This command has no
effect in CAD to CAM workflows. Sometimes used, and then usually as %IPPOS\*% to
confirm the default and then it then has no effect. Deprecated in 2013. (Spec.
8.1.4)
- [ ] AS - Sets the 'Axes correspondence' graphics state parameter - Deprecated in 2013.
Rarely used nowadays. (Spec. 8.1.2)
- [ ] IR - Sets 'Image rotation' graphics state parameter - Deprecated in 2013. Rarely
used nowadays. (Spec. 8.1.5)
- [ ] MI - Sets 'Image mirroring' graphics state parameter (Spec. 8.1.7)
- [ ] OF - Sets 'Image offset' graphics state parameter (Spec. 8.1.8)
- [ ] SF - Sets 'Scale factor' graphics state parameter (Spec. 8.1.9)
- [ ] IN - Sets the name of the file image. Has no effect. It is comment. Sometimes
used. Deprecated in 2013. (Spec. 8.1.3)
- [x] LN - Loads a name. Has no effect. It is a comment. Sometimes used. Deprecated
in 2013. (Spec. 8.1.6)
- [x] Combining G01/G02/G03 and D01 in a single command. (Spec 8.3.1)
- [x] Coordinate Data without Operation Code. (Spec 8.3.2)
- [x] Style Variations in Command Codes. (Spec 8.3.3)
- [ ] Deprecated usage of SR. (Spec 8.3.4)
- [ ] Deprecated Attribute Values. (Spec 8.4)
- [x] Format Specification (FS) Options (Trailing Zero Omission, Incremental Notation).
(Spec. 8.2)

- **Important**: _Incremental notation itself is not supported and is not planned due
to lack of test assets and expected complications during implementation._

- [ ] Rectangular Hole in Standard Apertures (Spec. 8.2.2)
- [x] Draws and Arcs with Rectangular Apertures (Spec. 8.2.3)
- [ ] Macro Primitive Code 2, Vector Line (Spec. 8.2.4)
- [ ] Macro Primitive Code 22, Lower Left Line (Spec. 8.2.5)
- [ ] Macro Primitive Code 6, Moiré (Spec. 8.2.6)

### Parser

Supported Gerber X3 features:

- [x] MO - Mode - Sets the unit to mm or inch.
- [x] FS - Format specification - Sets the coordinate format, e.g. the number of
decimals.
- [ ] AD - Aperture define - Defines a template-based aperture, assigns a D code to it.
- [x] Define circle.
- [x] Define rectangle.
- [x] Define obround.
- [x] Define polygon.
- [ ] Define macro.
- [ ] AM - Aperture macro - Defines a macro aperture template.
- [x] Dnn (nn≥10) - Sets the current aperture to D code nn.
- [x] D01 - Plot operation - Outside a region statement D01 creates a draw or arc object
with the current aperture.
- [x] D01 - Plot operation - Inside region statement adds a draw/arc segment to the
contour under construction. The current point is moved to draw/arc end point after
the creation of the draw/arc.
- [x] D02 - Move operation - D02 moves the current point to the coordinate in the
command. It does not create an object.
- [x] D03 - Flash operation - Creates a flash object with the current aperture. The
current point is moved to the flash point.
- [x] G01 - Sets linear/circular mode to linear.
- [x] G02 - Sets linear/circular mode to clockwise circular.
- [x] G03 - Sets linear/circular mode to counterclockwise circular.
- [x] LP - Load polarity - Loads the polarity object transformation parameter.
- [x] LM - Load mirroring - Loads the mirror object transformation parameter.
- [x] LR - Load rotation - Loads the rotation object transformation parameter.
- [x] LS - Load scaling - Loads the scale object transformation parameter.
- [x] G36 - Starts a region statement which creates a region by defining its contours.
- [x] G37 - Ends the region statement.
- [ ] AB - Aperture block - Opens a block aperture statement and assigns its aperture
number or closes a block aperture statement.
- [ ] SR - Step and repeat - Open or closes a step and repeat statement.
- [ ] TF - Attribute on file - Set a file attribute.
- [ ] TA - Attribute on aperture - Add an aperture attribute to the dictionary or modify
it.
- [ ] TO - Attribute on object - Add an object attribute to the dictionary or modify it.
- [ ] TD - Attribute delete - Delete one or all attributes in the dictionary.
- [x] M02 - End of file.

Supported **DEPRECATED** Gerber features:

- [x] G54 - Select aperture - This historic code optionally precedes an aperture
selection Dnn command. It has no effect. Sometimes used. Deprecated in 2012.
- [ ] G55 - Prepare for flash - This historic code optionally precedes D03 code. It has
no effect. Very rarely used nowadays. Deprecated in 2012.
- [x] G70 - Set the 'Unit' to inch - These historic codes perform a function handled by
the MO command. See 4.2.1. Sometimes used. Deprecated in 2012.
- [x] G71 - Set the 'Unit' to mm - This is part of the historic codes that perform a
function handled by the MO command.
- [x] G90 - Set the 'Coordinate format' to 'Absolute notation' - These historic codes
perform a function handled by the FS command. Very rarely used nowadays.
Deprecated in 2012.
- [x] G91 - Set the 'Coordinate format' to 'Incremental notation' - Part of the historic
codes handled by the FS command.

- **Important**: _Incremental notation itself is not supported and is not planned due
to lack of test assets and expected complications during implementation._

- [x] G74 - Sets single quadrant mode - Rarely used, and then typically without effect.
Deprecated in 2020. (Spec. 8.1.10)
- [x] M00 - Program stop - This historic code has the same effect as M02. Very rarely,
if ever, used nowadays. Deprecated in 2012.
- [x] M01 - Optional stop - This historic code has no effect. Very rarely, if ever, used
nowadays. Deprecated in 2012.
- [x] IP - Sets the 'Image polarity' graphics state parameter - This command has no
effect in CAD to CAM workflows. Sometimes used, and then usually as %IPPOS\*% to
confirm the default and then it then has no effect. Deprecated in 2013. (Spec.
8.1.4)
- [ ] AS - Sets the 'Axes correspondence' graphics state parameter - Deprecated in 2013.
Rarely used nowadays. (Spec. 8.1.2)
- [ ] IR - Sets 'Image rotation' graphics state parameter - Deprecated in 2013. Rarely
used nowadays. (Spec. 8.1.5)
- [ ] MI - Sets 'Image mirroring' graphics state parameter (Spec. 8.1.7)
- [ ] OF - Sets 'Image offset' graphics state parameter (Spec. 8.1.8)
- [ ] SF - Sets 'Scale factor' graphics state parameter (Spec. 8.1.9)
- [ ] IN - Sets the name of the file image. Has no effect. It is comment. Sometimes
used. Deprecated in 2013. (Spec. 8.1.3)
- [x] LN - Loads a name. Has no effect. It is a comment. Sometimes used. Deprecated
in 2013. (Spec. 8.1.6)
- [x] Combining G01/G02/G03/G70/G71 and D01 in a single command. (Spec 8.3.1)
- [x] Combining G01/G02/G03/G70/G71 and D02 in a single command.
- [x] Combining G01/G02/G03/G70/G71 and D03 in a single command.
- [x] Coordinate Data without Operation Code. (Spec 8.3.2)
- [x] Style Variations in Command Codes. (Spec 8.3.3)
- [ ] Deprecated usage of SR. (Spec 8.3.4)
- [ ] Deprecated Attribute Values. (Spec 8.4)
- [ ] Format Specification (FS) Options (Trailing Zero Omission, Incremental Notation).
(Spec. 8.2)

- **Important**: _Incremental notation itself is not supported and is not planned due
to lack of test assets and expected complications during implementation._

- [ ] Rectangular Hole in Standard Apertures (Spec. 8.2.2)
- [ ] Draws and Arcs with Rectangular Apertures (Spec. 8.2.3)
- [ ] Macro Primitive Code 2, Vector Line (Spec. 8.2.4)
- [ ] Macro Primitive Code 22, Lower Left Line (Spec. 8.2.5)
- [ ] Macro Primitive Code 6, Moiré (Spec. 8.2.6)

### Rasterized2DBackend

Supported Gerber X3 features:

- [x] Aperture definition with circle
- [x] Aperture definition with rectangle
- [x] Aperture definition with obround
- [x] Aperture definition with polygon
- [ ] Aperture definition with macro
- [ ] Block aperture definition
- [x] Draw flash with circle aperture
- [x] Draw flash with rectangle aperture
- [x] Draw flash with obround aperture
- [x] Draw flash with polygon aperture
- [ ] Draw flash with macro aperture
- [ ] Draw flash with block aperture
- [x] Draw line
- [x] Draw clockwise arc
- [x] Draw counterclockwise arc
- [ ] Global mirroring
- [ ] Global rotation
- [ ] Global scaling
- [ ] Create region
Please refer to documentation for
[Tokenizer](https://argmaster.github.io/pygerber/2.1.1/gerber/feature_support/tokenizer.html),
[Parser](https://argmaster.github.io/pygerber/2.1.1/gerber/feature_support/parser.html),
[Rasterized2DBackend](https://argmaster.github.io/pygerber/2.1.1/gerber/feature_support/rasterized_2d.html)
and
[Parser2](https://argmaster.github.io/pygerber/2.1.1/gerber/feature_support/parser2.html)
for detailed list of features which are supported/not supported.

Supported **DEPRECATED** Gerber features:

Expand All @@ -470,6 +249,8 @@ Supported **DEPRECATED** Gerber features:

**IMPORTANT** This feature list is incomplete, it will get longer over time ...

---

## Syntax feature requests

All deprecated features (Mainly those from X2 format) are considered optional and
Expand Down
2 changes: 1 addition & 1 deletion docs/gerber/high_level_api.md → docs/gerber/0_usage.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# High Level API
# Public API Usage

PyGerber offers simple high-level API for rendering Gerber files. All necessary tools
can be imported from `pygerber.gerberx3.api` module. See
Expand Down
3 changes: 3 additions & 0 deletions docs/gerber/1_reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Public API Reference

::: pygerber.gerberx3.api
6 changes: 3 additions & 3 deletions docs/gerber/advanced_api.md → docs/gerber/3_internal_api.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Advanced API
# PyGerber internal API

## Stability

PyGerber's Gerber advanced API is not as stable as high level API. This is because the
PyGerber's Gerber internal API is not as stable as high level API. This is because the
implementation of subsequent functionalities may force changes in the structure of the
code. However, our goal is to guarantee advanced API **stability between patch**
code. However, our goal is to guarantee internal API **stability between patch**
releases.

!!! warning "Security"
Expand Down
15 changes: 15 additions & 0 deletions docs/gerber/feature_support/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"semi": true,
"useTabs": false,
"endOfLine": "lf",
"printWidth": 88,
"overrides": [
{
"files": ["*.md"],
"options": {
"tabWidth": 4,
"proseWrap": "always"
}
}
]
}
Loading

0 comments on commit 6556538

Please sign in to comment.