def simplify_list(pattern): if type(pattern) == ebnf_semantic.Concatenation: terms = [term for term in pattern.terms if term != None] if len(terms) == 0: return None if len(terms) == 1: return terms[0] return ebnf_semantic.Concatenation(terms) elif type(pattern) == ebnf_semantic.Alternation: clauses = sorted(list(set([clause for clause in pattern.clauses if clause != None]))) if len(clauses) == 0: return None if len(clauses) == 1: result = clauses[0] else: result = ebnf_semantic.Alternation(clauses) if None in pattern.clauses: result = ebnf_semantic.Optional(result) return result return pattern
def build_state_node_for_optional(pattern, cache): subnode = build_state_node(pattern.rhs, cache) transitions = {symbol: next_pattern for symbol, next_pattern in subnode.transitions.items()} if None in transitions and transitions[None] != None: transitions[None] = ebnf_semantic.Optional(transitions[None]) else: transitions[None] = None node = StateNode() node.transitions = transitions return node
def simplify_alternation_with_repetition(pattern): clauses = [simplify_list(ebnf_semantic.Concatenation([clause.rhs, clause])) if type(clause) == ebnf_semantic.Repetition else clause for clause in pattern.clauses] return ebnf_semantic.Optional(simplify_list(ebnf_semantic.Alternation(clauses)))
def simplify_alternation_with_optional(pattern): clauses = [clause.rhs if type(clause) == ebnf_semantic.Optional else clause for clause in pattern.clauses] return ebnf_semantic.Optional(simplify_list(ebnf_semantic.Alternation(clauses)))
def simplify_concatenation_to_repetition(term1, term2): term1 = ebnf_semantic.Optional(simplify_list(ebnf_semantic.Concatenation([term1.rhs, term1]))) return simplify_concatenation_to_optional(term1, term2)
def merge_maps(prefix_map1, prefix_map2, ast_info, cache): if ebnf_semantic.Identifier in map( type, prefix_map1.keys()) and ebnf_semantic.Identifier in map( type, prefix_map2.keys()): identkey1 = None identkey2 = None for c in prefix_map1.keys(): if type(c) == ebnf_semantic.Identifier: identkey1 = c break for c in prefix_map2.keys(): if type(c) == ebnf_semantic.Identifier: identkey2 = c break if identkey1 != identkey2: expanded_map1 = expand_for_merge(prefix_map1, ast_info, cache) expanded_map2 = expand_for_merge(prefix_map2, ast_info, cache) return merge_maps(expanded_map1, expanded_map2, ast_info, cache) elif PartialIdentifier in map( type, prefix_map1.keys()) and PartialIdentifier in map( type, prefix_map2.keys()): identkey1 = None identkey2 = None for c in prefix_map1.keys(): if type(c) == PartialIdentifier: identkey1 = c break for c in prefix_map2.keys(): if type(c) == PartialIdentifier: identkey2 = c break if is_finished_partial(identkey1) and is_finished_partial(identkey2): # ambiguous. which to return? return prefix_map1 if identkey1 != identkey2: expanded_map1 = expand_for_merge(prefix_map1, ast_info, cache) expanded_map2 = expand_for_merge(prefix_map2, ast_info, cache) return merge_maps(expanded_map1, expanded_map2, ast_info, cache) elif ebnf_semantic.Identifier in map( type, prefix_map1.keys()) or PartialIdentifier in map( type, prefix_map1.keys()): expanded_map1 = expand_for_merge(prefix_map1, ast_info, cache) return merge_maps(expanded_map1, prefix_map2, ast_info, cache) elif ebnf_semantic.Identifier in map( type, prefix_map2.keys()) or PartialIdentifier in map( type, prefix_map2.keys()): expanded_map2 = expand_for_merge(prefix_map2, ast_info, cache) return merge_maps(prefix_map1, expanded_map2, ast_info, cache) else: new_map = {} for c in prefix_map1: if c in prefix_map2: subpattern1 = prefix_map1[c] subpattern2 = prefix_map2[c] if subpattern1 == None: if subpattern2 == None: new_map[c] = None else: new_map[c] = ebnf_semantic.Optional( subpattern2, subpattern2.offset) else: if subpattern2 == None: new_map[c] = ebnf_semantic.Optional( subpattern1, subpattern1.offset) else: if type(subpattern1) == ebnf_semantic.Alternation: if type(subpattern2) == ebnf_semantic.Alternation: new_map[c] = ebnf_semantic.Alternation( list(subpattern1.clauses) + list(subpattern2.clauses), subpattern1.clauses[0].offset) else: new_map[c] = ebnf_semantic.Alternation( list(subpattern1.clauses) + [subpattern2], subpattern1.clauses[0].offset) else: if type(subpattern2) == ebnf_semantic.Alternation: new_map[c] = ebnf_semantic.Alternation( [subpattern1] + list(subpattern2.clauses), subpattern1.offset) else: new_map[c] = ebnf_semantic.Alternation( [subpattern1, subpattern2], subpattern1.offset) else: new_map[c] = prefix_map1[c] for c in prefix_map2: if c not in prefix_map1: new_map[c] = prefix_map2[c] return new_map