Skip to content

Commit c1bd536

Browse files
authored
Add multiline comment support to .pt grammar (#42)
Support multiline comments using python-style docstring syntax Add this to - lark parsing - vscode highlighting - documentation - unit tests (written by copilot, thanks) Also add 2 orthogonal changes - Extra debug for `VisitError` - Remove unused block comments from syntax highlighting
1 parent 396aa7f commit c1bd536

11 files changed

Lines changed: 416 additions & 7 deletions

File tree

docs/syntax/constant.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ custom grammar:
2727
"Comments may be attached to values with a string following the definition"
2828
VALUE_B : constant[16] = 234
2929
"These are attached to the constant definitions"
30+
VALUE_C: constant[2] = 3
31+
"""
32+
Multiline comments can be used for long descriptions.
33+
Use triple quotes for these like with Python docstrings.
34+
"""
3035
}
3136
```
3237

docs/syntax/docstrings.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
Descriptions can be added to packtype definitions as shown below.
2+
The documentation is attached to the code in a way that will allow automated generation of documentation,
3+
as with Python docstrings.
4+
5+
## Example
6+
7+
Descriptions can be added with normal [Python docstrings]((https://peps.python.org/pep-0257/)) or with the Packtype custom grammar:
8+
9+
=== "Python (.py)"
10+
11+
```python linenums="1"
12+
import packtype
13+
from packtype import Constant
14+
15+
@packtype.package()
16+
class MyPackage:
17+
"""
18+
Package decription,
19+
using normal Python docstrings
20+
"""
21+
...
22+
23+
@MyPackage.enum()
24+
class Fruit:
25+
"""
26+
Class description,
27+
using normal Python docstrings
28+
"""
29+
APPLE : Constant
30+
ORANGE : Constant
31+
PEAR : Constant
32+
BANANA : Constant
33+
```
34+
35+
=== "Packtype (.pt)"
36+
37+
```sv linenums="1"
38+
package my_package {
39+
"""
40+
Package description
41+
using multiline docstring syntax
42+
"""
43+
enum fruit_t {
44+
"""
45+
Class description
46+
using multiline docstring syntax
47+
"""
48+
@prefix=FRUIT
49+
APPLE : constant
50+
"This is an apple"
51+
ORANGE : constant
52+
"""
53+
Member descriptions can also be multiline.
54+
Use triple quotes for these.
55+
"""
56+
PEAR : constant
57+
"This is a pear"
58+
BANANA : constant
59+
"This is a banana"
60+
}
61+
62+
}
63+
```
64+
65+
66+
```

docs/syntax/package.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ custom grammar:
2222

2323
```sv linenums="1"
2424
package my_package {
25-
"Description of what purpose this package serves"
25+
"""Description of what purpose this package serves"""
2626
// ...
2727
}
2828
```

docs/syntax/scalar.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ custom grammar:
3939
TypeB : Scalar[TYPE_B_W]
4040
"They can be queried from the digested result"
4141
TypeC : Scalar[7]
42+
"""
43+
Multiline comments can be used for long descriptions.
44+
Use triple quotes for these like with Python docstrings.
45+
"""
4246
}
4347
```
4448

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ nav:
4343
- Scalars: syntax/scalar.md
4444
- Structs: syntax/struct.md
4545
- Unions: syntax/union.md
46+
- Docstrings: syntax/docstrings.md
4647
- Utilities:
4748
- Basic: utilities/basic.md
4849
- Constants: utilities/constant.md

packtype/grammar/grammar.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from pathlib import Path
99

1010
from lark import Lark
11-
from lark.exceptions import UnexpectedToken
11+
from lark.exceptions import UnexpectedToken, VisitError
1212

1313
from ..common.logging import get_log
1414
from ..types.base import Base
@@ -93,6 +93,9 @@ def parse_string(
9393
f"Failed to parse {source.name if source else 'input'} on line {exc.line}: "
9494
f"\n\n{exc.get_context(definition)}\n{exc}"
9595
) from exc
96+
except VisitError as exc:
97+
raise exc.orig_exc from exc
98+
9699
# Gather declarations
97100
known_entities: dict[str, tuple[type[Base] | Constant, Position]] = {}
98101

packtype/grammar/packtype.lark

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818

1919
%import common.CNAME
2020
%import common.ESCAPED_STRING
21+
%import common._STRING_ESC_INNER
2122
%import common.INT
2223
%import common.SIGNED_INT
2324
%import common.WS
25+
%import common.NEWLINE
2426
%ignore WS
2527

2628
// =============================================================================
@@ -42,7 +44,12 @@ dimension: "[" expr "]"
4244
dimensions: dimension+
4345

4446
?name: CNAME
45-
descr: ESCAPED_STRING
47+
48+
// Multiline docstrings as with Python - start and end with three double-quotes
49+
_DOCSTRING_QUOTES: "\"\"\""
50+
ESCAPED_MULTILINE_DOCSTRING: _DOCSTRING_QUOTES (_STRING_ESC_INNER|NEWLINE)* _DOCSTRING_QUOTES
51+
52+
descr: (ESCAPED_STRING | ESCAPED_MULTILINE_DOCSTRING)
4653

4754
modifier: "@" name "=" (name | ESCAPED_STRING | NUMERIC)
4855

packtype/grammar/transformer.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#
44

55
import math
6+
import textwrap
67

78
from lark import Transformer, v_args
89

@@ -85,7 +86,11 @@ def CNAME(self, body): # noqa: N802
8586
return str(body)
8687

8788
def descr(self, body):
88-
return Description(str(body[0]).strip('"'))
89+
"""
90+
Take description and trim surrounding quotes,
91+
then remove common indentation and remove leading and trailing newlines.
92+
"""
93+
return Description(textwrap.dedent(str(body[0]).strip('"')).strip("\n"))
8994

9095
def modifier(self, body):
9196
return Modifier(*body)

0 commit comments

Comments
 (0)