openscad-parser 0.9.2__py3-none-any.whl

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.
@@ -0,0 +1,484 @@
1
+ #######################################################################
2
+ # Arpeggio PEG Grammar for OpenSCAD
3
+ #######################################################################
4
+
5
+ from __future__ import unicode_literals
6
+
7
+ from arpeggio import (
8
+ ParserPython, Optional, ZeroOrMore, OneOrMore, EOF, Kwd, Not, # And,
9
+ RegExMatch as _
10
+ )
11
+
12
+
13
+ # --- The parser ---
14
+
15
+ def getOpenSCADParser(reduce_tree=False, debug=False):
16
+ return ParserPython(
17
+ openscad_language, comment, reduce_tree=reduce_tree,
18
+ memoization=True, autokwd=True, debug=debug
19
+ )
20
+
21
+
22
+ # --- OpenSCAD language parsing root ---
23
+
24
+ def openscad_language():
25
+ return (ZeroOrMore([use_statement, include_statement, statement]), EOF)
26
+
27
+
28
+ # --- Lexical and basic rules ---
29
+
30
+ def comment_line():
31
+ return _(r'//.*?$', str_repr='comment')
32
+
33
+
34
+ def comment_multi():
35
+ return _(r'(?ms)/\*.*?\*/', str_repr='comment')
36
+
37
+
38
+ def comment():
39
+ return [comment_line, comment_multi]
40
+
41
+
42
+ def TOK_STRING():
43
+ return ('"', _(r'([^"\\]|\\.|\\$)*', str_repr='string'), '"')
44
+
45
+
46
+ def TOK_NUMBER():
47
+ return _(
48
+ r'[+-]?(0x[0-9A-Fa-f]+|'
49
+ r'\d+([.]\d*)?([eE][+-]?\d+)?'
50
+ r'|[.]\d+([eE][+-]?\d+)?)'
51
+ )
52
+
53
+
54
+ def TOK_ID():
55
+ return _(r"(\$?[_A-Za-z][A-Za-z0-9_]*)", str_repr='string')
56
+
57
+
58
+ def TOK_COMMA():
59
+ return ','
60
+
61
+
62
+ def TOK_LOGICAL_OR():
63
+ return "||"
64
+
65
+
66
+ def TOK_LOGICAL_AND():
67
+ return "&&"
68
+
69
+
70
+ def TOK_LOGICAL_NOT():
71
+ return "!"
72
+
73
+
74
+ def TOK_BINARY_OR():
75
+ return ("|", Not('|'))
76
+
77
+
78
+ def TOK_BINARY_AND():
79
+ return ("&", Not('&'))
80
+
81
+
82
+ def TOK_BINARY_NOT():
83
+ return "~"
84
+
85
+
86
+ def TOK_BINARY_SHIFT_LEFT():
87
+ return "<<"
88
+
89
+
90
+ def TOK_BINARY_SHIFT_RIGHT():
91
+ return ">>"
92
+
93
+
94
+ def TOK_GT():
95
+ return (">", Not('>', '='))
96
+
97
+
98
+ def TOK_LT():
99
+ return ("<", Not('<', '='))
100
+
101
+
102
+ def TOK_GTE():
103
+ return ">="
104
+
105
+
106
+ def TOK_LTE():
107
+ return "<="
108
+
109
+
110
+ def TOK_EQUAL():
111
+ return "=="
112
+
113
+
114
+ def TOK_NOTEQUAL():
115
+ return "!="
116
+
117
+
118
+ def TOK_ASSIGN():
119
+ return ('=', Not('='))
120
+
121
+
122
+ def TOK_USE():
123
+ return Kwd('use')
124
+
125
+
126
+ def TOK_INCLUDE():
127
+ return Kwd('include')
128
+
129
+
130
+ def TOK_MODULE():
131
+ return Kwd('module')
132
+
133
+
134
+ def TOK_FUNCTION():
135
+ return Kwd('function')
136
+
137
+
138
+ def TOK_IF():
139
+ return Kwd('if')
140
+
141
+
142
+ def TOK_ELSE():
143
+ return Kwd('else')
144
+
145
+
146
+ def TOK_FOR():
147
+ return Kwd('for')
148
+
149
+
150
+ def TOK_INTERSECTION_FOR():
151
+ return Kwd('intersection_for')
152
+
153
+
154
+ def TOK_LET():
155
+ return Kwd('let')
156
+
157
+
158
+ def TOK_ASSERT():
159
+ return Kwd('assert')
160
+
161
+
162
+ def TOK_ECHO():
163
+ return Kwd('echo')
164
+
165
+
166
+ def TOK_EACH():
167
+ return Kwd('each')
168
+
169
+
170
+ def TOK_TRUE():
171
+ return Kwd('true')
172
+
173
+
174
+ def TOK_FALSE():
175
+ return Kwd('false')
176
+
177
+
178
+ def TOK_UNDEF():
179
+ return Kwd('undef')
180
+
181
+
182
+ # --- Grammar rules ---
183
+
184
+ def use_statement():
185
+ return (TOK_USE, '<', _(r'[^>]+'), '>')
186
+
187
+
188
+ def include_statement():
189
+ return (TOK_INCLUDE, '<', _(r'[^>]+'), '>')
190
+
191
+
192
+ def statement():
193
+ return [
194
+ ";",
195
+ ('{', ZeroOrMore(statement), '}'),
196
+ module_definition,
197
+ function_definition,
198
+ module_instantiation,
199
+ assignment
200
+ ]
201
+
202
+
203
+ def module_definition():
204
+ return (TOK_MODULE, TOK_ID, '(', parameters, ')', statement)
205
+
206
+
207
+ def function_definition():
208
+ return (TOK_FUNCTION, TOK_ID, '(', parameters, ')', TOK_ASSIGN, expr, ';')
209
+
210
+
211
+ def assignment():
212
+ return (TOK_ID, TOK_ASSIGN, expr, ';')
213
+
214
+
215
+ def module_instantiation():
216
+ return [
217
+ modifier_show_only,
218
+ modifier_highlight,
219
+ modifier_background,
220
+ modifier_disable,
221
+ ifelse_statement,
222
+ single_module_instantiation
223
+ ]
224
+
225
+
226
+ def modifier_show_only():
227
+ return ('!', module_instantiation)
228
+
229
+
230
+ def modifier_highlight():
231
+ return ('#', module_instantiation)
232
+
233
+
234
+ def modifier_background():
235
+ return ('%', module_instantiation)
236
+
237
+
238
+ def modifier_disable():
239
+ return ('*', module_instantiation)
240
+
241
+
242
+ def ifelse_statement():
243
+ return [
244
+ (TOK_IF, '(', expr, ')', child_statement,
245
+ TOK_ELSE, child_statement),
246
+ (TOK_IF, '(', expr, ')', child_statement)
247
+ ]
248
+
249
+
250
+ def single_module_instantiation():
251
+ return [
252
+ modular_for,
253
+ modular_intersection_for,
254
+ modular_let,
255
+ modular_assert,
256
+ modular_echo,
257
+ modular_call
258
+ ]
259
+
260
+
261
+ def child_statement():
262
+ return [
263
+ ';',
264
+ ('{', ZeroOrMore([assignment, child_statement]), '}'),
265
+ module_instantiation
266
+ ]
267
+
268
+
269
+ # --- Modules and Module Control Structures ---
270
+
271
+ def modular_for():
272
+ return [
273
+ (TOK_FOR, "(", assignments_expr, ")", child_statement),
274
+ (TOK_FOR, "(", assignments_expr, ";", expr, ";", assignments_expr,
275
+ ")", child_statement)
276
+ ]
277
+
278
+
279
+ def modular_intersection_for():
280
+ return (TOK_INTERSECTION_FOR, "(", assignments_expr, ")", child_statement)
281
+
282
+
283
+ def modular_let():
284
+ return (TOK_LET, "(", assignments_expr, ")", child_statement)
285
+
286
+
287
+ def modular_assert():
288
+ return (TOK_ASSERT, "(", arguments, ")", child_statement)
289
+
290
+
291
+ def modular_echo():
292
+ return (TOK_ECHO, "(", arguments, ")", child_statement)
293
+
294
+
295
+ def modular_call():
296
+ return (TOK_ID, "(", arguments, ")", child_statement)
297
+
298
+
299
+ # --- Parameter and argument lists ---
300
+
301
+ def parameters():
302
+ return (ZeroOrMore(parameter, sep=TOK_COMMA), ZeroOrMore(TOK_COMMA))
303
+
304
+
305
+ def parameter():
306
+ return [
307
+ (TOK_ID, TOK_ASSIGN, expr),
308
+ TOK_ID
309
+ ]
310
+
311
+
312
+ def arguments():
313
+ return (ZeroOrMore(argument, sep=TOK_COMMA), Optional(TOK_COMMA))
314
+
315
+
316
+ def argument():
317
+ return [
318
+ (TOK_ID, TOK_ASSIGN, expr),
319
+ expr
320
+ ]
321
+
322
+
323
+ # --- Expressions ---
324
+
325
+ def assignments_expr():
326
+ return (ZeroOrMore(assignment_expr, sep=TOK_COMMA), Optional(TOK_COMMA))
327
+
328
+
329
+ def assignment_expr():
330
+ return (TOK_ID, TOK_ASSIGN, expr)
331
+
332
+
333
+ def expr():
334
+ return [
335
+ let_expr,
336
+ assert_expr,
337
+ echo_expr,
338
+ funclit_def,
339
+ ternary_expr,
340
+ prec_logical_or
341
+ ]
342
+
343
+
344
+ def let_expr():
345
+ return (TOK_LET, '(', assignments_expr, ')', expr)
346
+
347
+
348
+ def assert_expr():
349
+ return (TOK_ASSERT, '(', arguments, ')', Optional(expr))
350
+
351
+
352
+ def echo_expr():
353
+ return (TOK_ECHO, '(', arguments, ')', Optional(expr))
354
+
355
+
356
+ def funclit_def():
357
+ return (TOK_FUNCTION, '(', parameters, ')', expr)
358
+
359
+
360
+ def ternary_expr():
361
+ return (prec_logical_or, '?', expr, ':', expr)
362
+
363
+
364
+ def prec_logical_or():
365
+ return OneOrMore(prec_logical_and, sep=TOK_LOGICAL_OR)
366
+
367
+
368
+ def prec_logical_and():
369
+ return OneOrMore(prec_equality, sep=TOK_LOGICAL_AND)
370
+
371
+
372
+ def prec_equality():
373
+ return OneOrMore(prec_comparison, sep=[TOK_EQUAL, TOK_NOTEQUAL])
374
+
375
+
376
+ def prec_comparison():
377
+ return OneOrMore(prec_binary_or, sep=[TOK_LTE, TOK_GTE, TOK_LT, TOK_GT])
378
+
379
+
380
+ def prec_binary_or():
381
+ return OneOrMore(prec_binary_and, sep=TOK_BINARY_OR)
382
+
383
+
384
+ def prec_binary_and():
385
+ return OneOrMore(prec_binary_shift, sep=TOK_BINARY_AND)
386
+
387
+
388
+ def prec_binary_shift():
389
+ return OneOrMore(prec_addition, sep=[TOK_BINARY_SHIFT_LEFT, TOK_BINARY_SHIFT_RIGHT])
390
+
391
+
392
+ def prec_addition():
393
+ return OneOrMore(prec_multiplication, sep=['+', '-'])
394
+
395
+
396
+ def prec_multiplication():
397
+ return OneOrMore(prec_unary, sep=['*', '/', '%'])
398
+
399
+
400
+ def prec_unary():
401
+ return (ZeroOrMore(['+', '-', TOK_LOGICAL_NOT, TOK_BINARY_NOT]), prec_exponent)
402
+
403
+
404
+ def prec_exponent():
405
+ return [
406
+ (prec_call, '^', prec_unary),
407
+ prec_call
408
+ ]
409
+
410
+
411
+ def prec_call():
412
+ return (primary, ZeroOrMore([call_expr, lookup_expr, member_expr]))
413
+
414
+
415
+ def call_expr():
416
+ return ('(', arguments, ')')
417
+
418
+
419
+ def lookup_expr():
420
+ return ('[', expr, ']')
421
+
422
+
423
+ def member_expr():
424
+ return ('.', TOK_ID)
425
+
426
+
427
+ def primary():
428
+ return [
429
+ ('(', expr, ')'),
430
+ ('[', expr, ':', expr, Optional(':', expr), ']'),
431
+ ('[', vector_elements, Optional(TOK_COMMA), ']'),
432
+ TOK_UNDEF,
433
+ TOK_TRUE,
434
+ TOK_FALSE,
435
+ TOK_STRING,
436
+ TOK_NUMBER,
437
+ TOK_ID
438
+ ]
439
+
440
+
441
+ # --- Vector and list comprehension ---
442
+
443
+ def vector_elements():
444
+ return ZeroOrMore(vector_element, sep=TOK_COMMA)
445
+
446
+
447
+ def vector_element():
448
+ return [listcomp_elements, expr]
449
+
450
+
451
+ def listcomp_elements():
452
+ return [
453
+ ('(', listcomp_elements, ')'),
454
+ listcomp_let,
455
+ listcomp_each,
456
+ listcomp_for,
457
+ listcomp_ifelse,
458
+ ]
459
+
460
+
461
+ def listcomp_let():
462
+ return (TOK_LET, '(', assignments_expr, ')', listcomp_elements)
463
+
464
+
465
+ def listcomp_each():
466
+ return (TOK_EACH, vector_element)
467
+
468
+
469
+ def listcomp_for():
470
+ return [
471
+ (TOK_FOR, '(', assignments_expr, ';', expr, ';',
472
+ assignments_expr, ')', vector_element),
473
+ (TOK_FOR, '(', assignments_expr, ')', vector_element),
474
+ ]
475
+
476
+
477
+ def listcomp_ifelse():
478
+ return [
479
+ (TOK_IF, '(', expr, ')', vector_element, TOK_ELSE, vector_element),
480
+ (TOK_IF, '(', expr, ')', vector_element)
481
+ ]
482
+
483
+
484
+ # vim: set ts=4 sw=4 expandtab:
@@ -0,0 +1,34 @@
1
+ Metadata-Version: 2.4
2
+ Name: openscad_parser
3
+ Version: 0.9.2
4
+ Summary: A PEG parser to read OpenSCAD language source code.
5
+ Author-email: Revar Desmera <revarbat@gmail.com>
6
+ Maintainer-email: Revar Desmera <revarbat@gmail.com>
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/belfryscad/openscad_parser
9
+ Project-URL: Repository, https://github.com/belfryscad/openscad_parser
10
+ Project-URL: Bug Tracker, https://github.com/belfryscad/openscad_parser/issues
11
+ Project-URL: Releases, https://github.com/belfryscad/openscad_parser/releases
12
+ Project-URL: Usage, https://github.com/belfryscad/openscad_parser/README.rst
13
+ Project-URL: Documentation, https://github.com/belfryscad/openscad_parser/WRITING_DOCS.md
14
+ Keywords: openscad,openscad parser,parser
15
+ Classifier: Development Status :: 4 - Beta
16
+ Classifier: Environment :: Console
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Intended Audience :: Manufacturing
19
+ Classifier: Operating System :: MacOS :: MacOS X
20
+ Classifier: Operating System :: Microsoft :: Windows
21
+ Classifier: Operating System :: POSIX
22
+ Classifier: Programming Language :: Python :: 3
23
+ Classifier: Topic :: Artistic Software
24
+ Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
25
+ Classifier: Topic :: Multimedia :: Graphics :: 3D Rendering
26
+ Classifier: Topic :: Software Development :: Libraries
27
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
+ Requires-Python: >=3.7
29
+ Description-Content-Type: text/x-rst
30
+ License-File: LICENSE
31
+ Requires-Dist: arpeggio>=2.0.3
32
+ Provides-Extra: dev
33
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
34
+ Dynamic: license-file
@@ -0,0 +1,6 @@
1
+ openscad_parser/__init__.py,sha256=hKNgLYMjgrwrIlLC2EnxkTjw2cQaKhtZu2e9ZITHUSI,8813
2
+ openscad_parser-0.9.2.dist-info/licenses/LICENSE,sha256=N5Lw8pkdPzzYkAvuqPTtqP76sRGLHnVYrOKhY9w4aWo,1082
3
+ openscad_parser-0.9.2.dist-info/METADATA,sha256=FeWCZVTZWb9-gQNBs4ZTKe2SYHM2NpLyhzZCF3upgoc,1595
4
+ openscad_parser-0.9.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
+ openscad_parser-0.9.2.dist-info/top_level.txt,sha256=Jm01hgOXBGEBiYRGDw9rc3PArzW1ER15xoBoHC-dQT4,16
6
+ openscad_parser-0.9.2.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Belfry OpenSCAD Libraries
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ openscad_parser