IndexError list index out of range?

Question:

So I have a code that read from another file, and then looks through it inside the lexer() function. That function works, but I have an error on the parse() function. It says indexerror, but I checked and could not find the problem. I am trying to get the function called getVARRIABLE() to return the error. I have checked the line at which the error happens, which is line 100. Any tips?

Error:

Traceback (most recent call last):
  File "C:UsersmcquiOneDriveDesktopProgramming language for capstonesmain.py", line 134, in <module>
    run()
  File "C:UsersmcquiOneDriveDesktopProgramming language for capstonesmain.py", line 132, in run
    parse(toks)
  File "C:UsersmcquiOneDriveDesktopProgramming language for capstonesmain.py", line 102, in parse
    if toks[i] + " " + toks[i+1][0:6] == "show STRING" or toks[i] + " " + toks[i+1][0:3] == "show NUM" or toks[i] + " " + toks[i+1][0:4] == "show EXPR" or toks[i] + " " + toks[i+1][0:3] == "show VAR":
IndexError: list index out of range

main.py:


from lib2to3.pgen2 import token
from sys import *
tokens = []
symbols = {}

def open_file(filename):
    data = open(filename, 'r').read()
    data += "<EOF>"
    return data

def lexer(filecontents):
    filecontents = list(filecontents)
    tok = ""
    state = 0
    isexpr = 0
    string = ""
    var = ""
    expr = ""
    varstarted = 0
    n = ""
    for char in filecontents:
        tok += char
        if tok == " ":
            if state == 0:
                tok = ""
            else:
                tok = " "
        elif tok =="n" or tok =="<EOF>":
            if expr != "" and isexpr == 1:
                tokens.append("EXPR:" + expr)
                expr = ""
            elif expr != "" and isexpr == 0:
                tokens.append("NUM:" + expr)
                expr = ""
            elif var != "":
                tokens.append("VAR:" + var)
                var = ""
                varstarted = 0
            tok = ""
        elif tok == '=' and state == 0:
            if var != "":
                tokens.append("VAR:" + var)
                var = ""
                varstarted = 0
            tokens.append("EQUALS")
            tok = ""
        
        elif tok == "var " and state == 0:
            varstarted = 1
            var += tok
            tok = ""
        elif varstarted == 1:
            if tok == '<' or tok == '>':
                if var != "":
                    tokens.append("VAR:" + var)
                    var = ""
                    varstarted = 0
            var += tok
            tok = ""
        elif tok == "show" or tok == 'SHOW':
            tokens.append("show")
            tok = ""
        elif tok.isdigit():
            expr += tok
            tok = ""
        elif tok == '+' or tok=='-' or tok=='*'or tok=='/' or tok=='(' or tok==')':
            isexpr = 1
            expr+=tok
            tok = ""
        elif tok == """:
            if state == 0:
                state = 1
            elif state == 1:
                tokens.append("STRING:" + string + """)
                string = ""
                state = 0
                tok = ""
        elif state == 1:
            string += tok
            tok = ""
    return tokens
    # print(tokens)
    # return ''

def doAssign(varname, varvalue):
    # To get back VAR variable just change to [4:]
    symbols[varname[8:]] = varvalue

def getVARIABLE(varname):
 varname = varname[8:]
 if varname in symbols:
  return symbols[varname]
 else:
  return "VARIABLE ERROR: Undefind VARIABLE"


def parse(toks):
    i = 0
    while(i < len(toks)):
        if toks[i] + " " + toks[i+1][0:6] == "show STRING" or toks[i] + " " + toks[i+1][0:3] == "show NUM" or toks[i] + " " + toks[i+1][0:4] == "show EXPR" or toks[i] + " " + toks[i+1][0:3] == "show VAR":
            if toks[i+1][0:6] == "STRING":
                print(toks[i+1][8:-1])
            elif toks[i+1][0:3] == "NUM":
                print(toks[i+1][4:])
            elif toks[i+1][0:4] == "EXPR":
                print(eval(toks[i+1][5:]))
            elif toks[i+1][0:3] == "VAR":
                print(getVARIABLE(toks[i+1]))
            i+=2
        elif toks[i][0:3] + " " + toks[i + 1] + " " + toks[i + 2][0:6]== "VAR EQUALS STRING" or toks[i][0:3] + " " + toks[i + 1] + " " + toks[i + 2][0:3]== "VAR EQUALS NUM" or toks[i][0:3] + " " + toks[i + 1] + " " + toks[i + 2][0:4]== "VAR EQUALS EXPR":
            
            if toks[i+2][0:6] == "STRING":
                doAssign(toks[i], toks[i + 2])
            elif toks[i+2][0:3] == "NUM":
                doAssign(toks[i], toks[i + 2])
            elif toks[i+2][0:4] == "EXPR":
                doAssign(toks[i],"NUM:"+ str(eval( toks[i + 2][5:])))
            i+=3
    print(symbols)

##################################################################################





def run():
    data = open_file(argv[1])
    toks = lexer(data)
    parse(toks)

run()

input file:

var variable = 10+1308

show amog
Asked By: Kirill McQuillin

||

Answers:

toks[i+1] is outside the list when you’re on the last token, and toks[i+2] is outside when you’re on the 2nd-to-last token. So check if you’re in range before doing these tests.

You also need an else: case to increment i when none of the other cases match.

def parse(toks):
    i = 0
    while i < len(toks):
        if i < len(toks) - 1 and (toks[i] + " " + toks[i+1][0:6] == "show STRING" or toks[i] + " " + toks[i+1][0:3] == "show NUM" or toks[i] + " " + toks[i+1][0:4] == "show EXPR" or toks[i] + " " + toks[i+1][0:3] == "show VAR"):
            if toks[i+1][0:6] == "STRING":
                print(toks[i+1][8:-1])
            elif toks[i+1][0:3] == "NUM":
                print(toks[i+1][4:])
            elif toks[i+1][0:4] == "EXPR":
                print(eval(toks[i+1][5:]))
            elif toks[i+1][0:3] == "VAR":
                print(getVARIABLE(toks[i+1]))
            i+=2
        elif i < len(toks) - 2 and (toks[i][0:3] + " " + toks[i + 1] + " " + toks[i + 2][0:6]== "VAR EQUALS STRING" or toks[i][0:3] + " " + toks[i + 1] + " " + toks[i + 2][0:3]== "VAR EQUALS NUM" or toks[i][0:3] + " " + toks[i + 1] + " " + toks[i + 2][0:4]== "VAR EQUALS EXPR"):
            
            if toks[i+2][0:6] == "STRING":
                doAssign(toks[i], toks[i + 2])
            elif toks[i+2][0:3] == "NUM":
                doAssign(toks[i], toks[i + 2])
            elif toks[i+2][0:4] == "EXPR":
                doAssign(toks[i],"NUM:"+ str(eval( toks[i + 2][5:])))
            i+=3
        else:
            i += 1
    print(symbols)
Answered By: Barmar
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.