aiecs 1.0.1__py3-none-any.whl → 1.7.6__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.
Potentially problematic release.
This version of aiecs might be problematic. Click here for more details.
- aiecs/__init__.py +13 -16
- aiecs/__main__.py +7 -7
- aiecs/aiecs_client.py +269 -75
- aiecs/application/executors/operation_executor.py +79 -54
- aiecs/application/knowledge_graph/__init__.py +7 -0
- aiecs/application/knowledge_graph/builder/__init__.py +37 -0
- aiecs/application/knowledge_graph/builder/data_quality.py +302 -0
- aiecs/application/knowledge_graph/builder/data_reshaping.py +293 -0
- aiecs/application/knowledge_graph/builder/document_builder.py +369 -0
- aiecs/application/knowledge_graph/builder/graph_builder.py +490 -0
- aiecs/application/knowledge_graph/builder/import_optimizer.py +396 -0
- aiecs/application/knowledge_graph/builder/schema_inference.py +462 -0
- aiecs/application/knowledge_graph/builder/schema_mapping.py +563 -0
- aiecs/application/knowledge_graph/builder/structured_pipeline.py +1384 -0
- aiecs/application/knowledge_graph/builder/text_chunker.py +317 -0
- aiecs/application/knowledge_graph/extractors/__init__.py +27 -0
- aiecs/application/knowledge_graph/extractors/base.py +98 -0
- aiecs/application/knowledge_graph/extractors/llm_entity_extractor.py +422 -0
- aiecs/application/knowledge_graph/extractors/llm_relation_extractor.py +347 -0
- aiecs/application/knowledge_graph/extractors/ner_entity_extractor.py +241 -0
- aiecs/application/knowledge_graph/fusion/__init__.py +78 -0
- aiecs/application/knowledge_graph/fusion/ab_testing.py +395 -0
- aiecs/application/knowledge_graph/fusion/abbreviation_expander.py +327 -0
- aiecs/application/knowledge_graph/fusion/alias_index.py +597 -0
- aiecs/application/knowledge_graph/fusion/alias_matcher.py +384 -0
- aiecs/application/knowledge_graph/fusion/cache_coordinator.py +343 -0
- aiecs/application/knowledge_graph/fusion/entity_deduplicator.py +433 -0
- aiecs/application/knowledge_graph/fusion/entity_linker.py +511 -0
- aiecs/application/knowledge_graph/fusion/evaluation_dataset.py +240 -0
- aiecs/application/knowledge_graph/fusion/knowledge_fusion.py +632 -0
- aiecs/application/knowledge_graph/fusion/matching_config.py +489 -0
- aiecs/application/knowledge_graph/fusion/name_normalizer.py +352 -0
- aiecs/application/knowledge_graph/fusion/relation_deduplicator.py +183 -0
- aiecs/application/knowledge_graph/fusion/semantic_name_matcher.py +464 -0
- aiecs/application/knowledge_graph/fusion/similarity_pipeline.py +534 -0
- aiecs/application/knowledge_graph/pattern_matching/__init__.py +21 -0
- aiecs/application/knowledge_graph/pattern_matching/pattern_matcher.py +342 -0
- aiecs/application/knowledge_graph/pattern_matching/query_executor.py +366 -0
- aiecs/application/knowledge_graph/profiling/__init__.py +12 -0
- aiecs/application/knowledge_graph/profiling/query_plan_visualizer.py +195 -0
- aiecs/application/knowledge_graph/profiling/query_profiler.py +223 -0
- aiecs/application/knowledge_graph/reasoning/__init__.py +27 -0
- aiecs/application/knowledge_graph/reasoning/evidence_synthesis.py +341 -0
- aiecs/application/knowledge_graph/reasoning/inference_engine.py +500 -0
- aiecs/application/knowledge_graph/reasoning/logic_form_parser.py +163 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/__init__.py +79 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_builder.py +513 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_nodes.py +913 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_validator.py +866 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/error_handler.py +475 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/parser.py +396 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/query_context.py +208 -0
- aiecs/application/knowledge_graph/reasoning/logic_query_integration.py +170 -0
- aiecs/application/knowledge_graph/reasoning/query_planner.py +855 -0
- aiecs/application/knowledge_graph/reasoning/reasoning_engine.py +518 -0
- aiecs/application/knowledge_graph/retrieval/__init__.py +27 -0
- aiecs/application/knowledge_graph/retrieval/query_intent_classifier.py +211 -0
- aiecs/application/knowledge_graph/retrieval/retrieval_strategies.py +592 -0
- aiecs/application/knowledge_graph/retrieval/strategy_types.py +23 -0
- aiecs/application/knowledge_graph/search/__init__.py +59 -0
- aiecs/application/knowledge_graph/search/hybrid_search.py +457 -0
- aiecs/application/knowledge_graph/search/reranker.py +293 -0
- aiecs/application/knowledge_graph/search/reranker_strategies.py +535 -0
- aiecs/application/knowledge_graph/search/text_similarity.py +392 -0
- aiecs/application/knowledge_graph/traversal/__init__.py +15 -0
- aiecs/application/knowledge_graph/traversal/enhanced_traversal.py +305 -0
- aiecs/application/knowledge_graph/traversal/path_scorer.py +271 -0
- aiecs/application/knowledge_graph/validators/__init__.py +13 -0
- aiecs/application/knowledge_graph/validators/relation_validator.py +239 -0
- aiecs/application/knowledge_graph/visualization/__init__.py +11 -0
- aiecs/application/knowledge_graph/visualization/graph_visualizer.py +313 -0
- aiecs/common/__init__.py +9 -0
- aiecs/common/knowledge_graph/__init__.py +17 -0
- aiecs/common/knowledge_graph/runnable.py +471 -0
- aiecs/config/__init__.py +20 -5
- aiecs/config/config.py +762 -31
- aiecs/config/graph_config.py +131 -0
- aiecs/config/tool_config.py +399 -0
- aiecs/core/__init__.py +29 -13
- aiecs/core/interface/__init__.py +2 -2
- aiecs/core/interface/execution_interface.py +22 -22
- aiecs/core/interface/storage_interface.py +37 -88
- aiecs/core/registry/__init__.py +31 -0
- aiecs/core/registry/service_registry.py +92 -0
- aiecs/domain/__init__.py +270 -1
- aiecs/domain/agent/__init__.py +191 -0
- aiecs/domain/agent/base_agent.py +3870 -0
- aiecs/domain/agent/exceptions.py +99 -0
- aiecs/domain/agent/graph_aware_mixin.py +569 -0
- aiecs/domain/agent/hybrid_agent.py +1435 -0
- aiecs/domain/agent/integration/__init__.py +29 -0
- aiecs/domain/agent/integration/context_compressor.py +216 -0
- aiecs/domain/agent/integration/context_engine_adapter.py +587 -0
- aiecs/domain/agent/integration/protocols.py +281 -0
- aiecs/domain/agent/integration/retry_policy.py +218 -0
- aiecs/domain/agent/integration/role_config.py +213 -0
- aiecs/domain/agent/knowledge_aware_agent.py +1892 -0
- aiecs/domain/agent/lifecycle.py +291 -0
- aiecs/domain/agent/llm_agent.py +692 -0
- aiecs/domain/agent/memory/__init__.py +12 -0
- aiecs/domain/agent/memory/conversation.py +1124 -0
- aiecs/domain/agent/migration/__init__.py +14 -0
- aiecs/domain/agent/migration/conversion.py +163 -0
- aiecs/domain/agent/migration/legacy_wrapper.py +86 -0
- aiecs/domain/agent/models.py +884 -0
- aiecs/domain/agent/observability.py +479 -0
- aiecs/domain/agent/persistence.py +449 -0
- aiecs/domain/agent/prompts/__init__.py +29 -0
- aiecs/domain/agent/prompts/builder.py +159 -0
- aiecs/domain/agent/prompts/formatters.py +187 -0
- aiecs/domain/agent/prompts/template.py +255 -0
- aiecs/domain/agent/registry.py +253 -0
- aiecs/domain/agent/tool_agent.py +444 -0
- aiecs/domain/agent/tools/__init__.py +15 -0
- aiecs/domain/agent/tools/schema_generator.py +364 -0
- aiecs/domain/community/__init__.py +155 -0
- aiecs/domain/community/agent_adapter.py +469 -0
- aiecs/domain/community/analytics.py +432 -0
- aiecs/domain/community/collaborative_workflow.py +648 -0
- aiecs/domain/community/communication_hub.py +634 -0
- aiecs/domain/community/community_builder.py +320 -0
- aiecs/domain/community/community_integration.py +796 -0
- aiecs/domain/community/community_manager.py +803 -0
- aiecs/domain/community/decision_engine.py +849 -0
- aiecs/domain/community/exceptions.py +231 -0
- aiecs/domain/community/models/__init__.py +33 -0
- aiecs/domain/community/models/community_models.py +234 -0
- aiecs/domain/community/resource_manager.py +461 -0
- aiecs/domain/community/shared_context_manager.py +589 -0
- aiecs/domain/context/__init__.py +40 -10
- aiecs/domain/context/context_engine.py +1910 -0
- aiecs/domain/context/conversation_models.py +87 -53
- aiecs/domain/context/graph_memory.py +582 -0
- aiecs/domain/execution/model.py +12 -4
- aiecs/domain/knowledge_graph/__init__.py +19 -0
- aiecs/domain/knowledge_graph/models/__init__.py +52 -0
- aiecs/domain/knowledge_graph/models/entity.py +148 -0
- aiecs/domain/knowledge_graph/models/evidence.py +178 -0
- aiecs/domain/knowledge_graph/models/inference_rule.py +184 -0
- aiecs/domain/knowledge_graph/models/path.py +171 -0
- aiecs/domain/knowledge_graph/models/path_pattern.py +171 -0
- aiecs/domain/knowledge_graph/models/query.py +261 -0
- aiecs/domain/knowledge_graph/models/query_plan.py +181 -0
- aiecs/domain/knowledge_graph/models/relation.py +202 -0
- aiecs/domain/knowledge_graph/schema/__init__.py +23 -0
- aiecs/domain/knowledge_graph/schema/entity_type.py +131 -0
- aiecs/domain/knowledge_graph/schema/graph_schema.py +253 -0
- aiecs/domain/knowledge_graph/schema/property_schema.py +143 -0
- aiecs/domain/knowledge_graph/schema/relation_type.py +163 -0
- aiecs/domain/knowledge_graph/schema/schema_manager.py +691 -0
- aiecs/domain/knowledge_graph/schema/type_enums.py +209 -0
- aiecs/domain/task/dsl_processor.py +172 -56
- aiecs/domain/task/model.py +20 -8
- aiecs/domain/task/task_context.py +27 -24
- aiecs/infrastructure/__init__.py +0 -2
- aiecs/infrastructure/graph_storage/__init__.py +11 -0
- aiecs/infrastructure/graph_storage/base.py +837 -0
- aiecs/infrastructure/graph_storage/batch_operations.py +458 -0
- aiecs/infrastructure/graph_storage/cache.py +424 -0
- aiecs/infrastructure/graph_storage/distributed.py +223 -0
- aiecs/infrastructure/graph_storage/error_handling.py +380 -0
- aiecs/infrastructure/graph_storage/graceful_degradation.py +294 -0
- aiecs/infrastructure/graph_storage/health_checks.py +378 -0
- aiecs/infrastructure/graph_storage/in_memory.py +1197 -0
- aiecs/infrastructure/graph_storage/index_optimization.py +446 -0
- aiecs/infrastructure/graph_storage/lazy_loading.py +431 -0
- aiecs/infrastructure/graph_storage/metrics.py +344 -0
- aiecs/infrastructure/graph_storage/migration.py +400 -0
- aiecs/infrastructure/graph_storage/pagination.py +483 -0
- aiecs/infrastructure/graph_storage/performance_monitoring.py +456 -0
- aiecs/infrastructure/graph_storage/postgres.py +1563 -0
- aiecs/infrastructure/graph_storage/property_storage.py +353 -0
- aiecs/infrastructure/graph_storage/protocols.py +76 -0
- aiecs/infrastructure/graph_storage/query_optimizer.py +642 -0
- aiecs/infrastructure/graph_storage/schema_cache.py +290 -0
- aiecs/infrastructure/graph_storage/sqlite.py +1373 -0
- aiecs/infrastructure/graph_storage/streaming.py +487 -0
- aiecs/infrastructure/graph_storage/tenant.py +412 -0
- aiecs/infrastructure/messaging/celery_task_manager.py +92 -54
- aiecs/infrastructure/messaging/websocket_manager.py +51 -35
- aiecs/infrastructure/monitoring/__init__.py +22 -0
- aiecs/infrastructure/monitoring/executor_metrics.py +45 -11
- aiecs/infrastructure/monitoring/global_metrics_manager.py +212 -0
- aiecs/infrastructure/monitoring/structured_logger.py +3 -7
- aiecs/infrastructure/monitoring/tracing_manager.py +63 -35
- aiecs/infrastructure/persistence/__init__.py +14 -1
- aiecs/infrastructure/persistence/context_engine_client.py +184 -0
- aiecs/infrastructure/persistence/database_manager.py +67 -43
- aiecs/infrastructure/persistence/file_storage.py +180 -103
- aiecs/infrastructure/persistence/redis_client.py +74 -21
- aiecs/llm/__init__.py +73 -25
- aiecs/llm/callbacks/__init__.py +11 -0
- aiecs/llm/{custom_callbacks.py → callbacks/custom_callbacks.py} +26 -19
- aiecs/llm/client_factory.py +224 -36
- aiecs/llm/client_resolver.py +155 -0
- aiecs/llm/clients/__init__.py +38 -0
- aiecs/llm/clients/base_client.py +324 -0
- aiecs/llm/clients/google_function_calling_mixin.py +457 -0
- aiecs/llm/clients/googleai_client.py +241 -0
- aiecs/llm/clients/openai_client.py +158 -0
- aiecs/llm/clients/openai_compatible_mixin.py +367 -0
- aiecs/llm/clients/vertex_client.py +897 -0
- aiecs/llm/clients/xai_client.py +201 -0
- aiecs/llm/config/__init__.py +51 -0
- aiecs/llm/config/config_loader.py +272 -0
- aiecs/llm/config/config_validator.py +206 -0
- aiecs/llm/config/model_config.py +143 -0
- aiecs/llm/protocols.py +149 -0
- aiecs/llm/utils/__init__.py +10 -0
- aiecs/llm/utils/validate_config.py +89 -0
- aiecs/main.py +140 -121
- aiecs/scripts/aid/VERSION_MANAGEMENT.md +138 -0
- aiecs/scripts/aid/__init__.py +19 -0
- aiecs/scripts/aid/module_checker.py +499 -0
- aiecs/scripts/aid/version_manager.py +235 -0
- aiecs/scripts/{DEPENDENCY_SYSTEM_SUMMARY.md → dependance_check/DEPENDENCY_SYSTEM_SUMMARY.md} +1 -0
- aiecs/scripts/{README_DEPENDENCY_CHECKER.md → dependance_check/README_DEPENDENCY_CHECKER.md} +1 -0
- aiecs/scripts/dependance_check/__init__.py +15 -0
- aiecs/scripts/dependance_check/dependency_checker.py +1835 -0
- aiecs/scripts/{dependency_fixer.py → dependance_check/dependency_fixer.py} +192 -90
- aiecs/scripts/{download_nlp_data.py → dependance_check/download_nlp_data.py} +203 -71
- aiecs/scripts/dependance_patch/__init__.py +7 -0
- aiecs/scripts/dependance_patch/fix_weasel/__init__.py +11 -0
- aiecs/scripts/{fix_weasel_validator.py → dependance_patch/fix_weasel/fix_weasel_validator.py} +21 -14
- aiecs/scripts/{patch_weasel_library.sh → dependance_patch/fix_weasel/patch_weasel_library.sh} +1 -1
- aiecs/scripts/knowledge_graph/__init__.py +3 -0
- aiecs/scripts/knowledge_graph/run_threshold_experiments.py +212 -0
- aiecs/scripts/migrations/multi_tenancy/README.md +142 -0
- aiecs/scripts/tools_develop/README.md +671 -0
- aiecs/scripts/tools_develop/README_CONFIG_CHECKER.md +273 -0
- aiecs/scripts/tools_develop/TOOLS_CONFIG_GUIDE.md +1287 -0
- aiecs/scripts/tools_develop/TOOL_AUTO_DISCOVERY.md +234 -0
- aiecs/scripts/tools_develop/__init__.py +21 -0
- aiecs/scripts/tools_develop/check_all_tools_config.py +548 -0
- aiecs/scripts/tools_develop/check_type_annotations.py +257 -0
- aiecs/scripts/tools_develop/pre-commit-schema-coverage.sh +66 -0
- aiecs/scripts/tools_develop/schema_coverage.py +511 -0
- aiecs/scripts/tools_develop/validate_tool_schemas.py +475 -0
- aiecs/scripts/tools_develop/verify_executor_config_fix.py +98 -0
- aiecs/scripts/tools_develop/verify_tools.py +352 -0
- aiecs/tasks/__init__.py +0 -1
- aiecs/tasks/worker.py +115 -47
- aiecs/tools/__init__.py +194 -72
- aiecs/tools/apisource/__init__.py +99 -0
- aiecs/tools/apisource/intelligence/__init__.py +19 -0
- aiecs/tools/apisource/intelligence/data_fusion.py +632 -0
- aiecs/tools/apisource/intelligence/query_analyzer.py +417 -0
- aiecs/tools/apisource/intelligence/search_enhancer.py +385 -0
- aiecs/tools/apisource/monitoring/__init__.py +9 -0
- aiecs/tools/apisource/monitoring/metrics.py +330 -0
- aiecs/tools/apisource/providers/__init__.py +112 -0
- aiecs/tools/apisource/providers/base.py +671 -0
- aiecs/tools/apisource/providers/census.py +397 -0
- aiecs/tools/apisource/providers/fred.py +535 -0
- aiecs/tools/apisource/providers/newsapi.py +409 -0
- aiecs/tools/apisource/providers/worldbank.py +352 -0
- aiecs/tools/apisource/reliability/__init__.py +12 -0
- aiecs/tools/apisource/reliability/error_handler.py +363 -0
- aiecs/tools/apisource/reliability/fallback_strategy.py +376 -0
- aiecs/tools/apisource/tool.py +832 -0
- aiecs/tools/apisource/utils/__init__.py +9 -0
- aiecs/tools/apisource/utils/validators.py +334 -0
- aiecs/tools/base_tool.py +415 -21
- aiecs/tools/docs/__init__.py +121 -0
- aiecs/tools/docs/ai_document_orchestrator.py +607 -0
- aiecs/tools/docs/ai_document_writer_orchestrator.py +2350 -0
- aiecs/tools/docs/content_insertion_tool.py +1320 -0
- aiecs/tools/docs/document_creator_tool.py +1323 -0
- aiecs/tools/docs/document_layout_tool.py +1160 -0
- aiecs/tools/docs/document_parser_tool.py +1011 -0
- aiecs/tools/docs/document_writer_tool.py +1829 -0
- aiecs/tools/knowledge_graph/__init__.py +17 -0
- aiecs/tools/knowledge_graph/graph_reasoning_tool.py +807 -0
- aiecs/tools/knowledge_graph/graph_search_tool.py +944 -0
- aiecs/tools/knowledge_graph/kg_builder_tool.py +524 -0
- aiecs/tools/langchain_adapter.py +300 -138
- aiecs/tools/schema_generator.py +455 -0
- aiecs/tools/search_tool/__init__.py +100 -0
- aiecs/tools/search_tool/analyzers.py +581 -0
- aiecs/tools/search_tool/cache.py +264 -0
- aiecs/tools/search_tool/constants.py +128 -0
- aiecs/tools/search_tool/context.py +224 -0
- aiecs/tools/search_tool/core.py +778 -0
- aiecs/tools/search_tool/deduplicator.py +119 -0
- aiecs/tools/search_tool/error_handler.py +242 -0
- aiecs/tools/search_tool/metrics.py +343 -0
- aiecs/tools/search_tool/rate_limiter.py +172 -0
- aiecs/tools/search_tool/schemas.py +275 -0
- aiecs/tools/statistics/__init__.py +80 -0
- aiecs/tools/statistics/ai_data_analysis_orchestrator.py +646 -0
- aiecs/tools/statistics/ai_insight_generator_tool.py +508 -0
- aiecs/tools/statistics/ai_report_orchestrator_tool.py +684 -0
- aiecs/tools/statistics/data_loader_tool.py +555 -0
- aiecs/tools/statistics/data_profiler_tool.py +638 -0
- aiecs/tools/statistics/data_transformer_tool.py +580 -0
- aiecs/tools/statistics/data_visualizer_tool.py +498 -0
- aiecs/tools/statistics/model_trainer_tool.py +507 -0
- aiecs/tools/statistics/statistical_analyzer_tool.py +472 -0
- aiecs/tools/task_tools/__init__.py +49 -36
- aiecs/tools/task_tools/chart_tool.py +200 -184
- aiecs/tools/task_tools/classfire_tool.py +268 -267
- aiecs/tools/task_tools/image_tool.py +175 -131
- aiecs/tools/task_tools/office_tool.py +226 -146
- aiecs/tools/task_tools/pandas_tool.py +477 -121
- aiecs/tools/task_tools/report_tool.py +390 -142
- aiecs/tools/task_tools/research_tool.py +149 -79
- aiecs/tools/task_tools/scraper_tool.py +339 -145
- aiecs/tools/task_tools/stats_tool.py +448 -209
- aiecs/tools/temp_file_manager.py +26 -24
- aiecs/tools/tool_executor/__init__.py +18 -16
- aiecs/tools/tool_executor/tool_executor.py +364 -52
- aiecs/utils/LLM_output_structor.py +74 -48
- aiecs/utils/__init__.py +14 -3
- aiecs/utils/base_callback.py +0 -3
- aiecs/utils/cache_provider.py +696 -0
- aiecs/utils/execution_utils.py +50 -31
- aiecs/utils/prompt_loader.py +1 -0
- aiecs/utils/token_usage_repository.py +37 -11
- aiecs/ws/socket_server.py +14 -4
- {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/METADATA +52 -15
- aiecs-1.7.6.dist-info/RECORD +337 -0
- aiecs-1.7.6.dist-info/entry_points.txt +13 -0
- aiecs/config/registry.py +0 -19
- aiecs/domain/context/content_engine.py +0 -982
- aiecs/llm/base_client.py +0 -99
- aiecs/llm/openai_client.py +0 -125
- aiecs/llm/vertex_client.py +0 -186
- aiecs/llm/xai_client.py +0 -184
- aiecs/scripts/dependency_checker.py +0 -857
- aiecs/scripts/quick_dependency_check.py +0 -269
- aiecs/tools/task_tools/search_api.py +0 -7
- aiecs-1.0.1.dist-info/RECORD +0 -90
- aiecs-1.0.1.dist-info/entry_points.txt +0 -7
- /aiecs/scripts/{setup_nlp_data.sh → dependance_check/setup_nlp_data.sh} +0 -0
- /aiecs/scripts/{README_WEASEL_PATCH.md → dependance_patch/fix_weasel/README_WEASEL_PATCH.md} +0 -0
- /aiecs/scripts/{fix_weasel_validator.sh → dependance_patch/fix_weasel/fix_weasel_validator.sh} +0 -0
- /aiecs/scripts/{run_weasel_patch.sh → dependance_patch/fix_weasel/run_weasel_patch.sh} +0 -0
- {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/WHEEL +0 -0
- {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/licenses/LICENSE +0 -0
- {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Logic Query Parser
|
|
3
|
+
|
|
4
|
+
Parses declarative query DSL into executable query plans for knowledge graph reasoning.
|
|
5
|
+
|
|
6
|
+
This package provides:
|
|
7
|
+
- Grammar definition (Lark EBNF)
|
|
8
|
+
- AST node definitions
|
|
9
|
+
- Parser implementation
|
|
10
|
+
- Query plan conversion
|
|
11
|
+
- Error handling
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
```python
|
|
15
|
+
from aiecs.application.knowledge_graph.reasoning.logic_parser import LogicQueryParser
|
|
16
|
+
|
|
17
|
+
parser = LogicQueryParser(schema)
|
|
18
|
+
result = parser.parse_to_query_plan("Find(Person) WHERE age > 30")
|
|
19
|
+
|
|
20
|
+
if isinstance(result, QueryPlan):
|
|
21
|
+
# Execute the plan
|
|
22
|
+
planner.execute(result)
|
|
23
|
+
else:
|
|
24
|
+
# Handle errors
|
|
25
|
+
for error in result:
|
|
26
|
+
print(f"Error at line {error.line}: {error.message}")
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Phase: 2.4 - Logic Query Parser
|
|
30
|
+
Version: 1.0
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
__version__ = "1.0.0"
|
|
34
|
+
__phase__ = "2.4"
|
|
35
|
+
|
|
36
|
+
# Export main components
|
|
37
|
+
from .parser import LogicQueryParser
|
|
38
|
+
from .error_handler import ParserError, ErrorHandler
|
|
39
|
+
from .ast_nodes import (
|
|
40
|
+
ASTNode,
|
|
41
|
+
QueryNode,
|
|
42
|
+
FindNode,
|
|
43
|
+
TraversalNode,
|
|
44
|
+
FilterNode,
|
|
45
|
+
PropertyFilterNode,
|
|
46
|
+
BooleanFilterNode,
|
|
47
|
+
ValidationError,
|
|
48
|
+
)
|
|
49
|
+
from .query_context import (
|
|
50
|
+
QueryContext,
|
|
51
|
+
VariableRedefinitionError,
|
|
52
|
+
UndefinedVariableError,
|
|
53
|
+
)
|
|
54
|
+
from .ast_builder import ASTBuilder
|
|
55
|
+
from .ast_validator import ASTValidator
|
|
56
|
+
|
|
57
|
+
__all__ = [
|
|
58
|
+
# Parser
|
|
59
|
+
"LogicQueryParser",
|
|
60
|
+
"ParserError",
|
|
61
|
+
"ErrorHandler",
|
|
62
|
+
# AST Nodes
|
|
63
|
+
"ASTNode",
|
|
64
|
+
"QueryNode",
|
|
65
|
+
"FindNode",
|
|
66
|
+
"TraversalNode",
|
|
67
|
+
"FilterNode",
|
|
68
|
+
"PropertyFilterNode",
|
|
69
|
+
"BooleanFilterNode",
|
|
70
|
+
"ValidationError",
|
|
71
|
+
# AST Builder
|
|
72
|
+
"ASTBuilder",
|
|
73
|
+
# AST Validator
|
|
74
|
+
"ASTValidator",
|
|
75
|
+
# Context
|
|
76
|
+
"QueryContext",
|
|
77
|
+
"VariableRedefinitionError",
|
|
78
|
+
"UndefinedVariableError",
|
|
79
|
+
]
|
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AST Builder for Logic Query Parser
|
|
3
|
+
|
|
4
|
+
This module provides the ASTBuilder class that transforms Lark parse trees
|
|
5
|
+
into AST nodes. It extends lark.Transformer to convert parse tree nodes
|
|
6
|
+
into our custom AST node hierarchy.
|
|
7
|
+
|
|
8
|
+
Design Principles:
|
|
9
|
+
1. Each transformation method corresponds to a grammar rule
|
|
10
|
+
2. Line/column metadata is preserved from parse tree
|
|
11
|
+
3. Transformations are composable (bottom-up)
|
|
12
|
+
4. Type-safe conversions with proper error handling
|
|
13
|
+
|
|
14
|
+
Phase: 2.4 - Logic Query Parser
|
|
15
|
+
Task: 2.2 - Implement AST Builder
|
|
16
|
+
Version: 1.0
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from typing import Any, List, Union
|
|
20
|
+
from lark import Transformer, Token
|
|
21
|
+
|
|
22
|
+
from .ast_nodes import (
|
|
23
|
+
QueryNode,
|
|
24
|
+
FindNode,
|
|
25
|
+
TraversalNode,
|
|
26
|
+
FilterNode,
|
|
27
|
+
PropertyFilterNode,
|
|
28
|
+
BooleanFilterNode,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ASTBuilder(Transformer):
|
|
33
|
+
"""
|
|
34
|
+
Transform Lark parse tree into AST nodes
|
|
35
|
+
|
|
36
|
+
This class extends lark.Transformer to convert parse tree nodes
|
|
37
|
+
into our custom AST node hierarchy. Each method corresponds to
|
|
38
|
+
a grammar rule and returns the appropriate AST node.
|
|
39
|
+
|
|
40
|
+
**Transformation Flow**:
|
|
41
|
+
1. Lark parses query string → parse tree
|
|
42
|
+
2. ASTBuilder.transform(parse_tree) → AST
|
|
43
|
+
3. Bottom-up transformation (leaves first, then parents)
|
|
44
|
+
|
|
45
|
+
**Line/Column Metadata**:
|
|
46
|
+
- Extracted from Token.line and Token.column
|
|
47
|
+
- Preserved in all AST nodes for error reporting
|
|
48
|
+
|
|
49
|
+
Example:
|
|
50
|
+
```python
|
|
51
|
+
from lark import Lark
|
|
52
|
+
|
|
53
|
+
parser = Lark(grammar, start='query')
|
|
54
|
+
builder = ASTBuilder()
|
|
55
|
+
|
|
56
|
+
parse_tree = parser.parse("Find(Person) WHERE age > 30")
|
|
57
|
+
ast = builder.transform(parse_tree)
|
|
58
|
+
|
|
59
|
+
# ast is now a QueryNode with FindNode and filters
|
|
60
|
+
```
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
def __init__(self):
|
|
64
|
+
"""Initialize AST builder"""
|
|
65
|
+
super().__init__()
|
|
66
|
+
|
|
67
|
+
def negate(self, items: List[Any]) -> BooleanFilterNode:
|
|
68
|
+
"""
|
|
69
|
+
Transform negate rule: "NOT" not_condition
|
|
70
|
+
|
|
71
|
+
This is called when the grammar matches "NOT" not_condition.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
items: [condition to negate]
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
BooleanFilterNode with NOT operator
|
|
78
|
+
"""
|
|
79
|
+
condition = items[0]
|
|
80
|
+
|
|
81
|
+
# Get line/column from the condition
|
|
82
|
+
line = getattr(condition, "line", 1)
|
|
83
|
+
column = getattr(condition, "column", 1)
|
|
84
|
+
|
|
85
|
+
return BooleanFilterNode(line=line, column=column, operator="NOT", operands=[condition])
|
|
86
|
+
|
|
87
|
+
# ========================================================================
|
|
88
|
+
# Top-Level Query Transformation
|
|
89
|
+
# ========================================================================
|
|
90
|
+
|
|
91
|
+
def query(self, items: List[Any]) -> QueryNode:
|
|
92
|
+
"""
|
|
93
|
+
Transform query rule: find_clause traversal_clause* where_clause?
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
items: List of transformed children
|
|
97
|
+
[0] = FindNode
|
|
98
|
+
[1:] = TraversalNodes (if any)
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
QueryNode with find and traversals
|
|
102
|
+
"""
|
|
103
|
+
find_node = items[0]
|
|
104
|
+
traversals = []
|
|
105
|
+
|
|
106
|
+
# Collect traversal nodes (if any)
|
|
107
|
+
for item in items[1:]:
|
|
108
|
+
if isinstance(item, TraversalNode):
|
|
109
|
+
traversals.append(item)
|
|
110
|
+
elif isinstance(item, list):
|
|
111
|
+
# where_clause returns list of filters
|
|
112
|
+
# Attach filters to FindNode
|
|
113
|
+
# Note: FindNode is frozen, so we need to create a new one
|
|
114
|
+
find_node = FindNode(
|
|
115
|
+
line=find_node.line,
|
|
116
|
+
column=find_node.column,
|
|
117
|
+
entity_type=find_node.entity_type,
|
|
118
|
+
entity_name=find_node.entity_name,
|
|
119
|
+
filters=item,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
# Get line/column from find_node
|
|
123
|
+
return QueryNode(
|
|
124
|
+
line=find_node.line,
|
|
125
|
+
column=find_node.column,
|
|
126
|
+
find=find_node,
|
|
127
|
+
traversals=traversals,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# ========================================================================
|
|
131
|
+
# Find Clause Transformation
|
|
132
|
+
# ========================================================================
|
|
133
|
+
|
|
134
|
+
def find_clause(self, items: List[Any]) -> FindNode:
|
|
135
|
+
"""
|
|
136
|
+
Transform find_clause rule: "Find" "(" entity_spec ")"
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
items: List with entity_spec (tuple of entity_type, entity_name)
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
FindNode with entity type and optional name
|
|
143
|
+
"""
|
|
144
|
+
entity_type, entity_name, line, column = items[0]
|
|
145
|
+
|
|
146
|
+
return FindNode(
|
|
147
|
+
line=line,
|
|
148
|
+
column=column,
|
|
149
|
+
entity_type=entity_type,
|
|
150
|
+
entity_name=entity_name,
|
|
151
|
+
filters=[], # Filters added later by query rule
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
def entity_spec(self, items: List[Any]) -> tuple:
|
|
155
|
+
"""
|
|
156
|
+
Transform entity_spec rule: IDENTIFIER ("[" entity_name "]")?
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
items: [IDENTIFIER, optional entity_name]
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
Tuple of (entity_type, entity_name, line, column)
|
|
163
|
+
"""
|
|
164
|
+
entity_type_token = items[0]
|
|
165
|
+
entity_type = str(entity_type_token)
|
|
166
|
+
entity_name = None
|
|
167
|
+
|
|
168
|
+
# Check if entity name is provided
|
|
169
|
+
if len(items) > 1:
|
|
170
|
+
entity_name = items[1]
|
|
171
|
+
|
|
172
|
+
return (
|
|
173
|
+
entity_type,
|
|
174
|
+
entity_name,
|
|
175
|
+
entity_type_token.line,
|
|
176
|
+
entity_type_token.column,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
def entity_name(self, items: List[Any]) -> str:
|
|
180
|
+
"""
|
|
181
|
+
Transform entity_name rule: BACKTICK_STRING
|
|
182
|
+
|
|
183
|
+
Args:
|
|
184
|
+
items: [BACKTICK_STRING token]
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
Entity name without backticks
|
|
188
|
+
"""
|
|
189
|
+
backtick_string = str(items[0])
|
|
190
|
+
# Remove backticks
|
|
191
|
+
return backtick_string.strip("`")
|
|
192
|
+
|
|
193
|
+
# ========================================================================
|
|
194
|
+
# Traversal Clause Transformation
|
|
195
|
+
# ========================================================================
|
|
196
|
+
|
|
197
|
+
def traversal_clause(self, items: List[Any]) -> TraversalNode:
|
|
198
|
+
"""
|
|
199
|
+
Transform traversal_clause rule: "FOLLOWS" relation_spec direction?
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
items: [relation_type, optional direction]
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
TraversalNode with relation type and direction
|
|
206
|
+
"""
|
|
207
|
+
relation_type_token = items[0]
|
|
208
|
+
relation_type = str(relation_type_token)
|
|
209
|
+
direction = "outgoing" # Default
|
|
210
|
+
|
|
211
|
+
# Check if direction is provided
|
|
212
|
+
if len(items) > 1:
|
|
213
|
+
direction = items[1]
|
|
214
|
+
|
|
215
|
+
return TraversalNode(
|
|
216
|
+
line=relation_type_token.line,
|
|
217
|
+
column=relation_type_token.column,
|
|
218
|
+
relation_type=relation_type,
|
|
219
|
+
direction=direction,
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
def relation_spec(self, items: List[Any]) -> Token:
|
|
223
|
+
"""
|
|
224
|
+
Transform relation_spec rule: IDENTIFIER
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
items: [IDENTIFIER token]
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
IDENTIFIER token (passed through for line/column info)
|
|
231
|
+
"""
|
|
232
|
+
return items[0]
|
|
233
|
+
|
|
234
|
+
def incoming(self, items: List[Any]) -> str:
|
|
235
|
+
"""Transform INCOMING direction"""
|
|
236
|
+
return "incoming"
|
|
237
|
+
|
|
238
|
+
def outgoing(self, items: List[Any]) -> str:
|
|
239
|
+
"""Transform OUTGOING direction"""
|
|
240
|
+
return "outgoing"
|
|
241
|
+
|
|
242
|
+
# ========================================================================
|
|
243
|
+
# Where Clause Transformation
|
|
244
|
+
# ========================================================================
|
|
245
|
+
|
|
246
|
+
def where_clause(self, items: List[Any]) -> List[FilterNode]:
|
|
247
|
+
"""
|
|
248
|
+
Transform where_clause rule: "WHERE" condition
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
items: [condition (FilterNode or list of FilterNodes)]
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
List of FilterNodes
|
|
255
|
+
"""
|
|
256
|
+
condition = items[0]
|
|
257
|
+
|
|
258
|
+
# Wrap single filter in list
|
|
259
|
+
if isinstance(condition, FilterNode):
|
|
260
|
+
return [condition]
|
|
261
|
+
elif isinstance(condition, list):
|
|
262
|
+
return condition
|
|
263
|
+
else:
|
|
264
|
+
return [condition]
|
|
265
|
+
|
|
266
|
+
# ========================================================================
|
|
267
|
+
# Condition Transformation (Boolean Logic)
|
|
268
|
+
# ========================================================================
|
|
269
|
+
|
|
270
|
+
def or_condition(self, items: List[Any]) -> FilterNode:
|
|
271
|
+
"""
|
|
272
|
+
Transform or_condition rule: and_condition ("OR" and_condition)*
|
|
273
|
+
|
|
274
|
+
Args:
|
|
275
|
+
items: List of and_conditions
|
|
276
|
+
|
|
277
|
+
Returns:
|
|
278
|
+
BooleanFilterNode with OR operator (if multiple items)
|
|
279
|
+
or single FilterNode (if one item)
|
|
280
|
+
"""
|
|
281
|
+
if len(items) == 1:
|
|
282
|
+
return items[0]
|
|
283
|
+
|
|
284
|
+
# Multiple items: create OR node
|
|
285
|
+
first_item = items[0]
|
|
286
|
+
return BooleanFilterNode(
|
|
287
|
+
line=first_item.line if hasattr(first_item, "line") else 1,
|
|
288
|
+
column=first_item.column if hasattr(first_item, "column") else 1,
|
|
289
|
+
operator="OR",
|
|
290
|
+
operands=items,
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
def and_condition(self, items: List[Any]) -> FilterNode:
|
|
294
|
+
"""
|
|
295
|
+
Transform and_condition rule: not_condition ("AND" not_condition)*
|
|
296
|
+
|
|
297
|
+
Args:
|
|
298
|
+
items: List of not_conditions
|
|
299
|
+
|
|
300
|
+
Returns:
|
|
301
|
+
BooleanFilterNode with AND operator (if multiple items)
|
|
302
|
+
or single FilterNode (if one item)
|
|
303
|
+
"""
|
|
304
|
+
if len(items) == 1:
|
|
305
|
+
return items[0]
|
|
306
|
+
|
|
307
|
+
# Multiple items: create AND node
|
|
308
|
+
first_item = items[0]
|
|
309
|
+
return BooleanFilterNode(
|
|
310
|
+
line=first_item.line if hasattr(first_item, "line") else 1,
|
|
311
|
+
column=first_item.column if hasattr(first_item, "column") else 1,
|
|
312
|
+
operator="AND",
|
|
313
|
+
operands=items,
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
def not_condition(self, items: List[Any]) -> FilterNode:
|
|
317
|
+
"""
|
|
318
|
+
Transform not_condition rule: "NOT" not_condition -> negate | primary_condition
|
|
319
|
+
|
|
320
|
+
This method is called for the primary_condition branch (pass-through).
|
|
321
|
+
The "NOT" branch is handled by the negate() method.
|
|
322
|
+
|
|
323
|
+
Args:
|
|
324
|
+
items: [primary_condition]
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
FilterNode (passed through)
|
|
328
|
+
"""
|
|
329
|
+
return items[0]
|
|
330
|
+
|
|
331
|
+
def primary_condition(self, items: List[Any]) -> FilterNode:
|
|
332
|
+
"""
|
|
333
|
+
Transform primary_condition rule: "(" condition ")" | simple_condition
|
|
334
|
+
|
|
335
|
+
Args:
|
|
336
|
+
items: [condition] (parenthesized or simple)
|
|
337
|
+
|
|
338
|
+
Returns:
|
|
339
|
+
FilterNode
|
|
340
|
+
"""
|
|
341
|
+
return items[0]
|
|
342
|
+
|
|
343
|
+
# ========================================================================
|
|
344
|
+
# Simple Condition Transformation
|
|
345
|
+
# ========================================================================
|
|
346
|
+
|
|
347
|
+
def simple_condition(self, items: List[Any]) -> PropertyFilterNode:
|
|
348
|
+
"""
|
|
349
|
+
Transform simple_condition rule: property_path operator value
|
|
350
|
+
|
|
351
|
+
Args:
|
|
352
|
+
items: [property_path, operator, value]
|
|
353
|
+
|
|
354
|
+
Returns:
|
|
355
|
+
PropertyFilterNode
|
|
356
|
+
"""
|
|
357
|
+
property_path = items[0]
|
|
358
|
+
operator = items[1]
|
|
359
|
+
value = items[2]
|
|
360
|
+
|
|
361
|
+
# Get line/column from property_path token
|
|
362
|
+
if isinstance(property_path, str):
|
|
363
|
+
line, column = 1, 1
|
|
364
|
+
else:
|
|
365
|
+
line = getattr(property_path, "line", 1)
|
|
366
|
+
column = getattr(property_path, "column", 1)
|
|
367
|
+
property_path = str(property_path)
|
|
368
|
+
|
|
369
|
+
return PropertyFilterNode(
|
|
370
|
+
line=line,
|
|
371
|
+
column=column,
|
|
372
|
+
property_path=property_path,
|
|
373
|
+
operator=operator,
|
|
374
|
+
value=value,
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
def property_path(self, items: List[Any]) -> str:
|
|
378
|
+
"""
|
|
379
|
+
Transform property_path rule: IDENTIFIER ("." IDENTIFIER)*
|
|
380
|
+
|
|
381
|
+
Args:
|
|
382
|
+
items: List of IDENTIFIER tokens
|
|
383
|
+
|
|
384
|
+
Returns:
|
|
385
|
+
Dot-separated property path string
|
|
386
|
+
"""
|
|
387
|
+
# Join identifiers with dots for nested properties
|
|
388
|
+
path_parts = [str(item) for item in items]
|
|
389
|
+
return ".".join(path_parts)
|
|
390
|
+
|
|
391
|
+
# ========================================================================
|
|
392
|
+
# Operator Transformation
|
|
393
|
+
# ========================================================================
|
|
394
|
+
|
|
395
|
+
def eq(self, items: List[Any]) -> str:
|
|
396
|
+
"""Transform == operator"""
|
|
397
|
+
return "=="
|
|
398
|
+
|
|
399
|
+
def ne(self, items: List[Any]) -> str:
|
|
400
|
+
"""Transform != operator"""
|
|
401
|
+
return "!="
|
|
402
|
+
|
|
403
|
+
def gt(self, items: List[Any]) -> str:
|
|
404
|
+
"""Transform > operator"""
|
|
405
|
+
return ">"
|
|
406
|
+
|
|
407
|
+
def lt(self, items: List[Any]) -> str:
|
|
408
|
+
"""Transform < operator"""
|
|
409
|
+
return "<"
|
|
410
|
+
|
|
411
|
+
def gte(self, items: List[Any]) -> str:
|
|
412
|
+
"""Transform >= operator"""
|
|
413
|
+
return ">="
|
|
414
|
+
|
|
415
|
+
def lte(self, items: List[Any]) -> str:
|
|
416
|
+
"""Transform <= operator"""
|
|
417
|
+
return "<="
|
|
418
|
+
|
|
419
|
+
def in_op(self, items: List[Any]) -> str:
|
|
420
|
+
"""Transform IN operator"""
|
|
421
|
+
return "IN"
|
|
422
|
+
|
|
423
|
+
def contains(self, items: List[Any]) -> str:
|
|
424
|
+
"""Transform CONTAINS operator"""
|
|
425
|
+
return "CONTAINS"
|
|
426
|
+
|
|
427
|
+
# ========================================================================
|
|
428
|
+
# Value Transformation
|
|
429
|
+
# ========================================================================
|
|
430
|
+
|
|
431
|
+
def string_value(self, items: List[Any]) -> str:
|
|
432
|
+
"""
|
|
433
|
+
Transform string_value rule: STRING
|
|
434
|
+
|
|
435
|
+
Args:
|
|
436
|
+
items: [STRING token]
|
|
437
|
+
|
|
438
|
+
Returns:
|
|
439
|
+
String value without quotes
|
|
440
|
+
"""
|
|
441
|
+
string_token = str(items[0])
|
|
442
|
+
# Remove quotes (single or double)
|
|
443
|
+
return string_token.strip("\"'")
|
|
444
|
+
|
|
445
|
+
def number_value(self, items: List[Any]) -> Union[int, float]:
|
|
446
|
+
"""
|
|
447
|
+
Transform number_value rule: NUMBER
|
|
448
|
+
|
|
449
|
+
Args:
|
|
450
|
+
items: [NUMBER token]
|
|
451
|
+
|
|
452
|
+
Returns:
|
|
453
|
+
Integer or float value
|
|
454
|
+
"""
|
|
455
|
+
number_str = str(items[0])
|
|
456
|
+
|
|
457
|
+
# Try to parse as int first, then float
|
|
458
|
+
if "." in number_str:
|
|
459
|
+
return float(number_str)
|
|
460
|
+
else:
|
|
461
|
+
return int(number_str)
|
|
462
|
+
|
|
463
|
+
def boolean_value(self, items: List[Any]) -> bool:
|
|
464
|
+
"""
|
|
465
|
+
Transform boolean_value rule: BOOLEAN
|
|
466
|
+
|
|
467
|
+
Args:
|
|
468
|
+
items: [BOOLEAN token]
|
|
469
|
+
|
|
470
|
+
Returns:
|
|
471
|
+
Boolean value
|
|
472
|
+
"""
|
|
473
|
+
if not items:
|
|
474
|
+
return False
|
|
475
|
+
|
|
476
|
+
bool_str = str(items[0]).lower().strip()
|
|
477
|
+
return bool_str in ("true", "t", "1")
|
|
478
|
+
|
|
479
|
+
def list_value(self, items: List[Any]) -> List[Any]:
|
|
480
|
+
"""
|
|
481
|
+
Transform list_value rule: list
|
|
482
|
+
|
|
483
|
+
Args:
|
|
484
|
+
items: [list of values]
|
|
485
|
+
|
|
486
|
+
Returns:
|
|
487
|
+
List of values
|
|
488
|
+
"""
|
|
489
|
+
return items[0] if items else []
|
|
490
|
+
|
|
491
|
+
def list(self, items: List[Any]) -> List[Any]:
|
|
492
|
+
"""
|
|
493
|
+
Transform list rule: "[" [value ("," value)*] "]"
|
|
494
|
+
|
|
495
|
+
Args:
|
|
496
|
+
items: List of values
|
|
497
|
+
|
|
498
|
+
Returns:
|
|
499
|
+
List of values
|
|
500
|
+
"""
|
|
501
|
+
return items
|
|
502
|
+
|
|
503
|
+
def identifier_value(self, items: List[Any]) -> str:
|
|
504
|
+
"""
|
|
505
|
+
Transform identifier_value rule: IDENTIFIER
|
|
506
|
+
|
|
507
|
+
Args:
|
|
508
|
+
items: [IDENTIFIER token]
|
|
509
|
+
|
|
510
|
+
Returns:
|
|
511
|
+
Identifier string (for variable references)
|
|
512
|
+
"""
|
|
513
|
+
return str(items[0])
|