123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- #!/usr/bin/env python3
- '''
- KLL Context Definitions
- * Generic (auto-detected)
- * Configuration
- * BaseMap
- * DefaultMap
- * PartialMap
- '''
-
- # Copyright (C) 2016 by Jacob Alexander
- #
- # This file is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This file is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this file. If not, see <http://www.gnu.org/licenses/>.
-
- ### Imports ###
-
- import copy
- import os
-
- import common.organization as organization
-
-
-
- ### Decorators ###
-
- ## Print Decorator Variables
- ERROR = '\033[5;1;31mERROR\033[0m:'
- WARNING = '\033[5;1;33mWARNING\033[0m:'
-
-
-
- ### Classes ###
-
- class Context:
- '''
- Base KLL Context Class
- '''
- def __init__( self ):
- '''
- Context initialization
- '''
- # Each context may have one or more included kll files
- # And each of these files will have at least 1 Context
- self.kll_files = []
-
- # File data assigned to each context
- # This info is populated during the PreprocessorStage
- self.lines = []
- self.data = ""
- self.parent = None
-
- # Tokenized data sets
- self.classification_token_data = []
- self.expressions = []
-
- # Organized Expression Datastructure
- self.organization = organization.Organization()
-
- def __repr__( self ):
- # Build list of all the info
- return "(kll_files={0}, lines={1}, data='''{2}''')".format(
- self.kll_files,
- self.lines,
- self.data,
- )
-
- def initial_context( self, lines, data, parent ):
- '''
- Used in the PreprocessorStage to update the initial line and kll file data
-
- @param lines: Data split per line
- @param data: Entire context in a single string
- @param parent: Parent node, always a KLLFile
- '''
- self.lines = lines
- self.data = data
- self.parent = parent
-
- def query( self, kll_expression, kll_type ):
- '''
- Query
-
- Returns a dictionary of the specified property.
- Most queries should use this.
-
- See organization.py:Organization for property_type details.
-
- @param kll_expression: String name of expression type
- @param kll_type: String name of the expression sub-type
-
- @return: context_name: (dictionary)
- '''
- return self.organization.data_mapping[ kll_expression ][ kll_type ]
-
-
- class GenericContext( Context ):
- '''
- Generic KLL Context Class
- '''
-
-
- class ConfigurationContext( Context ):
- '''
- Configuration KLL Context Class
- '''
-
-
- class BaseMapContext( Context ):
- '''
- Base Map KLL Context Class
- '''
-
-
- class DefaultMapContext( Context ):
- '''
- Default Map KLL Context Class
- '''
-
-
- class PartialMapContext( Context ):
- '''
- Partial Map KLL Context Class
- '''
- def __init__( self, layer ):
- '''
- Partial Map Layer Context Initialization
-
- @param: Layer associated with Partial Map
- '''
- super().__init__()
-
- self.layer = layer
-
-
- class MergeContext( Context ):
- '''
- Container class for a merged Context
-
- Has references to the original contexts merged in
- '''
- def __init__( self, base_context ):
- '''
- Initialize the MergeContext with the base context
- Another MergeContext can be used as the base_context
-
- @param base_context: Context used to seed the MergeContext
- '''
- super().__init__()
-
- # List of context, in the order of merging, starting from the base
- self.contexts = [ base_context ]
-
- # Copy the base context Organization into the MergeContext
- self.organization = copy.copy( base_context.organization )
-
- # Set the layer if the base is a PartialMapContext
- if base_context.__class__.__name__ == 'PartialMapContext':
- self.layer = base_context.layer
-
- def merge( self, merge_in, debug ):
- '''
- Merge in context
-
- Another MergeContext can be merged into a MergeContext
-
- @param merge_in: Context to merge in to this one
- @param debug: Enable debug out
- '''
- # Append to context list
- self.contexts.append( merge_in )
-
- # Merge context
- self.organization.merge(
- merge_in.organization,
- debug
- )
-
- # Set the layer if the base is a PartialMapContext
- if merge_in.__class__.__name__ == 'PartialMapContext':
- self.layer = merge_in.layer
-
- def reduction( self ):
- '''
- Simplifies datastructure
-
- NOTE: This will remove data, therefore, context is lost
- '''
- self.organization.reduction()
-
- def paths( self ):
- '''
- Returns list of file paths used to generate this context
- '''
- file_paths = []
-
- for kll_context in self.contexts:
- # If context is a MergeContext then we have to recursively search
- if kll_context.__class__.__name__ is 'MergeContext':
- file_paths.extend( kll_context.paths() )
- else:
- file_paths.append( kll_context.parent.path )
-
- return file_paths
-
- def files( self ):
- '''
- Short form list of file paths used to generate this context
- '''
- file_paths = []
- for file_path in self.paths():
- file_paths.append( os.path.basename( file_path ) )
-
- return file_paths
-
- def __repr__( self ):
- return "(kll_files={0}, organization={1})".format(
- self.files(),
- self.organization,
- )
-
- def query_contexts( self, kll_expression, kll_type ):
- '''
- Context Query
-
- Returns a list of tuples (dictionary, kll_context) doing a deep search to the context leaf nodes.
- This results in pre-merge data and is useful for querying information about files used during compilation.
-
- See organization.py:Organization for property_type details.
-
- @param kll_expression: String name of expression type
- @param kll_type: String name of the expression sub-type
-
- @return: context_name: (dictionary, kll_context)
- '''
- # Build list of leaf contexts
- leaf_contexts = []
- for kll_context in self.contexts:
- # Recursively search if necessary
- if kll_context.__class__.__name__ == 'MergeContext':
- leaf_contexts.extend( kll_context.query_contexts( kll_expression, kll_type ) )
- else:
- leaf_contexts.append( ( kll_context.query( kll_expression, kll_type ), kll_context ) )
-
- return leaf_contexts
|