def expand_terminal(pattern, ast_info, cache): c = pattern.terminal[0] rest = pattern.terminal[1:] if rest: return {ebnf_semantic.Terminal(c, pattern.offset): ebnf_semantic.Terminal(rest, pattern.offset + 1)} return {ebnf_semantic.Terminal(c, pattern.offset): None}
def build_state_node_for_concatenation(pattern, cache): terms = list(pattern.terms) subnode = build_state_node(terms[0], cache) transitions = { symbol: simplify_list(ebnf_semantic.Concatenation([next_pattern] + terms[1:])) for symbol, next_pattern in subnode.transitions.items() if symbol != EOF } if EOF in subnode.transitions: clauses = [] for symbol, next_pattern in transitions.items(): if type(symbol) == str: clauses.append( simplify_list( ebnf_semantic.Concatenation( [ebnf_semantic.Terminal(symbol), next_pattern]))) else: clauses.append( simplify_list( ebnf_semantic.Concatenation([symbol, next_pattern]))) clauses.append( simplify_list( ebnf_semantic.Concatenation([subnode.transitions[EOF]] + terms[1:]))) simplified_pattern = simplify_list(ebnf_semantic.Alternation(clauses)) return build_state_node(simplified_pattern, cache) node = StateNode() node.transitions = transitions return node
def expand_transitions(transitions, cache): ast_info = cache["ast_info"] clauses = [] threads = set({}) for symbol, next_pattern in transitions.items(): if type(symbol) == ebnf_semantic.Identifier: identifier_pattern = ast_info.rules[symbol.identifier] thread = simplify_list(ebnf_semantic.Concatenation([symbol, next_pattern])) clause = simplify_list(ebnf_semantic.Concatenation([ExpandedIdentifier(symbol.identifier, identifier_pattern, thread), next_pattern])) threads.add(thread) elif type(symbol) == ExpandedIdentifier: subnode = build_state_node(symbol.subpattern, cache) clauses1 = [] for symbol1, next_pattern1 in subnode.transitions.items(): if type(symbol1) == str: symbol2 = ebnf_semantic.Terminal(symbol1) else: symbol2 = symbol1 if next_pattern1 == None: clause1 = simplify_list(ebnf_semantic.Concatenation([symbol2, ReduceAction(symbol.identifier, symbol.thread), next_pattern])) else: clause1 = simplify_list(ebnf_semantic.Concatenation([symbol2, ExpandedIdentifier(symbol.identifier, next_pattern1, symbol.thread), next_pattern])) clauses1.append(clause1) clause = simplify_list(ebnf_semantic.Alternation(clauses1)) elif type(symbol) == ForkAction: clause = next_pattern threads.update(symbol.threads) elif type(symbol) == str: clause = simplify_list(ebnf_semantic.Concatenation([ebnf_semantic.Terminal(symbol), next_pattern])) elif symbol == None: clause = next_pattern else: clause = simplify_list(ebnf_semantic.Concatenation([symbol, next_pattern])) clauses.append(clause) expanded_pattern = simplify_list(ebnf_semantic.Alternation(clauses)) if len(threads) > 0: expanded_pattern = simplify_list(ebnf_semantic.Concatenation([ForkAction(threads), expanded_pattern])) return expanded_pattern
def get_prefix_map_for_terminal(pattern, ast_info, cache): c = pattern.terminal[0] rest = pattern.terminal[1:] if not rest: return {c: None} return {c: ebnf_semantic.Terminal(rest, pattern.offset + 1)}
def build_state_node_for_terminal(pattern, cache): terminal = pattern.terminal node = StateNode() if len(terminal) == 1: node.transitions = {terminal[0]: EOF} else: node.transitions = {terminal[0]: ebnf_semantic.Terminal(terminal[1:])} return node
def expand_term(term, ast_info, cache): prefix_map1 = expand_pattern(term, ast_info, cache) prefix_map = {} for c, subpattern in prefix_map1.items(): if type(c) == str: prefix_map[ebnf_semantic.Terminal(c)] = subpattern else: prefix_map[c] = subpattern clauses = [] for pattern, next_pattern in prefix_map.items(): clauses.append(simplify_list(ebnf_semantic.Concatenation([pattern, next_pattern]))) return simplify_list(ebnf_semantic.Alternation(clauses))
def expand_reduce_action(symbol, next_pattern, cache): if next_pattern == EOF: return symbol if has_only_reduce_actions(next_pattern): return simplify_list( ebnf_semantic.Concatenation([symbol, next_pattern])) if type(next_pattern) == ForkAction: return simplify_list( ebnf_semantic.Concatenation([next_pattern, symbol])) if type(next_pattern) == ExpandedIdentifier: # XXX return simplify_list( ebnf_semantic.Concatenation([next_pattern, symbol])) if type(next_pattern) == ebnf_semantic.Terminal: first = next_pattern.terminal[0] rest = next_pattern.terminal[1:] if not rest: return simplify_list( ebnf_semantic.Concatenation( [ebnf_semantic.Terminal(first), symbol])) return simplify_list( ebnf_semantic.Concatenation([ ebnf_semantic.Terminal(first), symbol, ebnf_semantic.Terminal(rest) ])) if type(next_pattern) == ebnf_semantic.Identifier: # XXX return simplify_list( ebnf_semantic.Concatenation([next_pattern, symbol])) if type(next_pattern) == ebnf_semantic.Optional: clause1 = symbol clause2 = expand_reduce_action(symbol, next_pattern.rhs, cache) return simplify_list(ebnf_semantic.Alternation([clause1, clause2])) if type(next_pattern) == ebnf_semantic.Repetition: # clause1 = symbol # XXX clause2 = expand_reduce_action(symbol, simplify_list(ebnf_semantic.Concatenation([next_pattern.rhs, next_pattern])), cache) # return simplify_list(ebnf_semantic.Alternation([clause1, clause2])) return simplify_list(ebnf_semantic.Alternation([symbol, next_pattern])) if type(next_pattern) == ebnf_semantic.Concatenation: i = 0 while has_only_reduce_actions(next_pattern.terms[i]): i += 1 if i == 0: return simplify_list( ebnf_semantic.Concatenation([ expand_reduce_action(symbol, next_pattern.terms[0], cache) ] + list(next_pattern.terms[1:]))) new_symbol = simplify_list( ebnf_semantic.Concatenation([symbol] + list(next_pattern.terms[:i]))) return expand_reduce_action( new_symbol, simplify_list(ebnf_semantic.Concatenation(next_pattern.terms[i:])), cache) if type(next_pattern) == ebnf_semantic.Alternation: clauses = [ expand_reduce_action(symbol, clause, cache) for clause in next_pattern.clauses ] return simplify_list(ebnf_semantic.Alternation(clauses)) raise Exception("Shouldn't reach this point.")