예제 #1
0
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
예제 #3
0
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)))
예제 #4
0
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)))
예제 #5
0
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