pydpm_xl 0.1.39rc31__py3-none-any.whl → 0.2.0__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.
Files changed (123) hide show
  1. py_dpm/__init__.py +1 -1
  2. py_dpm/api/__init__.py +58 -189
  3. py_dpm/api/dpm/__init__.py +20 -0
  4. py_dpm/api/{data_dictionary.py → dpm/data_dictionary.py} +903 -984
  5. py_dpm/api/dpm/explorer.py +236 -0
  6. py_dpm/api/dpm/hierarchical_queries.py +142 -0
  7. py_dpm/api/{migration.py → dpm/migration.py} +16 -19
  8. py_dpm/api/{operation_scopes.py → dpm/operation_scopes.py} +319 -267
  9. py_dpm/api/dpm_xl/__init__.py +25 -0
  10. py_dpm/api/{ast_generator.py → dpm_xl/ast_generator.py} +3 -3
  11. py_dpm/api/{complete_ast.py → dpm_xl/complete_ast.py} +192 -168
  12. py_dpm/api/dpm_xl/semantic.py +354 -0
  13. py_dpm/api/{syntax.py → dpm_xl/syntax.py} +6 -5
  14. py_dpm/api/explorer.py +4 -0
  15. py_dpm/api/semantic.py +30 -306
  16. py_dpm/cli/__init__.py +9 -0
  17. py_dpm/{client.py → cli/main.py} +8 -8
  18. py_dpm/dpm/__init__.py +11 -0
  19. py_dpm/{models.py → dpm/models.py} +112 -88
  20. py_dpm/dpm/queries/base.py +100 -0
  21. py_dpm/dpm/queries/basic_objects.py +33 -0
  22. py_dpm/dpm/queries/explorer_queries.py +352 -0
  23. py_dpm/dpm/queries/filters.py +139 -0
  24. py_dpm/dpm/queries/glossary.py +45 -0
  25. py_dpm/dpm/queries/hierarchical_queries.py +838 -0
  26. py_dpm/dpm/queries/tables.py +133 -0
  27. py_dpm/dpm/utils.py +356 -0
  28. py_dpm/dpm_xl/__init__.py +8 -0
  29. py_dpm/dpm_xl/ast/__init__.py +14 -0
  30. py_dpm/{AST/ASTConstructor.py → dpm_xl/ast/constructor.py} +6 -6
  31. py_dpm/{AST/MLGeneration.py → dpm_xl/ast/ml_generation.py} +137 -87
  32. py_dpm/{AST/ModuleAnalyzer.py → dpm_xl/ast/module_analyzer.py} +7 -7
  33. py_dpm/{AST/ModuleDependencies.py → dpm_xl/ast/module_dependencies.py} +56 -41
  34. py_dpm/{AST/ASTObjects.py → dpm_xl/ast/nodes.py} +1 -1
  35. py_dpm/{AST/check_operands.py → dpm_xl/ast/operands.py} +16 -13
  36. py_dpm/{AST/ASTTemplate.py → dpm_xl/ast/template.py} +2 -2
  37. py_dpm/{AST/WhereClauseChecker.py → dpm_xl/ast/where_clause.py} +2 -2
  38. py_dpm/dpm_xl/grammar/__init__.py +18 -0
  39. py_dpm/dpm_xl/operators/__init__.py +19 -0
  40. py_dpm/{Operators/AggregateOperators.py → dpm_xl/operators/aggregate.py} +7 -7
  41. py_dpm/{Operators/NumericOperators.py → dpm_xl/operators/arithmetic.py} +6 -6
  42. py_dpm/{Operators/Operator.py → dpm_xl/operators/base.py} +5 -5
  43. py_dpm/{Operators/BooleanOperators.py → dpm_xl/operators/boolean.py} +5 -5
  44. py_dpm/{Operators/ClauseOperators.py → dpm_xl/operators/clause.py} +8 -8
  45. py_dpm/{Operators/ComparisonOperators.py → dpm_xl/operators/comparison.py} +5 -5
  46. py_dpm/{Operators/ConditionalOperators.py → dpm_xl/operators/conditional.py} +7 -7
  47. py_dpm/{Operators/StringOperators.py → dpm_xl/operators/string.py} +5 -5
  48. py_dpm/{Operators/TimeOperators.py → dpm_xl/operators/time.py} +6 -6
  49. py_dpm/{semantics/SemanticAnalyzer.py → dpm_xl/semantic_analyzer.py} +168 -68
  50. py_dpm/{semantics/Symbols.py → dpm_xl/symbols.py} +3 -3
  51. py_dpm/dpm_xl/types/__init__.py +13 -0
  52. py_dpm/{DataTypes/TypePromotion.py → dpm_xl/types/promotion.py} +2 -2
  53. py_dpm/{DataTypes/ScalarTypes.py → dpm_xl/types/scalar.py} +2 -2
  54. py_dpm/dpm_xl/utils/__init__.py +14 -0
  55. py_dpm/{data_handlers.py → dpm_xl/utils/data_handlers.py} +2 -2
  56. py_dpm/{Utils → dpm_xl/utils}/operands_mapping.py +1 -1
  57. py_dpm/{Utils → dpm_xl/utils}/operator_mapping.py +8 -8
  58. py_dpm/{OperationScopes/OperationScopeService.py → dpm_xl/utils/scopes_calculator.py} +148 -58
  59. py_dpm/{Utils/ast_serialization.py → dpm_xl/utils/serialization.py} +2 -2
  60. py_dpm/dpm_xl/validation/__init__.py +12 -0
  61. py_dpm/{Utils/ValidationsGenerationUtils.py → dpm_xl/validation/generation_utils.py} +2 -3
  62. py_dpm/{ValidationsGeneration/PropertiesConstraintsProcessor.py → dpm_xl/validation/property_constraints.py} +56 -21
  63. py_dpm/{ValidationsGeneration/auxiliary_functions.py → dpm_xl/validation/utils.py} +2 -2
  64. py_dpm/{ValidationsGeneration/VariantsProcessor.py → dpm_xl/validation/variants.py} +149 -55
  65. py_dpm/exceptions/__init__.py +23 -0
  66. py_dpm/{Exceptions → exceptions}/exceptions.py +7 -2
  67. pydpm_xl-0.2.0.dist-info/METADATA +278 -0
  68. pydpm_xl-0.2.0.dist-info/RECORD +88 -0
  69. pydpm_xl-0.2.0.dist-info/entry_points.txt +2 -0
  70. py_dpm/Exceptions/__init__.py +0 -0
  71. py_dpm/OperationScopes/__init__.py +0 -0
  72. py_dpm/Operators/__init__.py +0 -0
  73. py_dpm/Utils/__init__.py +0 -0
  74. py_dpm/Utils/utils.py +0 -2
  75. py_dpm/ValidationsGeneration/Utils.py +0 -364
  76. py_dpm/ValidationsGeneration/__init__.py +0 -0
  77. py_dpm/api/data_dictionary_validation.py +0 -614
  78. py_dpm/db_utils.py +0 -221
  79. py_dpm/grammar/__init__.py +0 -0
  80. py_dpm/grammar/dist/__init__.py +0 -0
  81. py_dpm/grammar/dpm_xlLexer.g4 +0 -437
  82. py_dpm/grammar/dpm_xlParser.g4 +0 -263
  83. py_dpm/semantics/DAG/DAGAnalyzer.py +0 -158
  84. py_dpm/semantics/DAG/__init__.py +0 -0
  85. py_dpm/semantics/__init__.py +0 -0
  86. py_dpm/views/data_types.sql +0 -12
  87. py_dpm/views/datapoints.sql +0 -65
  88. py_dpm/views/hierarchy_operand_reference.sql +0 -11
  89. py_dpm/views/hierarchy_preconditions.sql +0 -13
  90. py_dpm/views/hierarchy_variables.sql +0 -26
  91. py_dpm/views/hierarchy_variables_context.sql +0 -14
  92. py_dpm/views/key_components.sql +0 -18
  93. py_dpm/views/module_from_table.sql +0 -11
  94. py_dpm/views/open_keys.sql +0 -13
  95. py_dpm/views/operation_info.sql +0 -27
  96. py_dpm/views/operation_list.sql +0 -18
  97. py_dpm/views/operations_versions_from_module_version.sql +0 -30
  98. py_dpm/views/precondition_info.sql +0 -17
  99. py_dpm/views/report_type_operand_reference_info.sql +0 -18
  100. py_dpm/views/subcategory_info.sql +0 -17
  101. py_dpm/views/table_info.sql +0 -19
  102. pydpm_xl-0.1.39rc31.dist-info/METADATA +0 -53
  103. pydpm_xl-0.1.39rc31.dist-info/RECORD +0 -96
  104. pydpm_xl-0.1.39rc31.dist-info/entry_points.txt +0 -2
  105. /py_dpm/{AST → cli/commands}/__init__.py +0 -0
  106. /py_dpm/{migration.py → dpm/migration.py} +0 -0
  107. /py_dpm/{AST/ASTVisitor.py → dpm_xl/ast/visitor.py} +0 -0
  108. /py_dpm/{DataTypes → dpm_xl/grammar/generated}/__init__.py +0 -0
  109. /py_dpm/{grammar/dist → dpm_xl/grammar/generated}/dpm_xlLexer.interp +0 -0
  110. /py_dpm/{grammar/dist → dpm_xl/grammar/generated}/dpm_xlLexer.py +0 -0
  111. /py_dpm/{grammar/dist → dpm_xl/grammar/generated}/dpm_xlLexer.tokens +0 -0
  112. /py_dpm/{grammar/dist → dpm_xl/grammar/generated}/dpm_xlParser.interp +0 -0
  113. /py_dpm/{grammar/dist → dpm_xl/grammar/generated}/dpm_xlParser.py +0 -0
  114. /py_dpm/{grammar/dist → dpm_xl/grammar/generated}/dpm_xlParser.tokens +0 -0
  115. /py_dpm/{grammar/dist → dpm_xl/grammar/generated}/dpm_xlParserListener.py +0 -0
  116. /py_dpm/{grammar/dist → dpm_xl/grammar/generated}/dpm_xlParserVisitor.py +0 -0
  117. /py_dpm/{grammar/dist → dpm_xl/grammar/generated}/listeners.py +0 -0
  118. /py_dpm/{DataTypes/TimeClasses.py → dpm_xl/types/time.py} +0 -0
  119. /py_dpm/{Utils → dpm_xl/utils}/tokens.py +0 -0
  120. /py_dpm/{Exceptions → exceptions}/messages.py +0 -0
  121. {pydpm_xl-0.1.39rc31.dist-info → pydpm_xl-0.2.0.dist-info}/WHEEL +0 -0
  122. {pydpm_xl-0.1.39rc31.dist-info → pydpm_xl-0.2.0.dist-info}/licenses/LICENSE +0 -0
  123. {pydpm_xl-0.1.39rc31.dist-info → pydpm_xl-0.2.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,354 @@
1
+ from typing import Dict, Any, Optional
2
+ from dataclasses import dataclass
3
+
4
+ # Import directly to avoid circular imports
5
+ from antlr4 import CommonTokenStream, InputStream
6
+ from py_dpm.dpm_xl.grammar.generated.dpm_xlLexer import dpm_xlLexer
7
+ from py_dpm.dpm_xl.grammar.generated.dpm_xlParser import dpm_xlParser
8
+ from py_dpm.dpm_xl.grammar.generated.listeners import DPMErrorListener
9
+ from py_dpm.dpm_xl.ast.constructor import ASTVisitor
10
+ from py_dpm.dpm_xl.ast.operands import OperandsChecking
11
+ from py_dpm.dpm_xl import semantic_analyzer as SemanticAnalyzer
12
+ from py_dpm.dpm.utils import get_session, get_engine
13
+ from py_dpm.exceptions.exceptions import SemanticError
14
+
15
+
16
+ @dataclass
17
+ class SemanticValidationResult:
18
+ """
19
+ Result of semantic validation.
20
+
21
+ Attributes:
22
+ is_valid (bool): Whether the semantic validation passed
23
+ error_message (Optional[str]): Error message if validation failed
24
+ error_code (Optional[str]): Error code if validation failed
25
+ expression (str): The original expression that was validated
26
+ validation_type (str): Type of validation performed
27
+ results (Optional[Any]): Additional results from semantic analysis
28
+ """
29
+
30
+ is_valid: bool
31
+ error_message: Optional[str]
32
+ error_code: Optional[str]
33
+ expression: str
34
+ validation_type: str
35
+ results: Optional[Any] = None
36
+
37
+
38
+ class SemanticAPI:
39
+ """
40
+ API for DPM-XL semantic validation and analysis.
41
+
42
+ This class provides methods to perform semantic analysis on DPM-XL expressions,
43
+ including operand checking, data type validation, and structure validation.
44
+ """
45
+
46
+ def __init__(
47
+ self, database_path: Optional[str] = None, connection_url: Optional[str] = None
48
+ ):
49
+ """
50
+ Initialize the Semantic API.
51
+
52
+ Args:
53
+ database_path (Optional[str]): Path to SQLite database. If None, uses default from environment.
54
+ connection_url (Optional[str]): Full SQLAlchemy connection URL (e.g., postgresql://user:pass@host:port/db).
55
+ Takes precedence over database_path.
56
+ """
57
+ self.database_path = database_path
58
+ self.connection_url = connection_url
59
+
60
+ if connection_url:
61
+ # Create isolated engine and session for the provided connection URL
62
+ from sqlalchemy.orm import sessionmaker
63
+ from py_dpm.dpm.utils import create_engine_from_url
64
+
65
+ # Create engine for the connection URL (supports SQLite, PostgreSQL, MySQL, etc.)
66
+ self.engine = create_engine_from_url(connection_url)
67
+ session_maker = sessionmaker(bind=self.engine)
68
+ self.session = session_maker()
69
+
70
+ elif database_path:
71
+ # Create isolated engine and session for this specific database
72
+ from sqlalchemy import create_engine
73
+ from sqlalchemy.orm import sessionmaker
74
+ import os
75
+
76
+ # Create the database directory if it doesn't exist
77
+ db_dir = os.path.dirname(database_path)
78
+ if db_dir and not os.path.exists(db_dir):
79
+ os.makedirs(db_dir)
80
+
81
+ # Create engine for specific database path
82
+ db_connection_url = f"sqlite:///{database_path}"
83
+ self.engine = create_engine(db_connection_url, pool_pre_ping=True)
84
+ session_maker = sessionmaker(bind=self.engine)
85
+ self.session = session_maker()
86
+ else:
87
+ # Use default global connection
88
+ get_engine()
89
+ self.session = get_session()
90
+ self.engine = None
91
+
92
+ self.error_listener = DPMErrorListener()
93
+ self.visitor = ASTVisitor()
94
+
95
+ def validate_expression(
96
+ self, expression: str, release_id: Optional[int] = None
97
+ ) -> SemanticValidationResult:
98
+ """
99
+ Perform semantic validation on a DPM-XL expression.
100
+
101
+ This includes syntax validation, operands checking, data type validation,
102
+ and structure validation.
103
+
104
+ Args:
105
+ expression (str): The DPM-XL expression to validate
106
+ release_id (Optional[int]): Specific release ID for component filtering.
107
+ If None, uses live/latest release (EndReleaseID IS NULL).
108
+
109
+ Returns:
110
+ SemanticValidationResult: Result containing validation status and details
111
+
112
+ Example:
113
+ >>> from pydpm.api import SemanticAPI
114
+ >>> semantic = SemanticAPI()
115
+ >>> result = semantic.validate_expression("{tC_01.00, r0100, c0010} + {tC_01.00, r0200, c0010}")
116
+ >>> print(result.is_valid)
117
+ True
118
+
119
+ >>> # Validate for specific release
120
+ >>> result = semantic.validate_expression("{tC_01.00, r0100, c0010}", release_id=5)
121
+ """
122
+ try:
123
+ # Parse expression to AST
124
+ input_stream = InputStream(expression)
125
+ lexer = dpm_xlLexer(input_stream)
126
+ lexer._listeners = [self.error_listener]
127
+ token_stream = CommonTokenStream(lexer)
128
+
129
+ parser = dpm_xlParser(token_stream)
130
+ parser._listeners = [self.error_listener]
131
+ parse_tree = parser.start()
132
+
133
+ if parser._syntaxErrors > 0:
134
+ return SemanticValidationResult(
135
+ is_valid=False,
136
+ error_message="Syntax errors detected",
137
+ error_code="SYNTAX_ERROR",
138
+ expression=expression,
139
+ validation_type="SEMANTIC",
140
+ )
141
+
142
+ # Generate AST
143
+ ast = self.visitor.visit(parse_tree)
144
+
145
+ # Perform semantic analysis
146
+ oc = OperandsChecking(
147
+ session=self.session,
148
+ expression=expression,
149
+ ast=ast,
150
+ release_id=release_id,
151
+ )
152
+ semanticAnalysis = SemanticAnalyzer.InputAnalyzer(expression)
153
+
154
+ semanticAnalysis.data = oc.data
155
+ semanticAnalysis.key_components = oc.key_components
156
+ semanticAnalysis.open_keys = oc.open_keys
157
+ semanticAnalysis.preconditions = oc.preconditions
158
+
159
+ results = semanticAnalysis.visit(ast)
160
+
161
+ return SemanticValidationResult(
162
+ is_valid=True,
163
+ error_message=None,
164
+ error_code=None,
165
+ expression=expression,
166
+ validation_type="SEMANTIC",
167
+ results=results,
168
+ )
169
+
170
+ except SemanticError as e:
171
+ return SemanticValidationResult(
172
+ is_valid=False,
173
+ error_message=str(e),
174
+ error_code=getattr(e, "code", None),
175
+ expression=expression,
176
+ validation_type="SEMANTIC",
177
+ )
178
+ except Exception as e:
179
+ return SemanticValidationResult(
180
+ is_valid=False,
181
+ error_message=str(e),
182
+ error_code="UNKNOWN",
183
+ expression=expression,
184
+ validation_type="SEMANTIC",
185
+ )
186
+
187
+ def analyze_expression(
188
+ self, expression: str, release_id: Optional[int] = None
189
+ ) -> Dict[str, Any]:
190
+ """
191
+ Perform detailed semantic analysis on a DPM-XL expression.
192
+
193
+ Args:
194
+ expression (str): The DPM-XL expression to analyze
195
+ release_id (Optional[int]): Specific release ID for component filtering.
196
+ If None, uses live/latest release.
197
+
198
+ Returns:
199
+ Dict[str, Any]: Detailed analysis results
200
+
201
+ Raises:
202
+ Exception: If analysis fails
203
+
204
+ Example:
205
+ >>> from pydpm.api import SemanticAPI
206
+ >>> semantic = SemanticAPI()
207
+ >>> analysis = semantic.analyze_expression("{tC_01.00, r0100, c0010}")
208
+ >>> # Analyze for specific release
209
+ >>> analysis = semantic.analyze_expression("{tC_01.00, r0100, c0010}", release_id=5)
210
+ """
211
+ result = self.validate_expression(expression, release_id=release_id)
212
+
213
+ if not result.is_valid:
214
+ raise Exception(f"Semantic analysis failed: {result.error_message}")
215
+
216
+ # Extract additional analysis information
217
+ analysis = {
218
+ "expression": expression,
219
+ "is_valid": True,
220
+ "results": result.results,
221
+ "data_types": (
222
+ getattr(result.results, "type", None) if result.results else None
223
+ ),
224
+ "components": (
225
+ getattr(result.results, "components", None) if result.results else None
226
+ ),
227
+ }
228
+
229
+ return analysis
230
+
231
+ def is_valid_semantics(
232
+ self, expression: str, release_id: Optional[int] = None
233
+ ) -> bool:
234
+ """
235
+ Quick check if expression has valid semantics.
236
+
237
+ Args:
238
+ expression (str): The DPM-XL expression to check
239
+ release_id (Optional[int]): Specific release ID for component filtering.
240
+ If None, uses live/latest release.
241
+
242
+ Returns:
243
+ bool: True if semantics are valid, False otherwise
244
+
245
+ Example:
246
+ >>> from pydpm.api import SemanticAPI
247
+ >>> semantic = SemanticAPI()
248
+ >>> is_valid = semantic.is_valid_semantics("{tC_01.00, r0100, c0010}")
249
+ >>> # Check for specific release
250
+ >>> is_valid = semantic.is_valid_semantics("{tC_01.00, r0100, c0010}", release_id=5)
251
+ """
252
+ result = self.validate_expression(expression, release_id=release_id)
253
+ return result.is_valid
254
+
255
+ def __del__(self):
256
+ """Clean up resources."""
257
+ try:
258
+ if hasattr(self, "session") and self.session:
259
+ self.session.close()
260
+ except Exception:
261
+ pass
262
+
263
+ try:
264
+ if hasattr(self, "engine") and self.engine is not None:
265
+ self.engine.dispose()
266
+ except Exception:
267
+ pass
268
+
269
+ def close(self):
270
+ """
271
+ Explicitly close the underlying SQLAlchemy session and dispose any private engine.
272
+ """
273
+ try:
274
+ if hasattr(self, "session") and self.session:
275
+ self.session.close()
276
+ except Exception:
277
+ pass
278
+
279
+ try:
280
+ if hasattr(self, "engine") and self.engine is not None:
281
+ self.engine.dispose()
282
+ except Exception:
283
+ pass
284
+
285
+ def __enter__(self):
286
+ return self
287
+
288
+ def __exit__(self, exc_type, exc_val, exc_tb):
289
+ self.close()
290
+
291
+
292
+ # Convenience functions for direct usage
293
+ def validate_expression(
294
+ expression: str,
295
+ database_path: Optional[str] = None,
296
+ connection_url: Optional[str] = None,
297
+ release_id: Optional[int] = None,
298
+ ) -> SemanticValidationResult:
299
+ """
300
+ Convenience function to validate DPM-XL expression semantics.
301
+
302
+ Args:
303
+ expression (str): The DPM-XL expression to validate
304
+ database_path (Optional[str]): Path to SQLite database. If None, uses default from environment.
305
+ connection_url (Optional[str]): Full SQLAlchemy connection URL (e.g., postgresql://user:pass@host:port/db).
306
+ release_id (Optional[int]): Specific release ID for component filtering.
307
+ If None, uses live/latest release.
308
+
309
+ Returns:
310
+ SemanticValidationResult: Result containing validation status and details
311
+
312
+ Example:
313
+ >>> from pydpm.api.semantic import validate_expression
314
+ >>> result = validate_expression("{tC_01.00, r0100, c0010}", database_path="./database.db")
315
+ >>> # Using PostgreSQL
316
+ >>> result = validate_expression("{tC_01.00, r0100, c0010}",
317
+ ... connection_url="postgresql://user:pass@host:5432/db")
318
+ >>> # Validate for specific release
319
+ >>> result = validate_expression("{tC_01.00, r0100, c0010}", database_path="./database.db", release_id=5)
320
+ """
321
+ api = SemanticAPI(database_path=database_path, connection_url=connection_url)
322
+ return api.validate_expression(expression, release_id=release_id)
323
+
324
+
325
+ def is_valid_semantics(
326
+ expression: str,
327
+ database_path: Optional[str] = None,
328
+ connection_url: Optional[str] = None,
329
+ release_id: Optional[int] = None,
330
+ ) -> bool:
331
+ """
332
+ Convenience function to check if expression has valid semantics.
333
+
334
+ Args:
335
+ expression (str): The DPM-XL expression to check
336
+ database_path (Optional[str]): Path to SQLite database. If None, uses default from environment.
337
+ connection_url (Optional[str]): Full SQLAlchemy connection URL (e.g., postgresql://user:pass@host:port/db).
338
+ release_id (Optional[int]): Specific release ID for component filtering.
339
+ If None, uses live/latest release.
340
+
341
+ Returns:
342
+ bool: True if semantics are valid, False otherwise
343
+
344
+ Example:
345
+ >>> from pydpm.api.semantic import is_valid_semantics
346
+ >>> is_valid = is_valid_semantics("{tC_01.00, r0100, c0010}", database_path="./database.db")
347
+ >>> # Using PostgreSQL
348
+ >>> is_valid = is_valid_semantics("{tC_01.00, r0100, c0010}",
349
+ ... connection_url="postgresql://user:pass@host:5432/db")
350
+ >>> # Check for specific release
351
+ >>> is_valid = is_valid_semantics("{tC_01.00, r0100, c0010}", database_path="./database.db", release_id=5)
352
+ """
353
+ api = SemanticAPI(database_path=database_path, connection_url=connection_url)
354
+ return api.is_valid_semantics(expression, release_id=release_id)
@@ -3,10 +3,10 @@ from dataclasses import dataclass
3
3
 
4
4
  # Import directly to avoid circular imports
5
5
  from antlr4 import CommonTokenStream, InputStream
6
- from py_dpm.grammar.dist.dpm_xlLexer import dpm_xlLexer
7
- from py_dpm.grammar.dist.dpm_xlParser import dpm_xlParser
8
- from py_dpm.grammar.dist.listeners import DPMErrorListener
9
- from py_dpm.AST.ASTConstructor import ASTVisitor
6
+ from py_dpm.dpm_xl.grammar.generated.dpm_xlLexer import dpm_xlLexer
7
+ from py_dpm.dpm_xl.grammar.generated.dpm_xlParser import dpm_xlParser
8
+ from py_dpm.dpm_xl.grammar.generated.listeners import DPMErrorListener
9
+ from py_dpm.dpm_xl.ast.constructor import ASTVisitor
10
10
 
11
11
 
12
12
  @dataclass
@@ -123,7 +123,7 @@ class SyntaxAPI:
123
123
 
124
124
  def is_valid_syntax(self, expression: str) -> bool:
125
125
  """
126
- Quick check if expression has valid syntax.
126
+ Quick check if expression has valid syntax.
127
127
 
128
128
  Args:
129
129
  expression (str): The DPM-XL expression to check
@@ -180,3 +180,4 @@ def is_valid_syntax(expression: str) -> bool:
180
180
  """
181
181
  api = SyntaxAPI()
182
182
  return api.is_valid_syntax(expression)
183
+
py_dpm/api/explorer.py ADDED
@@ -0,0 +1,4 @@
1
+ from py_dpm.api.dpm.explorer import ExplorerQueryAPI
2
+
3
+ __all__ = ["ExplorerQueryAPI"]
4
+