Esempio n. 1
0
 def arr_brace(sym: SyntaxTree, context: SemanticContext):
     size = sym.childs[1].sym.val
     dims = [size]
     ll_dims = sym.childs[3].get_attr('dims')
     if ll_dims:
         dims.extend(ll_dims)
     sym.set_attr('dims', dims)
Esempio n. 2
0
 def expr_idn(sym: SyntaxTree, context: SemanticContext):
     var = sym.childs[0].sym.val
     symbol = context.lookup_sym(var)
     if not symbol:
         return -1, "{} is not defined".format(var)
     operand = Operand(var, symbol.type)
     sym.set_attr("res", operand)
Esempio n. 3
0
 def struct_type(sym: SyntaxTree, context: SemanticContext):
     vardl = sym.childs[2]
     eles = vardl.get_attr('eles')
     sym_width = vardl.get_attr('width')
     sym_type = STypeRecord(eles)
     sym.set_attr('type', sym_type)
     sym.set_attr('width', sym_width)
Esempio n. 4
0
 def stmt_s(sym: SyntaxTree, context: SemanticContext):
     saddr = sym.childs[1].get_attr('quad')
     s1nl = sym.childs[0].get_attr('nl')
     s2nl = sym.childs[2].get_attr('nl')
     if s1nl:
         context.back_patch(s1nl, saddr)
     sym.set_attr('nl', s2nl)
Esempio n. 5
0
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
Esempio n. 6
0
 def arr_ref_one(sym: SyntaxTree, context: SemanticContext):
     start = context.addr
     sym.set_attr('start', start)
     var = sym.childs[0].sym.val
     symbol = context.lookup_sym(var)
     if not symbol:
         return -1, "{} is not defined".format(var)
     elif not isinstance(symbol.type, STypeArray):
         return -1, "{} is not a valid array".format(var)
     index_res = sym.childs[2].get_attr('res')
     # get offset
     ele_type = symbol.type.get_ele_type()
     if index_res != 0:
         res1 = context.gen_tmp()
         ele_type_width = get_type_width(ele_type)
         context.gen_ins("*", index_res, ele_type_width, res1)
         res2 = context.gen_tmp()
         context.gen_ins('&', var, None, res2)
         res = context.gen_tmp()
         context.gen_ins('+', res2, res1, res)
     else:
         res = context.gen_tmp()
         context.gen_ins('&', var, None, res)
     res_type = STypePtr(ele_type)
     sym.set_attr('res', Operand(res, res_type))
Esempio n. 7
0
    def arr_ref(sym: SyntaxTree, context: SemanticContext):
        start = context.addr
        sym.set_attr('start', start)
        operand = sym.childs[0].get_attr('res')
        last_res = operand.val
        last_type = operand.type
        arr_type = last_type.get_ref_type()
        if not isinstance(arr_type, STypeArray):
            return -1, "Too many array brackets"
        ele_type = arr_type.get_ele_type()

        index_operand = sym.childs[2].get_attr('res')
        index_res = index_operand.val
        index_type = index_operand.type
        if index_type != TokenType.INT:
            return -1, "Array index must be int"
        if index_res != 0:
            res1 = context.gen_tmp()
            ele_type_width = get_type_width(ele_type)
            context.gen_ins("*", index_res, ele_type_width, res1)
            res = context.gen_tmp()
            context.gen_ins('+', last_res, res1, res)
        else:
            res = last_res
        res_type = STypePtr(ele_type)
        sym.set_attr('res', Operand(res, res_type))
Esempio n. 8
0
 def stmt_if(sym: SyntaxTree, context: SemanticContext):
     sym_b = sym.childs[1]
     sym_s = sym.childs[4]
     sstart = sym.childs[3].get_attr('quad')
     btl = sym_b.get_attr('tl')
     bfl = sym_b.get_attr('fl')
     context.back_patch(btl, sstart)
     snl = bfl + sym_s.get_attr('nl')
     sym.set_attr('nl', snl)
Esempio n. 9
0
 def sub_val(sym: SyntaxTree, context: SemanticContext):
     tok = sym.childs[1].sym
     if tok.type == TokenType.CINT:
         res_type = TokenType.INT
     elif tok.type == TokenType.CFLOAT:
         res_type = TokenType.FLOAT
     else:
         assert False, "Invalid Type {}".format(tok.type)
     sym.set_attr("res", Operand(-tok.val, res_type))
Esempio n. 10
0
 def bool_expr2(sym: SyntaxTree, context: SemanticContext):
     sym_g = sym.childs[0]
     sym_h = sym.childs[3]
     quad = sym.childs[2].get_attr('quad')
     gtl = sym_g.get_attr('tl')
     htl = sym_h.get_attr('tl')
     gfl = sym_g.get_attr('fl')
     hfl = sym_h.get_attr('fl')
     context.back_patch(gtl, quad)
     sym.set_attr('tl', htl)
     sym.set_attr('fl', gfl + hfl)
Esempio n. 11
0
 def bool_expr1(sym: SyntaxTree, context: SemanticContext):
     sym_b = sym.childs[0]
     sym_g = sym.childs[3]
     quad = sym.childs[2].get_attr('quad')
     btl = sym_b.get_attr('tl')
     gtl = sym_g.get_attr('tl')
     bfl = sym_b.get_attr('fl')
     gfl = sym_g.get_attr('fl')
     context.back_patch(bfl, quad)
     sym.set_attr('tl', btl + gtl)
     sym.set_attr('fl', gfl)
Esempio n. 12
0
 def param_list_one(sym: SyntaxTree, context: SemanticContext):
     child_type = sym.childs[0].get_attr('type')
     child_width = sym.childs[0].get_attr('width')
     child_name = sym.childs[1].sym.val
     context.add_sym(child_name, child_type)
     params = [{
         'name': child_name,
         'type': child_type,
         'width': child_width
     }]
     sym.set_attr('params', params)
Esempio n. 13
0
 def stmt_while(sym: SyntaxTree, context: SemanticContext):
     sym_b = sym.childs[2]
     sym_s = sym.childs[6]
     bstart = sym.childs[1].get_attr('quad')
     sstart = sym.childs[5].get_attr('quad')
     snl = sym_s.get_attr('nl')
     btl = sym_b.get_attr('tl')
     bfl = sym_b.get_attr('fl')
     context.back_patch(snl, bstart)
     context.back_patch(btl, sstart)
     context.gen_ins('goto', None, None, bstart)
     sym.set_attr('nl', bfl)
Esempio n. 14
0
 def array_type(sym: SyntaxTree, context: SemanticContext):
     dims = sym.childs[1].get_attr('dims')
     prim_type = sym.childs[0].get_attr('type')
     prim_width = sym.childs[0].get_attr('width')
     if dims:
         sym_type = STypeArray(prim_type, dims)
         ele_num = reduce(lambda total, x: total * x, dims)
     else:
         sym_type = prim_type
         ele_num = 1
     sym.set_attr('type', sym_type)
     sym.set_attr('width', prim_width * ele_num)
Esempio n. 15
0
 def var_decl_list_begin(sym: SyntaxTree, context: SemanticContext):
     child_type = sym.childs[0].get_attr('type')
     child_width = sym.childs[0].get_attr('width')
     child_name = sym.childs[0].get_attr('name')
     eles = {
         child_name: {
             "type": child_type,
             "width": child_width,
             "offset": 0
         }
     }
     sym.set_attr('eles', eles)
     sym.set_attr('offset', child_width)
Esempio n. 16
0
 def prim_type(sym: SyntaxTree, context: SemanticContext):
     sym_type = sym.childs[0].sym.type
     sym.set_attr("type", sym_type)
     if sym_type == TokenType.CHAR:
         width = 1
     elif sym_type == TokenType.SHORT:
         width = 2
     elif sym_type == TokenType.INT or sym_type == TokenType.FLOAT:
         width = 4
     elif sym_type == TokenType.DOUBLE:
         width = 8
     else:
         assert False, "Unknown Type {}".format(str(sym_type))
     sym.set_attr("width", width)
Esempio n. 17
0
 def bool_expr5(sym: SyntaxTree, context: SemanticContext):
     toktype = sym.childs[0].childs[0].sym.type
     start = context.addr
     sym.set_attr('start', start)
     if toktype == TokenType.TRUE:
         ins = context.gen_ins('goto', None, None, None)
         stl = [ins]
         sfl = []
     else:
         ins = context.gen_ins('goto', None, None, None)
         stl = []
         sfl = [ins]
     sym.set_attr('tl', stl)
     sym.set_attr('fl', sfl)
Esempio n. 18
0
 def stmt_if_else(sym: SyntaxTree, context: SemanticContext):
     sym_b = sym.childs[1]
     sym_s1 = sym.childs[4]
     sym_s2 = sym.childs[10]
     else_gate = sym.childs[6]
     s1start = sym.childs[3].get_attr('quad')
     s2start = sym.childs[9].get_attr('quad')
     s1nl = sym_s1.get_attr('nl')
     s2nl = sym_s2.get_attr('nl')
     btl = sym_b.get_attr('tl')
     bfl = sym_b.get_attr('fl')
     context.back_patch(btl, s1start)
     context.back_patch(bfl, s2start)
     snl = s1nl + s2nl + else_gate.get_attr('nl')
     sym.set_attr('nl', snl)
Esempio n. 19
0
 def wrapper(sym: SyntaxTree, context: SemanticContext):
     start = context.addr
     sym.set_attr('start', start)
     op = func(sym, context)
     ysym = sym.childs[0]
     fsym = sym.childs[2]
     yres = ysym.get_attr('res')
     fres = fsym.get_attr('res')
     res = context.gen_tmp()
     res_type = deduce_type(yres.type, fres.type)
     context.gen_ins(op, yres.val, fres.val, res)
     sym.set_attr('res', Operand(res, res_type))
     if res_type is None:
         return -1, "Can't do {} on {} and {}".format(
             op, str(yres.type), str(fres.type))
Esempio n. 20
0
def build_sentence(tree: SyntaxTree, wordBank: WordBank, default: str) -> str:
    sentence = [{'text': default, 'is_word': False}]

    while not is_complete_sentence(sentence):
        for x in range(len(sentence)):
            if sentence[x]['is_word']:
                continue

            con = sentence[x]['text']
            rules = tree.get_rules(con)

            if len(rules) == 0:
                sentence[x] = {'text': wordBank.random_word(
                    con), 'is_word': True}
                break

            rule = rules[random.randrange(len(rules))]
            rule = [{'text': r, 'is_word': False} for r in rule]

            sentence = sentence[:x] + rule + sentence[x + 1:]
            break

    out = ""

    for word in sentence:
        if len(out) != 0:
            out += " "

        out += word['text']

    return out
Esempio n. 21
0
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
Esempio n. 22
0
 def param_list(sym: SyntaxTree, context: SemanticContext):
     has_err = False
     err_strs = []
     child_type = sym.childs[2].get_attr('type')
     child_width = sym.childs[2].get_attr('width')
     child_name = sym.childs[3].sym.val
     sym_param = sym.childs[0]
     params = list(sym_param.get_attr('params'))
     for param in params:
         if child_name == param['name']:
             has_err = True
             err_strs.append("Duplicate parameter {}".format(child_name))
     context.add_sym(child_name, child_type)
     params.append({
         'name': child_name,
         'type': child_type,
         'width': child_width
     })
     sym.set_attr('params', params)
     if has_err:
         return -1, '\n'.join(err_strs)
Esempio n. 23
0
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
Esempio n. 24
0
 def var_decl(sym: SyntaxTree, context: SemanticContext):
     child_type = sym.childs[0].get_attr('type')
     child_width = sym.childs[0].get_attr('width')
     child_name = sym.childs[1].sym.val
     sym.set_attr('type', child_type)
     sym.set_attr('width', child_width)
     sym.set_attr('name', child_name)
Esempio n. 25
0
 def var_decl_list(sym: SyntaxTree, context: SemanticContext):
     has_err = False
     vard = sym.childs[1]
     child_type = vard.get_attr('type')
     child_width = vard.get_attr('width')
     child_name = vard.get_attr('name')
     vardl = sym.childs[0]
     eles = dict(vardl.get_attr('eles'))
     offset = vardl.get_attr('offset')
     if child_name in eles:
         has_err = True
     else:
         eles[child_name] = {
             "type": child_type,
             "width": child_width,
             "offset": offset
         }
         offset += child_width
     sym.set_attr('eles', eles)
     sym.set_attr('offset', offset)
     if has_err:
         return -1, "Duplicate record attribute {}".format(child_name)
Esempio n. 26
0
    def stmt_call(sym: SyntaxTree, context: SemanticContext):
        fname = sym.childs[1].sym.val
        symbol = context.lookup_sym(fname)
        if not symbol:
            return -1, "Function {} is not defined".format(fname)
        args = sym.childs[3].get_attr('args')
        res = Operand(context.gen_tmp(), symbol.type.ret_type)
        context.gen_ins('call', symbol, len(args), res)
        sym.set_attr('res', res)

        args_len = len(args)
        params_len = len(symbol.type.param_types)
        if args_len < params_len:
            return -1, "Too few arguments was given"
        if args_len > params_len:
            return -1, "Too many arguments was given"
        for i in range(args_len):
            if args[i].type != symbol.type.param_types[i] and\
                deduce_type(args[i].type, symbol.type.param_types[i]) is None:
                args_str = ', '.join(map(lambda arg: str(arg.type), args))
                params_str = ', '.join(map(str, symbol.type.param_types))
                return -1, "Incompatible parameter types {}({}). expected {}({})".format(
                    fname, args_str, fname, params_str)
Esempio n. 27
0
 def record_ref(sym: SyntaxTree, context: SemanticContext):
     start = context.addr
     sym.set_attr('start', start)
     var = sym.childs[0].sym.val
     attr = sym.childs[2].sym.val
     symbol = context.lookup_sym(var)
     if not symbol:
         return -1, "{} is not defined".format(var)
     elif not isinstance(symbol.type, STypeRecord):
         return -1, "{} is not a valid structure".format(var)
     offset = symbol.type.get_ele_offset(attr)
     if offset is None:
         return -1, "{} has no attribute {}".format(var, attr)
     if offset != 0:
         res1 = context.gen_tmp()
         context.gen_ins("&", var, None, res1)
         res = context.gen_tmp()
         context.gen_ins('+', res1, offset, res)
     else:
         res = context.gen_tmp()
         context.gen_ins("&", var, None, res)
     res_type = STypePtr(symbol.type.get_ele_type(attr))
     sym.set_attr('res', Operand(res, res_type))
Esempio n. 28
0
 def bool_expr4(sym: SyntaxTree, context: SemanticContext):
     start = context.addr
     sym.set_attr('start', start)
     res1 = sym.childs[0].get_attr('res')
     res2 = sym.childs[2].get_attr('res')
     relop = RELOPS[sym.childs[1].childs[0].sym.type]
     ins1 = context.gen_ins(relop, res1, res2, None)
     sym.set_attr('tl', [ins1])
     ins2 = context.gen_ins('goto', None, None, None)
     sym.set_attr('fl', [ins2])
Esempio n. 29
0
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'))
Esempio n. 30
0
    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