openscad-parser 1.0.1__tar.gz → 2.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openscad_parser
3
- Version: 1.0.1
3
+ Version: 2.2.0
4
4
  Summary: A PEG parser to read OpenSCAD language source code, with optional AST tree generation.
5
5
  Keywords: openscad,openscad parser,parser
6
6
  Author: Revar Desmera
@@ -21,9 +21,10 @@ Classifier: Topic :: Software Development :: Libraries
21
21
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
22
  Requires-Dist: arpeggio>=2.0.3
23
23
  Requires-Dist: pytest>=7.0.0 ; extra == 'dev'
24
+ Requires-Dist: pyyaml>=6.0 ; extra == 'yaml'
24
25
  Maintainer: Revar Desmera
25
26
  Maintainer-email: Revar Desmera <revarbat@gmail.com>
26
- Requires-Python: >=3.7
27
+ Requires-Python: >=3.11
27
28
  Project-URL: Bug Tracker, https://github.com/belfryscad/openscad_parser/issues
28
29
  Project-URL: Documentation, https://github.com/belfryscad/openscad_parser/WRITING_DOCS.md
29
30
  Project-URL: Homepage, https://github.com/belfryscad/openscad_parser
@@ -31,6 +32,7 @@ Project-URL: Releases, https://github.com/belfryscad/openscad_parser/releases
31
32
  Project-URL: Repository, https://github.com/belfryscad/openscad_parser
32
33
  Project-URL: Usage, https://github.com/belfryscad/openscad_parser/README.rst
33
34
  Provides-Extra: dev
35
+ Provides-Extra: yaml
34
36
  Description-Content-Type: text/x-rst
35
37
 
36
38
  OpenSCAD Parser
@@ -53,6 +55,7 @@ Features
53
55
  - Source position tracking for all AST nodes
54
56
  - AST tree can contain comment nodes (single-line and multi-line)
55
57
  - AST tree uses dataclasses and can be pickled/unpickled for caching/serialization
58
+ - JSON and YAML serialization/deserialization of AST trees
56
59
 
57
60
  Installation
58
61
  ------------
@@ -145,6 +148,13 @@ Use ``getASTfromFile()`` to parse an OpenSCAD file. This function includes autom
145
148
 
146
149
  The cache is automatically invalidated when the file is modified, ensuring you always get up-to-date results.
147
150
 
151
+ **Include Processing:** By default, ``getASTfromFile()`` processes ``include <file>`` statements before parsing (``process_includes=True``). This means the AST will NOT contain ``IncludeStatement`` nodes - instead, the included file contents are expanded into the AST. Set ``process_includes=False`` to preserve ``IncludeStatement`` nodes in the AST::
152
+
153
+ # Get AST with IncludeStatement nodes preserved
154
+ ast_with_includes = getASTfromFile("my_model.scad", process_includes=False)
155
+
156
+ **Note:** Unlike ``include`` statements, ``use <file>`` statements are ALWAYS parsed into ``UseStatement`` AST nodes, regardless of the ``process_includes`` setting. This is because ``use`` statements only affect module and function lookup at runtime, not source inclusion.
157
+
148
158
  Parsing Library Files
149
159
  ^^^^^^^^^^^^^^^^^^^^^^
150
160
 
@@ -466,27 +476,43 @@ Main Functions
466
476
  :returns: AST node or list of AST nodes (for top-level statements)
467
477
  :rtype: ASTNode | list[ASTNode] | None
468
478
 
469
- ``getASTfromFile(file: str)``
479
+ ``getASTfromFile(file: str, include_comments: bool = False, process_includes: bool = True)``
470
480
  Parse an OpenSCAD source file and return its AST. Includes automatic caching
471
481
  that invalidates when the file's modification timestamp changes.
472
482
 
473
483
  :param file: The OpenSCAD source file to be parsed
484
+ :param include_comments: If True, include comments in the AST (default: False)
485
+ :param process_includes: If True, process include statements and replace with file contents (default: True).
486
+ When False, the AST will contain IncludeStatement nodes where includes appear.
474
487
  :returns: List of AST nodes (for top-level statements)
475
488
  :rtype: list[ASTNode] | None
476
489
  :raises FileNotFoundError: If the specified file does not exist
477
490
  :raises Exception: If there is an error while reading the file
478
491
 
479
- ``getASTfromLibraryFile(currfile: str, libfile: str)``
492
+ **Note:** When ``process_includes=True`` (default), the AST will NOT contain ``IncludeStatement`` nodes
493
+ because includes are processed before parsing. When ``process_includes=False``, ``IncludeStatement``
494
+ nodes will appear in the AST where ``include <file>`` statements exist in the source code.
495
+
496
+ Unlike ``include`` statements, ``use <file>`` statements are ALWAYS parsed into ``UseStatement``
497
+ AST nodes regardless of the ``process_includes`` setting, since ``use`` only affects runtime
498
+ lookup, not source inclusion.
499
+
500
+ ``getASTfromLibraryFile(currfile: str, libfile: str, include_comments: bool = False, process_includes: bool = True)``
480
501
  Find and parse an OpenSCAD library file using OpenSCAD's search path rules.
481
502
  Searches in: current file directory, OPENSCADPATH, and platform default paths.
482
503
 
483
504
  :param currfile: Full path to the current OpenSCAD file (can be empty string)
484
505
  :param libfile: Partial or full path to the library file to find
506
+ :param include_comments: If True, include comments in the AST (default: False)
507
+ :param process_includes: If True, process include statements (default: True).
508
+ When False, the AST will contain IncludeStatement nodes where includes appear.
485
509
  :returns: Tuple of (AST nodes list, absolute file path). The AST list is None if empty or not valid.
486
510
  :rtype: tuple[list[ASTNode] | None, str]
487
511
  :raises FileNotFoundError: If the library file cannot be found
488
512
  :raises Exception: If there is an error while reading or parsing the file
489
513
 
514
+ **Note:** The ``process_includes`` parameter affects the AST structure (see ``getASTfromFile`` documentation).
515
+
490
516
  ``parse_ast(parser, code, file="")``
491
517
  Parse OpenSCAD code and generate an AST (lower-level API).
492
518
 
@@ -501,6 +527,65 @@ Main Functions
501
527
 
502
528
  This function removes all cached AST trees from memory.
503
529
 
530
+ Serialization Functions
531
+ ~~~~~~~~~~~~~~~~~~~~~~~
532
+
533
+ ``ast_to_dict(ast: ASTNode | Sequence[ASTNode] | None, include_position: bool = True)``
534
+ Convert an AST to a Python dictionary (JSON-serializable).
535
+
536
+ :param ast: An AST node, sequence of AST nodes, or None
537
+ :param include_position: If True, include source position information (default: True)
538
+ :returns: A dictionary representation of the AST, a list of dictionaries, or None
539
+ :rtype: dict[str, Any] | list[dict[str, Any]] | None
540
+
541
+ ``ast_to_json(ast: ASTNode | Sequence[ASTNode] | None, include_position: bool = True, indent: int | None = 2)``
542
+ Serialize an AST to a JSON string.
543
+
544
+ :param ast: An AST node, sequence of AST nodes, or None
545
+ :param include_position: If True, include source position information (default: True)
546
+ :param indent: Indentation level for pretty-printing. Use None for compact output (default: 2)
547
+ :returns: A JSON string representation of the AST
548
+ :rtype: str
549
+
550
+ ``ast_from_dict(data: dict[str, Any] | list[dict[str, Any]] | None)``
551
+ Reconstruct an AST from a Python dictionary.
552
+
553
+ :param data: A dictionary, list of dictionaries, or None (as returned by ast_to_dict)
554
+ :returns: An AST node, list of AST nodes, or None
555
+ :rtype: ASTNode | list[ASTNode] | None
556
+ :raises ValueError: If the data contains an unknown node type or is malformed
557
+
558
+ ``ast_from_json(json_str: str)``
559
+ Deserialize an AST from a JSON string.
560
+
561
+ :param json_str: A JSON string (as returned by ast_to_json)
562
+ :returns: An AST node, list of AST nodes, or None
563
+ :rtype: ASTNode | list[ASTNode] | None
564
+ :raises ValueError: If the JSON contains an unknown node type or is malformed
565
+ :raises json.JSONDecodeError: If the string is not valid JSON
566
+
567
+ ``ast_to_yaml(ast: ASTNode | Sequence[ASTNode] | None, include_position: bool = True)``
568
+ Serialize an AST to a YAML string.
569
+
570
+ Requires PyYAML to be installed: ``pip install openscad_parser[yaml]``
571
+
572
+ :param ast: An AST node, sequence of AST nodes, or None
573
+ :param include_position: If True, include source position information (default: True)
574
+ :returns: A YAML string representation of the AST
575
+ :rtype: str
576
+ :raises ImportError: If PyYAML is not installed
577
+
578
+ ``ast_from_yaml(yaml_str: str)``
579
+ Deserialize an AST from a YAML string.
580
+
581
+ Requires PyYAML to be installed: ``pip install openscad_parser[yaml]``
582
+
583
+ :param yaml_str: A YAML string (as returned by ast_to_yaml)
584
+ :returns: An AST node, list of AST nodes, or None
585
+ :rtype: ASTNode | list[ASTNode] | None
586
+ :raises ImportError: If PyYAML is not installed
587
+ :raises ValueError: If the YAML contains an unknown node type or is malformed
588
+
504
589
  AST Node Classes
505
590
  ~~~~~~~~~~~~~~~~
506
591
 
@@ -557,6 +642,95 @@ All AST nodes include source position information::
557
642
 
558
643
  The ``Position`` class provides lazy evaluation of line/column numbers from character positions.
559
644
 
645
+ Serialization
646
+ -------------
647
+
648
+ AST trees can be serialized to JSON or YAML formats and deserialized back to AST nodes. This is useful for caching, storage, or transferring AST data between processes.
649
+
650
+ JSON Serialization
651
+ ~~~~~~~~~~~~~~~~~~
652
+
653
+ Serialize an AST to JSON::
654
+
655
+ from openscad_parser.ast import getASTfromString, ast_to_json, ast_from_json
656
+
657
+ # Parse code to AST
658
+ ast = getASTfromString("cube(10);")
659
+
660
+ # Serialize to JSON string
661
+ json_str = ast_to_json(ast, include_position=True, indent=2)
662
+
663
+ # Deserialize back to AST
664
+ ast_restored = ast_from_json(json_str)
665
+
666
+ The ``ast_to_json()`` function accepts:
667
+ - ``ast``: An AST node, sequence of AST nodes, or None
668
+ - ``include_position``: If True, include source position information (default: True)
669
+ - ``indent``: Indentation level for pretty-printing. Use None for compact output (default: 2)
670
+
671
+ Dictionary Serialization
672
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
673
+
674
+ You can also work with Python dictionaries directly::
675
+
676
+ from openscad_parser.ast import getASTfromString, ast_to_dict, ast_from_dict
677
+
678
+ ast = getASTfromString("x = 42;")
679
+
680
+ # Convert to dictionary
681
+ data = ast_to_dict(ast, include_position=True)
682
+
683
+ # Convert back to AST
684
+ ast_restored = ast_from_dict(data)
685
+
686
+ YAML Serialization
687
+ ~~~~~~~~~~~~~~~~~~
688
+
689
+ For YAML serialization, you need to install PyYAML::
690
+
691
+ pip install openscad_parser[yaml]
692
+
693
+ Then serialize to YAML::
694
+
695
+ from openscad_parser.ast import getASTfromString, ast_to_yaml, ast_from_yaml
696
+
697
+ ast = getASTfromString("cube(10);")
698
+
699
+ # Serialize to YAML string
700
+ yaml_str = ast_to_yaml(ast, include_position=True)
701
+
702
+ # Deserialize back to AST
703
+ ast_restored = ast_from_yaml(yaml_str)
704
+
705
+ The ``ast_to_yaml()`` function accepts:
706
+ - ``ast``: An AST node, sequence of AST nodes, or None
707
+ - ``include_position``: If True, include source position information (default: True)
708
+
709
+ Serialization Functions
710
+ ~~~~~~~~~~~~~~~~~~~~~~~
711
+
712
+ All serialization functions can be imported directly from ``openscad_parser.ast`` (recommended)::
713
+
714
+ from openscad_parser.ast import (
715
+ ast_to_dict,
716
+ ast_to_json,
717
+ ast_to_yaml,
718
+ ast_from_dict,
719
+ ast_from_json,
720
+ ast_from_yaml,
721
+ )
722
+
723
+ They are also available from ``openscad_parser.ast.serialization``::
724
+
725
+ from openscad_parser.ast.serialization import (
726
+ ast_to_dict,
727
+ ast_to_json,
728
+ ast_to_yaml,
729
+ ast_from_dict,
730
+ ast_from_json,
731
+ ast_from_yaml,
732
+ )
733
+
560
734
  Error Handling
561
735
  --------------
562
736
 
@@ -18,6 +18,7 @@ Features
18
18
  - Source position tracking for all AST nodes
19
19
  - AST tree can contain comment nodes (single-line and multi-line)
20
20
  - AST tree uses dataclasses and can be pickled/unpickled for caching/serialization
21
+ - JSON and YAML serialization/deserialization of AST trees
21
22
 
22
23
  Installation
23
24
  ------------
@@ -110,6 +111,13 @@ Use ``getASTfromFile()`` to parse an OpenSCAD file. This function includes autom
110
111
 
111
112
  The cache is automatically invalidated when the file is modified, ensuring you always get up-to-date results.
112
113
 
114
+ **Include Processing:** By default, ``getASTfromFile()`` processes ``include <file>`` statements before parsing (``process_includes=True``). This means the AST will NOT contain ``IncludeStatement`` nodes - instead, the included file contents are expanded into the AST. Set ``process_includes=False`` to preserve ``IncludeStatement`` nodes in the AST::
115
+
116
+ # Get AST with IncludeStatement nodes preserved
117
+ ast_with_includes = getASTfromFile("my_model.scad", process_includes=False)
118
+
119
+ **Note:** Unlike ``include`` statements, ``use <file>`` statements are ALWAYS parsed into ``UseStatement`` AST nodes, regardless of the ``process_includes`` setting. This is because ``use`` statements only affect module and function lookup at runtime, not source inclusion.
120
+
113
121
  Parsing Library Files
114
122
  ^^^^^^^^^^^^^^^^^^^^^^
115
123
 
@@ -431,27 +439,43 @@ Main Functions
431
439
  :returns: AST node or list of AST nodes (for top-level statements)
432
440
  :rtype: ASTNode | list[ASTNode] | None
433
441
 
434
- ``getASTfromFile(file: str)``
442
+ ``getASTfromFile(file: str, include_comments: bool = False, process_includes: bool = True)``
435
443
  Parse an OpenSCAD source file and return its AST. Includes automatic caching
436
444
  that invalidates when the file's modification timestamp changes.
437
445
 
438
446
  :param file: The OpenSCAD source file to be parsed
447
+ :param include_comments: If True, include comments in the AST (default: False)
448
+ :param process_includes: If True, process include statements and replace with file contents (default: True).
449
+ When False, the AST will contain IncludeStatement nodes where includes appear.
439
450
  :returns: List of AST nodes (for top-level statements)
440
451
  :rtype: list[ASTNode] | None
441
452
  :raises FileNotFoundError: If the specified file does not exist
442
453
  :raises Exception: If there is an error while reading the file
443
454
 
444
- ``getASTfromLibraryFile(currfile: str, libfile: str)``
455
+ **Note:** When ``process_includes=True`` (default), the AST will NOT contain ``IncludeStatement`` nodes
456
+ because includes are processed before parsing. When ``process_includes=False``, ``IncludeStatement``
457
+ nodes will appear in the AST where ``include <file>`` statements exist in the source code.
458
+
459
+ Unlike ``include`` statements, ``use <file>`` statements are ALWAYS parsed into ``UseStatement``
460
+ AST nodes regardless of the ``process_includes`` setting, since ``use`` only affects runtime
461
+ lookup, not source inclusion.
462
+
463
+ ``getASTfromLibraryFile(currfile: str, libfile: str, include_comments: bool = False, process_includes: bool = True)``
445
464
  Find and parse an OpenSCAD library file using OpenSCAD's search path rules.
446
465
  Searches in: current file directory, OPENSCADPATH, and platform default paths.
447
466
 
448
467
  :param currfile: Full path to the current OpenSCAD file (can be empty string)
449
468
  :param libfile: Partial or full path to the library file to find
469
+ :param include_comments: If True, include comments in the AST (default: False)
470
+ :param process_includes: If True, process include statements (default: True).
471
+ When False, the AST will contain IncludeStatement nodes where includes appear.
450
472
  :returns: Tuple of (AST nodes list, absolute file path). The AST list is None if empty or not valid.
451
473
  :rtype: tuple[list[ASTNode] | None, str]
452
474
  :raises FileNotFoundError: If the library file cannot be found
453
475
  :raises Exception: If there is an error while reading or parsing the file
454
476
 
477
+ **Note:** The ``process_includes`` parameter affects the AST structure (see ``getASTfromFile`` documentation).
478
+
455
479
  ``parse_ast(parser, code, file="")``
456
480
  Parse OpenSCAD code and generate an AST (lower-level API).
457
481
 
@@ -466,6 +490,65 @@ Main Functions
466
490
 
467
491
  This function removes all cached AST trees from memory.
468
492
 
493
+ Serialization Functions
494
+ ~~~~~~~~~~~~~~~~~~~~~~~
495
+
496
+ ``ast_to_dict(ast: ASTNode | Sequence[ASTNode] | None, include_position: bool = True)``
497
+ Convert an AST to a Python dictionary (JSON-serializable).
498
+
499
+ :param ast: An AST node, sequence of AST nodes, or None
500
+ :param include_position: If True, include source position information (default: True)
501
+ :returns: A dictionary representation of the AST, a list of dictionaries, or None
502
+ :rtype: dict[str, Any] | list[dict[str, Any]] | None
503
+
504
+ ``ast_to_json(ast: ASTNode | Sequence[ASTNode] | None, include_position: bool = True, indent: int | None = 2)``
505
+ Serialize an AST to a JSON string.
506
+
507
+ :param ast: An AST node, sequence of AST nodes, or None
508
+ :param include_position: If True, include source position information (default: True)
509
+ :param indent: Indentation level for pretty-printing. Use None for compact output (default: 2)
510
+ :returns: A JSON string representation of the AST
511
+ :rtype: str
512
+
513
+ ``ast_from_dict(data: dict[str, Any] | list[dict[str, Any]] | None)``
514
+ Reconstruct an AST from a Python dictionary.
515
+
516
+ :param data: A dictionary, list of dictionaries, or None (as returned by ast_to_dict)
517
+ :returns: An AST node, list of AST nodes, or None
518
+ :rtype: ASTNode | list[ASTNode] | None
519
+ :raises ValueError: If the data contains an unknown node type or is malformed
520
+
521
+ ``ast_from_json(json_str: str)``
522
+ Deserialize an AST from a JSON string.
523
+
524
+ :param json_str: A JSON string (as returned by ast_to_json)
525
+ :returns: An AST node, list of AST nodes, or None
526
+ :rtype: ASTNode | list[ASTNode] | None
527
+ :raises ValueError: If the JSON contains an unknown node type or is malformed
528
+ :raises json.JSONDecodeError: If the string is not valid JSON
529
+
530
+ ``ast_to_yaml(ast: ASTNode | Sequence[ASTNode] | None, include_position: bool = True)``
531
+ Serialize an AST to a YAML string.
532
+
533
+ Requires PyYAML to be installed: ``pip install openscad_parser[yaml]``
534
+
535
+ :param ast: An AST node, sequence of AST nodes, or None
536
+ :param include_position: If True, include source position information (default: True)
537
+ :returns: A YAML string representation of the AST
538
+ :rtype: str
539
+ :raises ImportError: If PyYAML is not installed
540
+
541
+ ``ast_from_yaml(yaml_str: str)``
542
+ Deserialize an AST from a YAML string.
543
+
544
+ Requires PyYAML to be installed: ``pip install openscad_parser[yaml]``
545
+
546
+ :param yaml_str: A YAML string (as returned by ast_to_yaml)
547
+ :returns: An AST node, list of AST nodes, or None
548
+ :rtype: ASTNode | list[ASTNode] | None
549
+ :raises ImportError: If PyYAML is not installed
550
+ :raises ValueError: If the YAML contains an unknown node type or is malformed
551
+
469
552
  AST Node Classes
470
553
  ~~~~~~~~~~~~~~~~
471
554
 
@@ -522,6 +605,95 @@ All AST nodes include source position information::
522
605
 
523
606
  The ``Position`` class provides lazy evaluation of line/column numbers from character positions.
524
607
 
608
+ Serialization
609
+ -------------
610
+
611
+ AST trees can be serialized to JSON or YAML formats and deserialized back to AST nodes. This is useful for caching, storage, or transferring AST data between processes.
612
+
613
+ JSON Serialization
614
+ ~~~~~~~~~~~~~~~~~~
615
+
616
+ Serialize an AST to JSON::
617
+
618
+ from openscad_parser.ast import getASTfromString, ast_to_json, ast_from_json
619
+
620
+ # Parse code to AST
621
+ ast = getASTfromString("cube(10);")
622
+
623
+ # Serialize to JSON string
624
+ json_str = ast_to_json(ast, include_position=True, indent=2)
625
+
626
+ # Deserialize back to AST
627
+ ast_restored = ast_from_json(json_str)
628
+
629
+ The ``ast_to_json()`` function accepts:
630
+ - ``ast``: An AST node, sequence of AST nodes, or None
631
+ - ``include_position``: If True, include source position information (default: True)
632
+ - ``indent``: Indentation level for pretty-printing. Use None for compact output (default: 2)
633
+
634
+ Dictionary Serialization
635
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
636
+
637
+ You can also work with Python dictionaries directly::
638
+
639
+ from openscad_parser.ast import getASTfromString, ast_to_dict, ast_from_dict
640
+
641
+ ast = getASTfromString("x = 42;")
642
+
643
+ # Convert to dictionary
644
+ data = ast_to_dict(ast, include_position=True)
645
+
646
+ # Convert back to AST
647
+ ast_restored = ast_from_dict(data)
648
+
649
+ YAML Serialization
650
+ ~~~~~~~~~~~~~~~~~~
651
+
652
+ For YAML serialization, you need to install PyYAML::
653
+
654
+ pip install openscad_parser[yaml]
655
+
656
+ Then serialize to YAML::
657
+
658
+ from openscad_parser.ast import getASTfromString, ast_to_yaml, ast_from_yaml
659
+
660
+ ast = getASTfromString("cube(10);")
661
+
662
+ # Serialize to YAML string
663
+ yaml_str = ast_to_yaml(ast, include_position=True)
664
+
665
+ # Deserialize back to AST
666
+ ast_restored = ast_from_yaml(yaml_str)
667
+
668
+ The ``ast_to_yaml()`` function accepts:
669
+ - ``ast``: An AST node, sequence of AST nodes, or None
670
+ - ``include_position``: If True, include source position information (default: True)
671
+
672
+ Serialization Functions
673
+ ~~~~~~~~~~~~~~~~~~~~~~~
674
+
675
+ All serialization functions can be imported directly from ``openscad_parser.ast`` (recommended)::
676
+
677
+ from openscad_parser.ast import (
678
+ ast_to_dict,
679
+ ast_to_json,
680
+ ast_to_yaml,
681
+ ast_from_dict,
682
+ ast_from_json,
683
+ ast_from_yaml,
684
+ )
685
+
686
+ They are also available from ``openscad_parser.ast.serialization``::
687
+
688
+ from openscad_parser.ast.serialization import (
689
+ ast_to_dict,
690
+ ast_to_json,
691
+ ast_to_yaml,
692
+ ast_from_dict,
693
+ ast_from_json,
694
+ ast_from_yaml,
695
+ )
696
+
525
697
  Error Handling
526
698
  --------------
527
699
 
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "openscad_parser"
7
- version = "1.0.1"
7
+ version = "2.2.0"
8
8
  description = "A PEG parser to read OpenSCAD language source code, with optional AST tree generation."
9
9
  readme = "README.rst"
10
10
  authors = [
@@ -14,7 +14,7 @@ maintainers = [
14
14
  { name="Revar Desmera", email="revarbat@gmail.com" },
15
15
  ]
16
16
  license = "MIT"
17
- requires-python = ">=3.7"
17
+ requires-python = ">=3.11"
18
18
  classifiers = [
19
19
  "Development Status :: 4 - Beta",
20
20
  "Environment :: Console",
@@ -39,6 +39,9 @@ dependencies = [
39
39
  dev = [
40
40
  "pytest>=7.0.0",
41
41
  ]
42
+ yaml = [
43
+ "PyYAML>=6.0",
44
+ ]
42
45
 
43
46
  [project.urls]
44
47
  "Homepage" = "https://github.com/belfryscad/openscad_parser"
@@ -0,0 +1,38 @@
1
+ #######################################################################
2
+ # Arpeggio PEG Grammar for OpenSCAD
3
+ #######################################################################
4
+
5
+ from __future__ import unicode_literals
6
+
7
+ from arpeggio import ParserPython
8
+ from .grammar import openscad_language, openscad_language_with_comments, comment, whitespace_only
9
+
10
+
11
+ # --- The parser ---
12
+
13
+ def getOpenSCADParser(reduce_tree=False, debug=False, include_comments=False):
14
+ """Create an OpenSCAD parser instance.
15
+
16
+ Args:
17
+ reduce_tree: If True, reduce the parse tree (default: False)
18
+ debug: If True, enable debug output (default: False)
19
+ include_comments: If True, include comments in the AST instead of skipping them (default: False)
20
+
21
+ Returns:
22
+ ParserPython instance configured for OpenSCAD parsing
23
+ """
24
+ if include_comments:
25
+ # When including comments, use whitespace-only rule and include comments in grammar
26
+ return ParserPython(
27
+ openscad_language_with_comments, whitespace_only, reduce_tree=reduce_tree,
28
+ memoization=True, autokwd=True, debug=debug
29
+ )
30
+ else:
31
+ # Default behavior: comments are skipped as whitespace
32
+ return ParserPython(
33
+ openscad_language, comment, reduce_tree=reduce_tree,
34
+ memoization=True, autokwd=True, debug=debug
35
+ )
36
+
37
+
38
+ # vim: set ts=4 sw=4 expandtab: