def optimize(syntax_tree, sql): if syntax_tree.operator == 'SELECT': condition = syntax_tree.condition sql = condition.split('&') relation = [] for i in range(len(sql)): if search(sql[i]) is not None: relation.append(search(sql[i])) syntax_tree = optimize(syntax_tree.left_child, sql) elif syntax_tree.operator == 'PROJECTION': syntax_tree.left_child = optimize(syntax_tree.left_child, sql) elif syntax_tree.operator == 'JOIN': first_tree = SyntaxTree() first_tree.operator = 'SELECT' first_tree.condition = sql[0] first_tree.left_child = syntax_tree.left_child syntax_tree.left_child = first_tree if len(sql) == 1: return syntax_tree second_tree = SyntaxTree() second_tree.operator = 'SELECT' second_tree.condition = sql[1] second_tree.right_child = syntax_tree.right_child syntax_tree.right_child = second_tree return syntax_tree
def parse(sql_statement): sql = sql_statement.split() execute_tree = SyntaxTree() index = 0 while True: if index >= len(sql): break #处理一元运算符 elif sql[index] == 'SELECT' or sql[index] == 'PROJECTION': execute_tree.operator = sql[index] index += 2 # 从[开始到]里面的全部记录下来 condition = '' while sql[index] != ']': condition += sql[index] condition += ' ' index += 1 index += 1 execute_tree.condition = condition #处理二元运算符 elif sql[index] == 'JOIN': # 连接操作需要创建子树,所以分开写 execute_tree.operator = sql[index] execute_tree.left_child = SyntaxTree() execute_tree.left_child.attribute = sql[index - 1] execute_tree.right_child = SyntaxTree() execute_tree.right_child.attribute = sql[index + 1] index += 1 #处理子查询,进行递归 elif sql[index] == '(': index += 1 statement = '' while index < len(sql) and sql[index] != ')': statement += sql[index] statement += ' ' index += 1 index += 1 execute_tree.left_child = parse(statement) else: index += 1 return execute_tree
def parse(sql_statement): sql = sql_statement.split() execute_tree = SyntaxTree() index = 0 while True: if index >= len(sql): break elif sql[index] == 'SELECT' or sql[index] == 'PROJECTION': execute_tree.operator = sql[index] index += 2 # 从[开始到]里面的全部记录下来 condition = '' while sql[index] != ']': condition += sql[index] condition += ' ' index += 1 index += 1 execute_tree.condition = condition elif sql[index] == 'JOIN': # 连接操作需要创建子树,所以分开写 execute_tree.operator = sql[index] execute_tree.left_child = SyntaxTree() execute_tree.left_child.attribute = sql[index - 1] execute_tree.right_child = SyntaxTree() execute_tree.right_child.attribute = sql[index + 1] index += 1 elif sql[index] == '(': # 每次遇到这个说明需要创建一棵子树,由于题目中的查询都是只有一个分支,所以可以直接进入下一个子树中 index += 1 statement = '' while index < len(sql) and sql[index] != ')': statement += sql[index] statement += ' ' index += 1 index += 1 execute_tree.left_child = parse(statement) else: index += 1 return execute_tree
from syntaxtree import SyntaxTree from wordbank import WordBank import config import builder if __name__ == '__main__': tree = SyntaxTree() config.load_rules('rules.config', tree) bank = WordBank() config.load_words('words.csv', bank) print(builder.build_sentence(tree, bank, 'S'))
def analyze(self, toks, text, semantic=False, context=None): if not toks: return SyntaxTree(TokenType.END), [] err_strs = [] status_stack = [0] sym_stack = [SyntaxTree(TokenType.END)] tok_idx = 0 accept = False if context is None: context = SemanticContext() if toks[-1] != TokenType.END: toks = toks + [Token(TokenType.END, None, 0, -1)] while tok_idx < len(toks): tok = toks[tok_idx] if tok.type == TokenType.CCOMMENT: tok_idx += 1 continue toktype = tok.type status = status_stack[-1] if self._has_error(status, toktype): err_strs.append(self._gen_err_str(tok, text)) tok_idx += 1 continue act, number = self.action_table[status][toktype] if act == ActionType.MOVE: tok_idx += 1 status_stack.append(number) sym_stack.append(SyntaxTree(tok)) elif act == ActionType.REDUCE: production = self.productions[number] parent = SyntaxTree(production.lhs) for exp_sym in reversed(production.rhs): status_stack.pop() sym = sym_stack.pop() assert sym.get_sym_name() == str( exp_sym), "Expect {} but get {}".format( exp_sym, sym.get_sym_name()) parent.add_child(sym) parent.childs = parent.childs[::-1] sym_stack.append(parent) act, idx = self.action_table[status_stack[-1]][parent.sym] assert act == ActionType.GOTO status_stack.append(idx) # do action if semantic and production.action: print(production.action.name) try: ret = production.action.do_action(parent, context) if ret: err_code, message = ret else: err_code = 0 except Exception as ex: print(''.join(ex.args)) if err_code: node = parent while node.childs: node = node.childs[0] row, col = count_position(text, node.sym.start) err_strs.append("{}:{} {}".format(row, col, message)) elif act == ActionType.ACCEPT: accept = True break else: assert False if not accept: err_strs.append("Expect More Token") sym = SyntaxTree("Incomplete") while sym_stack: sym.add_child(sym_stack.pop()) sym_stack.append(sym) return sym_stack.pop(), err_strs