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_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_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_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_term(p): '''term : term MUL factor | term DIV factor | term MOD factor | term AND factor | factor''' if len(p) == 2: p[0] = Node("term-factor", [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("term-term", [p[1], p[3]]) if p[2] == '*': 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') elif p[2] == '/': symbol = table.get_temp('real') elif p[2].lower() in ['div', 'mod']: # pascal 语言里 div 和 / 是不同的 # div 表示整除,总得到一个整数 # / 表示浮点数除,总得到一个浮点数 if type_of_node(p[1]) != 'integer': raise ValueError('Type mismatch: %s' % type_of_node(p[1])) if type_of_node(p[3]) != 'integer': raise ValueError('Type mismatch: %s' % type_of_node(p[3])) symbol = table.get_temp('integer') elif p[2].lower() == 'and': symbol = table.get_temp('boolean') emit(p[2], symbol, p[1], p[3]) p[0].symbol = symbol
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_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_expression(p): '''expression : expression GE expr | expression GT expr | expression LE expr | expression LT expr | expression EQUAL expr | expression UNEQUAL expr | expr''' if len(p) == 2: p[0] = Node("expression", [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("expression", [p[1], p[3]]) symbol = table.get_temp('boolean') 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_factor_function(p): '''factor : NAME LP args_list RP''' # TODO p[0] = Node("p_factor_function", [p[3]]) function = table.get_identifier(p[1]) p[0].value = None p[0].type = function.type for item, param in zip(p[3].list, function.params): if param[2]: emit("REFER", None, item) else: emit("PARAM", None, item) symbol = table.get_temp(p[0].type) emit("CALL", symbol, p[1], table.get_identifier_scope(p[1])) p[0].symbol = symbol