def parse_select_dependencies(string): """Parse a select query and return the dependencies Args: string(str): Input string to be parsed Returns: result(list of str): List of dependent tables """ if string == '': return list() # Find all dependent tables dep_parse = WordStart() + (_from | _join) + _db_name.setResultsName('table') output = dep_parse.setParseAction(lambda x: x.table).searchString(string) # Flatten the list before returning flattened_output = [item for sublist in output for item in sublist] # Deduplicated the list unique_output = deduplicate_with_order(flattened_output) if len(unique_output) == 0: raise ParseException('No dependent table in select query') return unique_output
def parse_select_dependencies(string): """Parse a select query and return the dependencies Args: string(str): Input string to be parsed Returns: result(list of str): List of dependent tables """ if string == "": return list() # Find all dependent tables dep_parse = WordStart() + (_from | _join) + _db_name.setResultsName("table") output = dep_parse.setParseAction(lambda x: x.table).searchString(string) # Flatten the list before returning flattened_output = [item for sublist in output for item in sublist] # Deduplicated the list unique_output = deduplicate_with_order(flattened_output) if len(unique_output) == 0: raise ParseException("No dependent table in select query") return unique_output
def __init__(self, basedir: str = '.') -> None: self.__basedir = basedir self.__specifications: Dict[str, Specification] = {} self.__pdus: Dict[str, PDU] = {} self.__refinements: Dict[str, Refinement] = {} # Generic comma = Suppress(Literal(',')) comma.setName('","') semicolon = Suppress(Literal(';')) semicolon.setName('";"') # Comments comment = Regex(r'--.*') # Names identifier = WordStart(alphanums) + Word(alphanums + '_') + WordEnd(alphanums + '_') identifier.setParseAction(verify_identifier) identifier.setName('Identifier') qualified_identifier = Optional(identifier + Literal('.')) - identifier qualified_identifier.setParseAction(lambda t: ''.join(t.asList())) attribute_designator = Keyword('First') | Keyword('Last') | Keyword( 'Length') attribute_reference = identifier + Literal('\'') - attribute_designator attribute_reference.setParseAction(parse_attribute) attribute_reference.setName('Attribute') name = attribute_reference | identifier name.setName('Name') # Literals numeral = Word(nums) + ZeroOrMore(Optional(Word('_')) + Word(nums)) numeral.setParseAction( lambda t: int(''.join(t.asList()).replace('_', ''))) extended_digit = Word(nums + 'ABCDEF') based_numeral = extended_digit + ZeroOrMore( Optional('_') + extended_digit) based_literal = numeral + Literal('#') - based_numeral - Literal('#') based_literal.setParseAction( lambda t: int(t[2].replace('_', ''), int(t[0]))) numeric_literal = based_literal | numeral numeric_literal.setParseAction(lambda t: Number(t[0])) numeric_literal.setName('Number') literal = numeric_literal # Operators mathematical_operator = (Literal('**') | Literal('+') | Literal('-') | Literal('*') | Literal('/')) relational_operator = (Keyword('<=') | Keyword('>=') | Keyword('=') | Keyword('/=') | Keyword('<') | Keyword('>')) logical_operator = Keyword('and') | Keyword('or') # Expressions mathematical_expression = Forward() relation = mathematical_expression + relational_operator - mathematical_expression relation.setParseAction(parse_relation) relation.setName('Relation') logical_expression = infixNotation( relation, [(logical_operator, 2, opAssoc.LEFT, parse_logical_expression)]) logical_expression.setName('LogicalExpression') term = Keyword('null') | literal | name term.setParseAction(parse_term) mathematical_expression << infixNotation( term, [(mathematical_operator, 2, opAssoc.LEFT, parse_mathematical_expression)]) mathematical_expression.setName('MathematicalExpression') # Type Refinement value_constraint = Keyword('if') - logical_expression value_constraint.setParseAction(lambda t: t[1]) type_refinement_definition = ( Keyword('new') - qualified_identifier - Suppress(Literal('(')) - identifier - Suppress(Literal('=>')) - (Keyword('null') | qualified_identifier) - Suppress(Literal(')')) - Optional(value_constraint)) type_refinement_definition.setName('Refinement') # Integer Types size_aspect = Keyword('Size') - Keyword('=>') - mathematical_expression size_aspect.setParseAction(parse_aspect) range_type_aspects = Keyword('with') - size_aspect range_type_aspects.setParseAction(parse_aspects) range_type_definition = (Keyword('range') - mathematical_expression - Suppress(Literal('..')) - mathematical_expression - range_type_aspects) range_type_definition.setName('RangeInteger') modular_type_definition = Keyword('mod') - mathematical_expression modular_type_definition.setName('ModularInteger') integer_type_definition = range_type_definition | modular_type_definition # Enumeration Types enumeration_literal = name positional_enumeration = enumeration_literal + ZeroOrMore( comma - enumeration_literal) positional_enumeration.setParseAction( lambda t: [(k, Number(v)) for v, k in enumerate(t.asList())]) element_value_association = enumeration_literal + Keyword( '=>') - numeric_literal element_value_association.setParseAction(lambda t: (t[0], t[2])) named_enumeration = (element_value_association + ZeroOrMore(comma - element_value_association)) boolean_literal = Keyword('True') | Keyword('False') boolean_literal.setParseAction(lambda t: t[0] == 'True') boolean_aspect_definition = Optional(Keyword('=>') - boolean_literal) boolean_aspect_definition.setParseAction(lambda t: (t if t else ['=>', True])) always_valid_aspect = Literal( 'Always_Valid') - boolean_aspect_definition always_valid_aspect.setParseAction(parse_aspect) enumeration_aspects = Keyword('with') - delimitedList( size_aspect | always_valid_aspect) enumeration_aspects.setParseAction(parse_aspects) enumeration_type_definition = ( Literal('(') - (named_enumeration | positional_enumeration) - Literal(')') - enumeration_aspects) enumeration_type_definition.setName('Enumeration') # Array Type unconstrained_array_definition = Keyword('array of') + name array_type_definition = unconstrained_array_definition array_type_definition.setName('Array') # Message Type first_aspect = Keyword('First') - Keyword( '=>') - mathematical_expression first_aspect.setParseAction(parse_aspect) length_aspect = Keyword('Length') - Keyword( '=>') - mathematical_expression length_aspect.setParseAction(parse_aspect) component_aspects = Keyword('with') - delimitedList(first_aspect | length_aspect) component_aspects.setParseAction(parse_aspects) then = (Keyword('then') - (Keyword('null') | identifier) - Group(Optional(component_aspects)) - Group(Optional(value_constraint))) then.setParseAction(parse_then) then_list = then + ZeroOrMore(comma - then) then_list.setParseAction(lambda t: [t.asList()]) component_list = Forward() message_type_definition = Keyword( 'message') - component_list - Keyword('end message') message_type_definition.setName('Message') component_item = (~Keyword('end') + ~CaselessKeyword('Message') - identifier + Literal(':') - name - Optional(then_list) - semicolon) component_item.setParseAction(lambda t: Component(t[0], t[2], t[3]) if len(t) >= 4 else Component(t[0], t[2])) component_item.setName('Component') null_component_item = Keyword('null') - then - semicolon null_component_item.setParseAction( lambda t: Component(t[0], '', [t[1]])) null_component_item.setName('NullComponent') component_list << (Group( Optional(null_component_item) - component_item - ZeroOrMore(component_item))) component_list.setParseAction(lambda t: t.asList()) # Types type_definition = (enumeration_type_definition | integer_type_definition | message_type_definition | type_refinement_definition | array_type_definition) type_declaration = (Keyword('type') - identifier - Keyword('is') - type_definition - semicolon) type_declaration.setParseAction(parse_type) # Package basic_declaration = type_declaration package_declaration = (Keyword('package') - identifier - Keyword('is') - Group(ZeroOrMore(basic_declaration)) - Keyword('end') - name - semicolon) package_declaration.setParseAction( lambda t: Package(t[1], t[3].asList())) # Context context_item = Keyword('with') - identifier - semicolon context_item.setParseAction(lambda t: t[1]) context_clause = ZeroOrMore(context_item) context_clause.setParseAction(lambda t: Context(t.asList())) # Specification specification = Optional(context_clause + package_declaration) specification.setParseAction(lambda t: Specification(t[0], t[1]) if len(t) == 2 else None) # Grammar self.__grammar = specification + StringEnd() self.__grammar.setParseAction(self.__evaluate_specification) self.__grammar.ignore(comment)