Esempio n. 1
0
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)
Esempio n. 2
0
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]
Esempio n. 3
0
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
Esempio n. 4
0
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']}
Esempio n. 5
0
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
Esempio n. 6
0
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)
Esempio n. 7
0
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'])
Esempio n. 8
0
def p_output(p):
    'output : PRINT expression'
    aux = codegen.opdos.pop()
    codegen.gen_quad(dir.printt, aux['dir'], -1, -1)
Esempio n. 9
0
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'])
Esempio n. 10
0
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)
Esempio n. 11
0
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'])
Esempio n. 12
0
def p_return(p):
    '''return : RETURN expression'''
    aux = codegen.opdos.pop()
    codegen.gen_quad(dir.retorno, aux['dir'], -1, -1)
Esempio n. 13
0
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
Esempio n. 14
0
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)
Esempio n. 15
0
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')