def p_w2(p): 'w2 :' aux = codegen.opdos.pop() if (aux['type'] != bool and aux['type'] != int): errors.append('Line {}: expression must be boolean'.format(lineno+1)) codegen.gen_quad(dir.gotof, aux['dir'], -1, -1) codegen.jumps.append(codegen.curr_ins)
def p_call(p): '''call : ID LPAREN callparams RPAREN | ID LPAREN noparams RPAREN''' # checa si existe la funcion proc = symtable.get_proc(p[1]) if not proc: errors.append("Line {}: Call to an undefined function '{}'".format(lineno, p[1])) raise SyntaxError else: codegen.gen_quad(dir.era, -1, -1, -1) # compara el numero de parametros proc_params = proc['params'] call_params = p[3] call_params.reverse() if len(proc_params) != len(call_params): errors.append("Line {}: wrong number of arguments in call to '{}'".format(lineno, p[1])) raise SyntaxError # compara el tipo de parametros, y genera los cuadruplos correspondientes for i in range(len(call_params)): #if proc_params[i]['type'] != call_params[i]['type']: # errors.append('Line {}: inconsistent parameters in \'{}\''.format(lineno, p[1])) # raise SyntaxError codegen.gen_quad(dir.param, call_params[i]['dir'], -1, proc_params[i]['dir']) codegen.gen_quad(dir.gosub, proc['start_no'], -1, -1) # devuelve el id para usarse en expresiones p[0] = p[1]
def p_array_index(p): '''array_index : LBRACK expression RBRACK''' var = symtable.get_var(p[-1]) if not var: errors.append("Line {}: Undefined variable '{}'".format(p.lineno(1), p[-1])) raise SyntaxError elif not var['dim']: errors.append("Line {}: Variable '{}' is not an array".format(p.lineno(1), p[-1])) raise SyntaxError exp_res = codegen.opdos.pop() if exp_res['type'] != int: errors.append("Line {}: Index must be integer".format(p.lineno(1))) raise SyntaxError liminf = 0 limsup = var['dim']-1 codegen.gen_quad(dir.verifica, exp_res['dir'], liminf, limsup) basedir = symtable.add_constant(var['dir']) pointer = symtable.newpointer() codegen.gen_quad(dir.suma, basedir['dir'], exp_res['dir'], pointer) res = {'dir':pointer, 'type':int, 'dim':None} #codegen.opdos.append(res) p[0] = res
def p_varcte_call(p): '''varcte : call''' var = symtable.proc_table['program']['var_table'][p[1]] tempdir = symtable.newtemp(var['type']) codegen.gen_quad(dir.asigna, var['dir'], -1, tempdir) p[0] = {'dir':tempdir, 'type':var['type']}
def p_w3(p): 'w3 :' gotof_index = codegen.jumps.pop() beginning_index = codegen.jumps.pop() codegen.gen_quad(dir.goto, -1, -1, beginning_index) codegen.quads[gotof_index][3] = codegen.curr_ins+1
def p_i2(p): 'i2 :' codegen.gen_quad(dir.goto, -1, -1, -1) i = codegen.jumps.pop() codegen.quads[i][3] = codegen.curr_ins+1 codegen.jumps.append(codegen.curr_ins)
def p_input(p): 'input : SCAN ID' var = symtable.get_var(p[2]) if not var: var = symtable.add_var(p[2], str, None) codegen.gen_quad(dir.scan, -1, -1, var['dir'])
def p_output(p): 'output : PRINT expression' aux = codegen.opdos.pop() codegen.gen_quad(dir.printt, aux['dir'], -1, -1)
def p_assignment_index_expression(p): '''assignment : ID array_index EQ expression''' exp_res = codegen.opdos.pop() var = p[2] codegen.gen_quad(dir.asigna, exp_res['dir'], -1, var['dir'])
def p_assignment_array(p): '''assignment : ID EQ array''' array = p[3] var = symtable.add_var(p[1], int, len(array)) for i in range(len(array)): codegen.gen_quad(dir.asigna, array[i]['dir'], -1, var['dir']+i)
def p_assignment_expression(p): '''assignment : ID EQ expression''' exp_res = codegen.opdos.pop() var = symtable.add_var(p[1], exp_res['type'], None) codegen.gen_quad(dir.asigna, exp_res['dir'], -1, var['dir'])
def p_return(p): '''return : RETURN expression''' aux = codegen.opdos.pop() codegen.gen_quad(dir.retorno, aux['dir'], -1, -1)
def p_function(p): 'function : DEF ID add_proc defparams statements-block' symtable.end_current_proc() codegen.gen_quad(dir.ret, -1, -1, -1) codegen.quads[codegen.jumps.pop()][3] = codegen.curr_ins+1
def p_add_proc(p): 'add_proc :' codegen.gen_quad(dir.goto, -1, -1, -1) symtable.add_proc(p[-1], codegen.curr_ins+1, int) codegen.jumps.append(codegen.curr_ins)
def p_empty(p): 'empty :' pass def p_error(t): errors.append("Line {}: Syntax error near {}".format(t.lineno, t.value)) # Panic mode: Read ahead looking for a closing '}' #while 1: # tok = yacc.token() # Get the next token # if not tok or tok.type == 'RBRACE': break #yacc.restart() # Build the parser yacc.yacc() # Parse input file if (len(sys.argv) <= 1): print('No file specified, exiting now') else: f = open(sys.argv[1], 'r') yacc.parse(f.read()) codegen.gen_quad(-1, -1, -1, -1) if len(errors) > 0: if len(errors) == 1: print('found '+str(len(errors))+' error:') else: print('found '+str(len(errors))+' errors:') for error in errors: print(' '+error) else: codegen.write_to_file(sys.argv[1].split('.')[0]+'.rlo')