Ejemplo n.º 1
0
def Return(token):

    if len(returnList):
        returnList[-1][2] = 1

    token = lexer.peekNextToken()
    if token[1] == ";" and token[0] == "symbol":
        lexer.getNextToken()  # consume the token
        # No value to be returned, just push const 0
        text("push constant 0")
        if lexer.peekNextToken()[1] != "}":
            Error(token, "Unreachable code")

    elif token[0] in ["id", "number"]:
        # Return expression
        returnData = symbolTable.orderExpr("return")
        if not returnData[0]:
            return returnData

    elif token[1] == "this":
        text("push pointer 0")

    else:
        Error(
            token,
            "Unexpected token of type '" + token[0] + "' cannot be returned.")

    text("return")
    return [1]
Ejemplo n.º 2
0
def F():
    global token
    if token.token_id == Token_ENUM.TK_LEFT_PAR:
        token = getNextToken()
        e = E()
        if token.token_id != Token_ENUM.TK_RIGHT_PAR:
            raise ValueError("Expecting right parenthesis ')', but found ",
                             token.lexema)
        token = getNextToken()
        return F_prime(e)
    else:
        r = R()
        return F_prime(r)
def R():
    global token
    if token.token_id != Token_ENUM.TK_DIGIT and token.token_id != Token_ENUM.TK_LETTER:
        raise ValueError("Expecting a letter or digit, but found ",
                         token.lexema, token.token_id)
    if token.token_id == Token_ENUM.TK_DIGIT:
        digit = Digit(int(token.lexema))
        token = getNextToken()
        return digit
    elif token.token_id == Token_ENUM.TK_LETTER:
        letter = Letter(token.lexema)
        token = getNextToken()
        return letter
Ejemplo n.º 4
0
def setObjectArgs(attribute):

    # Log bracket count when entering a function so you can later tell when the function is exited
    #                       function name,           bracket pointer,    value returned
    returnList.append(
        [symbolTable.objectName, symbolTable.bracketPointer[0], 0])

    token = lexer.getNextToken()
    if token[1] != "(" and token[0] != "symbol":
        Error(token, "Expected '('")

    peekToken = lexer.peekNextToken()
    if peekToken[1] == ")" and peekToken[
            0] == "symbol":  # Check if function has no arguments
        lexer.getNextToken()  # Consume the token

    else:
        # Check syntax of function arguments
        expectedTypeList = [["keyword", "id"], ["id"], ["symbol"]]
        expectedTypePointer = 0
        while token[1] != ")":
            token = lexer.getNextToken()

            if token[0] not in expectedTypeList[expectedTypePointer]:

                Error(token, "Expected a type followed by a variable name")

            elif expectedTypePointer == 0:
                pass

            elif expectedTypePointer == 1:  # add variable to symbol table
                symbolTable.addSymbol(type="argument",
                                      attribute=attribute,
                                      symbol=token[1],
                                      scope="")

            elif expectedTypePointer == 2:
                if not token[1] in [",", ")"]:
                    Error(token, "Expected ')' or ',' in parameters list")

            # incriment pointer
            expectedTypePointer += 1
            if expectedTypePointer == 3:
                expectedTypePointer = 0

    token = lexer.peekNextToken()
    if token[1] != "{" and token[0] != "symbol":
        Error(token, "Expected '{'")

    return [1]
Ejemplo n.º 5
0
def parseFile():
    # Generate a list of methods to later be used in function calls
    token = lexer.peekNextToken()
    while (token[0] != "EOF"):
        if token[1] == "method":
            lexer.peekNextToken()  # consume
            symbolTable.methodList.append(lexer.peekNextToken()[1])
        token = lexer.peekNextToken()

    # Begin main parsing of file
    token = lexer.getNextToken()
    while (token[0] != "EOF"):
        stmt(token)
        token = lexer.getNextToken()
Ejemplo n.º 6
0
def createVar(token, attribute, context):

    # Check syntax of variables and add them to the symbol table
    tokenSwitch = 1  # Switch between checking for id and symbol with each loop

    while token[1] != ";":
        token = lexer.getNextToken()
        if token[1] != ";":
            if tokenSwitch:
                if token[0] != "id":
                    Error(token, "Identifier expected")
                else:
                    if objectType == "":  # If refrenced from static context
                        symbolTable.addSymbol(type=context,
                                              attribute=attribute,
                                              symbol=token[1],
                                              scope=symbolTable.objectName)
                    else:
                        symbolTable.addSymbol(type="local",
                                              attribute=attribute,
                                              symbol=token[1],
                                              scope=symbolTable.objectName)

                tokenSwitch = 0
            else:
                if token[0] != "symbol" and token[1] != ",":
                    Error(token, "Symbol expected")
                else:
                    tokenSwitch = 1

    return [1]
Ejemplo n.º 7
0
def method(token):

    # Check method is of correct type
    global objectType
    objectType = "method"

    token = lexer.getNextToken()
    if not token[1] in [
            "int", "boolean", "char", "void", symbolTable.className
    ] and token[0] != "keyword":  # Class name can be used in constructors
        return [0, "Invalid method declaration of type " + str(token[1])]

    attribute = token[1]
    setObjectName()

    symbolTable.symbolIndexList = [
        [], []
    ]  # Reset symbolIndexList on creation of new object

    #Function header is the first argument to be added to the symbol table
    symbolTable.addSymbol(type="argument",
                          attribute=attribute,
                          symbol=symbolTable.className + "." +
                          symbolTable.objectName,
                          scope=symbolTable.objectName)

    # Push argument
    text("push argument 0")
    text("pop pointer 0")

    return setObjectArgs(attribute)
def parse(text):
    setInput(text)
    global token
    token = getNextToken()
    return E()
    if token.token_id != Token_ENUM.TK_EOF:
        raise ValueError("Input not parsed entirely.")
Ejemplo n.º 9
0
def setObjectName():
    # Check function has appropriate type and name
    token = lexer.getNextToken()
    if token[0] != "id":
        Error(token, "Expected 'id'")

    # Reset counter and set new name on entry to new object
    symbolTable.objectName = token[1]
    symbolTable.labelCounter = [0, 0, 0]

    # Get number of declared variables in function
    while (token[1] != "{"):  # loop to start of function
        token = lexer.peekNextToken()
        if token[0] == "EOF":
            Error(token, "Unexpected EOF")

    # Loop to end of the function
    # Incriment variable counter each time one is encountered
    bCount = 1
    varCount = 0
    while bCount:
        token = lexer.peekNextToken()

        if token[1] == "var":
            token = lexer.peekNextToken()  # Consume data type

            # Check syntax of variables and add them to the symbol table
            tokenSwitch = 1  # Switch between checking for id and symbol with each loop
            while token[1] != ";":
                token = lexer.peekNextToken()

                if token[1] != ";":
                    if tokenSwitch:
                        if token[0] != "id":
                            Error(token, "Expected token of type 'identifier'")
                        else:
                            varCount += 1
                        tokenSwitch = 0
                    else:
                        if token[0] != "symbol" and token[1] != ",":
                            Error(token, "Expected ','")
                        else:
                            tokenSwitch = 1

                if token[0] == "EOF":
                    Error(token, "Unexpected EOF")

        if token[1] == "{":
            bCount += 1
        elif token[1] == "}":
            bCount -= 1

        if token[0] == "EOF":
            Error(token, "Unexpected EOF")

    text("function " + symbolTable.className + "." + symbolTable.objectName +
         " " + str(varCount))
def F_prime(var):
    global token
    if token.token_id == Token_ENUM.OP_KLEENE:
        token = getNextToken()
        kleene = Kleene(var)
        return F_prime(kleene)
    else:
        #epsilon
        return var
Ejemplo n.º 11
0
def var(token):
    token = lexer.getNextToken()

    if not token[1] in ["int", "boolean", "char", "void", "Array"
                        ] and token[0] != "id":
        return [0, "declared variable is of invalid type"]

    attribute = token[1]
    return createVar(token, attribute, 0)
def E_prime(var):
    global token
    if token.token_id == Token_ENUM.OP_OR:
        token = getNextToken()
        t = T()
        or_st = Or(var, t)
        return E_prime(or_st)
    else:
        #epsilon
        return var
def T_prime(var):
    global token
    if token.token_id == Token_ENUM.OP_CONCAT:
        token = getNextToken()
        f = F()
        concat_st = Concat(var, f)
        return T_prime(concat_st)
    else:
        #epsilon
        return var
Ejemplo n.º 14
0
def Class(token):
    token = lexer.getNextToken()

    if token[0] != "id":
        Error(token, "Expected 'id'")
    else:
        symbolTable.className = token[1]

    if lexer.peekNextToken()[1] != "{":
        Error(token, "Expected '{'")

    return [1]
Ejemplo n.º 15
0
def let(token):

    token = lexer.getNextToken()
    if token[0] != "id":
        return [0, "Expected 'id'"]

    peekToken = lexer.peekNextToken()
    if peekToken[1] == "[" and peekToken[0] == "symbol":  # Check if array

        expr = [token]  # Stores list of tokens in expression
        lexer.getNextToken()  # consume token
        expr[-1][0] = "array"
        expr[-1][1] = [copy.copy(expr[-1]),
                       []]  # store function with arguments
        bCount = 1
        while bCount:  # Exit on obtaining all parameters
            token = lexer.getNextToken()

            if token[1] == "[" and token[0] == "symbol":
                bCount += 1
            elif token[1] == "]" and token[0] == "symbol":
                bCount -= 1

            if bCount:
                expr[-1][1][1].append(token)

        token = lexer.peekNextToken()  # Revert peek

        symbolTable.arrayLetSwitch = 1
        symbolTable.expressionToCode(expr)
        symbolTable.arrayLetSwitch = 0

        getToken = lexer.getNextToken()
        if getToken[1] != "=" and getToken[0] != "operator":
            return [0, "Expected '='"]

        returnData = symbolTable.orderExpr("let")
        if not returnData[0]:
            return returnData

        text("pop temp 0")
        text("pop pointer 1")
        text("push temp 0")
        text("pop that 0")

    else:
        popData = symbolTable.pushPop(token)

        getToken = lexer.getNextToken()
        if getToken[1] != "=" and getToken[0] != "operator":
            return [0, "Expected '='"]

        returnData = symbolTable.orderExpr("let")
        if not returnData[0]:
            return returnData
        text("pop " + popData[0] + " " + str(popData[1]))

    return [1]
Ejemplo n.º 16
0
def constructor(token):  # Check function is of correct type
    global objectType
    objectType = "constructor"

    token = lexer.getNextToken()
    if not token[1] == symbolTable.className:
        return [0, "Invalid method declaration of type " + str(token[1])]

    attribute = token[1]

    setObjectName()
    text("push constant " + str(symbolTable.staticVarCount))

    # Alloc memory
    text("call Memory.alloc 1")
    text("pop pointer 0")

    return setObjectArgs(attribute)
Ejemplo n.º 17
0
def function(token):
    global objectType
    objectType = "function"

    symbolTable.symbolIndexList = [
        [], []
    ]  # Reset symbolIndexList on creation of new object

    # Check function is of correct type
    token = lexer.getNextToken()
    if not token[1] in [
            "int", "boolean", "char", "void", symbolTable.className
    ] and token[0] != "keyword":  # Class name can be used in constructors
        return [0, "Invalid method declaration of type " + str(token[1])]

    attribute = token[1]

    setObjectName()
    return setObjectArgs(attribute)
Ejemplo n.º 18
0
def boolean(token):
    token = lexer.getNextToken()
    attribute = token[1]
    return createVar(token, attribute, "boolean")
Ejemplo n.º 19
0
 def getNextToken(self, code):
     return lexer.getNextToken(code)
Ejemplo n.º 20
0
def int(token):
    token = lexer.getNextToken()
    attribute = token[1]
    return createVar(token, attribute, "int")
Ejemplo n.º 21
0
def void(token):
    token = lexer.getNextToken()
    attribute = token[1]
    return createVar(token, attribute, "void")
Ejemplo n.º 22
0
def static(token):
    token = lexer.getNextToken()
    attribute = token[1]
    return createVar(token, attribute, "static")
Ejemplo n.º 23
0
def field(token):
    token = lexer.getNextToken()
    attribute = token[1]
    return createVar(token, attribute, "field")
Ejemplo n.º 24
0
def char(token):
    token = lexer.getNextToken()
    attribute = token[1]
    return createVar(token, attribute, "char")
Ejemplo n.º 25
0
def orderExpr(exprType):
    ''' Obtains a list of tokens which comprise an expression '''

    # Perform checks on the expression and wrap it up into a list
    bracketOpenCount = 0
    expr = []  # Stores list of tokens in expression
    token = lexer.peekNextToken()
    errorToken = token  # Hold current token for later error calls

    if exprType in ["if", "while"]:
        ending = "{"
    elif exprType in ["let", "do"]:
        ending = ";"
    elif exprType in ["return"]:
        ending = ";"
        token = [token[0], "return", token[2]]

    while token[1] != ending:

        token = lexer.getNextToken()  # Consume token
        if token[0] == "EOF":
            Error(errorToken, "Unexpected EOF")

        expr.append(token)

        # Insure matching number of parenthesis
        if token[0] == "symbol" and token[1] == "(":
            bracketOpenCount += 1
        elif token[0] == "symbol" and token[1] == ")":
            bracketOpenCount -= 1

        if bracketOpenCount == -1:
            Error(errorToken, "Mismatched number of parenthesis")

        lastToken = token
        token = lexer.peekNextToken()
        # Check if next token implies the current token is a function call
        if lastToken[0] == "id" and (token[1] == "(" and token[0] == "symbol"):
            lexer.getNextToken()  # consume token
            expr[-1][0] = "function"
            expr[-1][1] = [copy.copy(expr[-1]),
                           []]  # store function with arguments
            bCount = 1
            while bCount:  # Exit on obtaining all parameters
                token = lexer.getNextToken()
                if token[1] == "(":
                    bCount += 1
                elif token[1] == ")":
                    bCount -= 1

                if bCount:
                    expr[-1][1][1].append(token)

            token = lexer.peekNextToken()  # Revert peek

        # Check if next token implies the current token is array
        elif lastToken[0] == "id" and (token[1] == "["
                                       and token[0] == "symbol"):
            lexer.getNextToken()  # consume token
            expr[-1][0] = "array"
            expr[-1][1] = [copy.copy(expr[-1]),
                           []]  # store function with arguments
            bCount = 1
            while bCount:  # Exit on obtaining all parameters
                token = lexer.getNextToken()
                if token[1] == "[" and token[0] == "symbol":
                    bCount += 1
                elif token[1] == "]" and token[0] == "symbol":
                    bCount -= 1

                if bCount:
                    expr[-1][1][1].append(token)

            token = lexer.peekNextToken()  # Revert peek

    return runExpr(expr)