def p_procedure_name(p): '''procedure_name : NAME''' p[0] = Node("procedure_name", p[1]) table.define(p[1], 'integer', 'procedure') table.add_scope(p[1], 'function', 'integer') p[0].name = p[1]
def p_val_para_list(p): # 值传递 '''val_para_list : name_list ''' p[0] = Node("val_para_list", [p[1]]) p[0].list = p[1].list
def p_else_clause(p): '''else_clause : ELSE stmt | empty''' if len(p) == 3: p[0] = Node("else_clause", [p[2]]) else: p[0] = Node("else_clause", [p[1]])
def p_function_name(p): '''function_name : NAME ''' p[0] = Node("function_name", p[1]) table.define(p[1], 'integer', 'function') table.add_scope(p[1], 'function', 'integer') p[0].name = p[1]
def p_var_decl_list(p): '''var_decl_list : var_decl_list var_decl | var_decl''' if len(p) == 3: p[0] = Node("var_decl_list", [p[1], p[2]]) else: p[0] = Node("var_decl_list", [p[1]])
def p_case_expr_list(p): '''case_expr_list : case_expr_list case_expr | case_expr''' if len(p) == 3: p[0] = Node("case_expr_list", [p[1], p[2]]) else: p[0] = Node("case_expr_list", [p[1]])
def p_const_part(p): '''const_part : CONST const_expr_list | empty''' if len(p) == 3: p[0] = Node("const_part", [p[2]]) elif len(p) == 2: p[0] = Node("const_part", [])
def p_var_part(p): '''var_part : VAR var_decl_list | empty''' if len(p) == 3: p[0] = Node("var_part", [p[2]]) else: p[0] = Node("var_part", [p[1]])
def p_type_decl_list(p): '''type_decl_list : type_decl_list type_definition | type_definition''' if len(p) == 3: p[0] = Node("type_decl_list", [p[1], p[2]]) else: p[0] = Node("type_decl_list", [p[1]])
def p_type_decl(p): '''type_decl : simple_type_decl | array_type_decl | record_type_decl''' p[0] = Node("type_decl", [p[1]]) p[0].type = p[1].type
def p_type_part(p): '''type_part : TYPE type_decl_list | empty''' if len(p) == 3: p[0] = Node("type_part", [p[2]]) else: p[0] = Node("type_part", [p[1]])
def p_const_value(p): '''const_value : INTEGER | REAL | CHAR | STRING | SYS_CON | true | false''' p[0] = Node("const_value", p[1]) p[0].value = p[1] if type(p[1]) == int: p[0].type = 'integer' elif type(p[1]) == float: p[0].type = 'real' elif type(p[1]) == str: p[0].type = 'char' if str(p[1]).lower() == 'true': p[0].type = 'boolean' p[0].value = True if str(p[1]).lower() == 'false': p[0].type = 'boolean' p[0].value = False
def p_const_expr_list(p): '''const_expr_list : const_expr_list const_expr | const_expr''' if len(p) == 3: p[0] = Node("const_expr_list", [p[1], p[2]]) elif len(p) == 2: p[0] = Node("const_expr_list", [p[1]])
def p_stmt(p): '''stmt : stmt_label non_label_stmt | non_label_stmt''' if len(p) == 3: p[0] = Node("stmt", [p[2]]) else: p[0] = Node("stmt", [p[1]])
def p_stmt_list(p): '''stmt_list : stmt_list stmt SEMI | empty''' if len(p) == 4: p[0] = Node("stmt_list", [p[1], p[2]]) else: p[0] = Node("stmt_list", [p[1]])
def p_factor_not(p): '''factor : NOT factor''' p[0] = Node("factor", [p[2]]) symbol = table.get_temp(type_of_node(p[2])) emit('NOT', symbol, p[2]) p[0].symbol = symbol
def p_factor_minus(p): '''factor : MINUS factor''' p[0] = Node("factor", [p[2]]) symbol = table.get_temp(type_of_node(p[2])) emit('-', symbol, 0, p[2]) p[0].symbol = symbol
def p_while_label1(p): '''while_label1 : ''' p[0] = Node("", []) p[0].label1 = table.get_label() p[0].label3 = table.get_label() emit('LABEL', p[0].label1)
def p_factor_1(p): '''factor : LP expression RP ''' p[0] = Node("factor", [p[2]]) if hasattr(p[2], 'symbol'): p[0].symbol = p[2].symbol else: p[0].value = p[2].value p[0].type = p[2].type
def p_if_label1(p): '''if_label1 : ''' p[0] = Node("", []) p[0].label2 = table.get_label() p[0].label3 = table.get_label() emit('BEQ', p[0].label2, p[-2], False)
def p_factor_array(p): '''factor : NAME LB expression RB ''' # FIXME: 这个地方只有可能是在右边的数组索引,而不是左边的,所以将内容载入到临时变量里面吧 p[0] = Node("p_factor_array", [p[3]]) # FIXME: 也需要创建一个临时变量 symbol = table.get_identifier(p[1]) symbol = table.get_temp(type_of_node(symbol)) emit('LOADREF', symbol, p[1], p[3]) p[0].symbol = symbol
def p_routine_part(p): '''routine_part : routine_part function_decl | routine_part procedure_decl | function_decl | procedure_decl | empty''' if len(p) == 3: p[0] = Node("routine_part", [p[1], p[2]]) else: p[0] = Node("routine_part", [p[1]])
def p_factor_name(p): '''factor : NAME''' p[0] = Node('factor', [p[1]]) symbol = table.get_identifier(p[1]) if symbol.var_function == 'function': if table.scope().name.endswith('.' + symbol.name): symbol = table.get_identifier('_return') p[0].symbol = symbol
def p_array_type_decl(p): '''array_type_decl : ARRAY LB INTEGER DOTDOT INTEGER RB OF type_decl''' # 0 1 2 3 4 5 6 7 8 # TODO 只支持常数中的整数,并且是单维 # '''array_type_decl : ARRAY LB simple_type_decl RB OF type_decl''' p[0] = Node("array_type_decl", [p[3], p[5], p[8]]) symbol = table.get_temp('array', 'type', { 'data_type': p[8].type, 'dimension': [(p[3], p[5])] }) p[0].type = symbol.name
def p_for_label1(p): '''for_label1 : ''' p[0] = Node("", []) symbol = table.get_identifier(p[-6]) emit('+', symbol, p[-4], 0) p[0].label1 = table.get_label() p[0].label2 = table.get_label() p[0].symbol = symbol emit('LABEL', p[0].label1)
def p_factor_2(p): '''factor : NAME DOT NAME''' p[0] = Node("p_factor_1", [p[1], p[2], p[3]]) symbol = table.get_identifier(p[1]) params = symbol.get_params() try: symbol = table.get_temp( [a_tuple for a_tuple in params if a_tuple[0] == p[3]][0][1]) except IndexError: raise ValueError("Dot index error") emit('LOADREF', symbol, p[1], p[3]) p[0].symbol = symbol
def p_expr(p): '''expr : expr PLUS term | expr MINUS term | expr OR term | term''' if len(p) == 2: p[0] = Node("expr-term", [p[1]]) if hasattr(p[1], 'symbol'): p[0].symbol = p[1].symbol else: p[0].value = p[1].value p[0].type = p[1].type else: p[0] = Node("expr-expr", [p[1], p[3]]) if p[2] == 'or': symbol = table.get_temp('boolean') else: print(type_of_node(p[1])) print(type_of_node(p[3])) if type_of_node(p[1]) == 'real' or type_of_node(p[3]) == 'real': symbol = table.get_temp('real') else: symbol = table.get_temp('integer') emit(p[2], symbol, p[1], p[3]) p[0].symbol = symbol
def p_function_head(p): '''function_head : FUNCTION function_name parameters COLON simple_type_decl ''' p[0] = Node("function_head", [p[3], p[5]]) for name, type, reference in p[3].list: table.define(name, type, reference=reference) table.define('_return', p[5].type, 'var', p[3].list) table.scope().return_type = p[5].type table.get_identifier(p[2].name).type = p[5].type table.get_identifier(p[2].name).params = p[3].list symbol = table.get_identifier('_return') p[0].symbol = symbol emit("LABEL", p[2].name, table.scope().name)
def p_if_label2(p): '''if_label2 : ''' p[0] = Node("", []) emit('JMP', p[-2].label3) emit('LABEL', p[-2].label2)
def p_proc_stmt_read(p): '''proc_stmt : READ LP factor RP''' p[0] = Node("proc_stmt", [p[3]]) if hasattr(p[3], 'symbol'): emit("INPUT", p[3].symbol) else: raise ValueError("destination is not variable")