Esempio n. 1
0
    def __parse(self, tokens):
        """
        The recursive parser that builds the parse tree from one line of
        source code.
        :param tokens: The tokens from the source line separated by whitespace
            in a list of strings.
        :exception: raises a syntax_error.SyntaxError with the message
            'Incomplete statement' if the statement is incomplete (e.g.
            there are no tokens left and this method was called).
        :exception: raises a syntax_error.SyntaxError with the message
            'Invalid token {token}' if an unrecognized token is
            encountered (e.g. not one of the tokens listed above).
        :return:
        """
        if len(tokens) < 1:
            return
        firstToken = tokens[0]

        if firstToken is self.COMMENT_TOKEN:
            return

        if firstToken.isdigit():
            node = literal_node.LiteralNode(firstToken)
            self.parseTrees.append(node)

        elif firstToken.isidentifier():
            self.symTbl[firstToken] = ''
            node = variable_node.VariableNode(firstToken, self.symTbl)
            self.parseTrees.append(node)

        elif firstToken == self.ASSIGNMENT_TOKEN:
            first = self.parseTrees.pop()
            second = self.parseTrees.pop()
            valid = self.checkIfPoppedNodesAreValidForAssignmentNode(
                first, second)
            if valid == True:
                node = assignment_node.AssignmentNode(first, second,
                                                      self.symTbl, firstToken)
                self.parseTrees.append(node)
                node.evaluate()
            else:
                self.syntaxError = True
                raise syntax_error.SyntaxError('Incomplete Statement' +
                                               ' line Number ' +
                                               str(self.lineNum))

        elif firstToken in self.MATH_TOKENS:
            first = self.parseTrees.pop()
            second = self.parseTrees.pop()
            valid = self.checkIfPoppedNodesAreValidForMathNode(first, second)
            if valid == True:
                node = math_node.MathNode(first, second, firstToken)
                self.parseTrees.append(node)
            else:
                self.syntaxError = True
                raise syntax_error.SyntaxError('Incomplete Statement' +
                                               ' line Number ' +
                                               str(self.lineNum))

        self.__parse(tokens[1:])
Esempio n. 2
0
    def __parse(self, tokens):
        """
        The recursive parser that builds the parse tree from one line of
        source code.
        :param tokens: The tokens from the source line separated by whitespace
            in a list of strings.
        :exception: raises a syntax_error.SyntaxError with the message
            'Incomplete statement' if the statement is incomplete (e.g.
            there are no tokens left and this method was called).
        :exception: raises a syntax_error.SyntaxError with the message
            'Invalid token {token}' if an unrecognized token is
            encountered (e.g. not one of the tokens listed above).
        :return:
        """
        if len(tokens) > 0:
            token = tokens.pop(0)
        else:
            return

        if token is self.COMMENT_TOKEN:
            return None

        elif token is self.PRINT_TOKEN:
            return print_node.PrintNode(self.__parse(tokens))

        elif token.isdigit():
            return literal_node.LiteralNode(token)

        elif token == '=':
            return assignment_node.AssignmentNode(self.__parse(tokens),
                                                  self.__parse(tokens),
                                                  self.symTbl, token)

        elif token in self.MATH_TOKENS:
            left = self.__parse(tokens)
            right = self.__parse(tokens)
            if not isinstance(left,
                              (literal_node.LiteralNode, math_node.MathNode,
                               variable_node.VariableNode)):
                raise syntax_error.SyntaxError('Incomplete expression')
            if not isinstance(right,
                              (literal_node.LiteralNode, math_node.MathNode,
                               variable_node.VariableNode)):
                raise syntax_error.SyntaxError('Incomplete expression')

            return math_node.MathNode(left, right, token)

        elif token.isidentifier():
            return variable_node.VariableNode(token, self.symTbl)
        else:
            raise syntax_error.SyntaxError("Invalid token {" + str(token) +
                                           "}")
Esempio n. 3
0
    def __parse(self, tokens):
        """
        The recursive parser that builds the parse tree from one line of
        source code.
        :param tokens: The tokens from the source line separated by whitespace
            in a list of strings.
        :exception: raises a syntax_error.SyntaxError with the message
            'Incomplete statement' if the statement is incomplete (e.g.
            there are no tokens left and this method was called).
        :exception: raises a syntax_error.SyntaxError with the message
            'Invalid token {token}' if an unrecognized token is
            encountered (e.g. not one of the tokens listed above).
        :return:
        """

        if len(tokens) == 0:
            return
        elif tokens[0].isidentifier():
            node = variable_node.VariableNode(tokens[0], self.symTbl)
            self.parseTrees.append(node)
        elif tokens[0].isdigit():
            node = literal_node.LiteralNode(int(tokens[0]))
            self.parseTrees.append(node)
        elif tokens[0] == '=':
            node = assignment_node.AssignmentNode(self.parseTrees.pop(),
                                                  self.parseTrees.pop(),
                                                  self.symTbl, tokens[0])
            self.parseTrees.append(node)
        elif tokens[0] == '@':
            node = print_node.PrintNode(self.parseTrees.pop())
            self.parseTrees.append(node)
        elif tokens[0] in self.MATH_TOKENS:
            x = self.parseTrees.pop()
            y = self.parseTrees.pop()
            if not isinstance(x,
                              (variable_node.VariableNode,
                               literal_node.LiteralNode, math_node.MathNode)):
                raise syntax_error.SyntaxError('Incomplete Statement')
            if not isinstance(y,
                              (variable_node.VariableNode,
                               literal_node.LiteralNode, math_node.MathNode)):
                raise syntax_error.SyntaxError('Incomplete Statement')
            node = math_node.MathNode(x, y, tokens[0])
            self.parseTrees.append(node)
        else:
            raise syntax_error.SyntaxError("Invalid token")
        self.__parse(tokens[1:])
        """
Esempio n. 4
0
 def __parse(self, tokens):
     """
     The recursive parser that builds the parse tree from one line of
     source code.
     :param tokens: The tokens from the source line separated by whitespace
         in a list of strings.
     :exception: raises a syntax_error.SyntaxError with the message
         'Incomplete statement' if the statement is incomplete (e.g.
         there are no tokens left and this method was called).
     :exception: raises a syntax_error.SyntaxError with the message
         'Invalid token {token}' if an unrecognized token is
         encountered (e.g. not one of the tokens listed above).
     :return:
     """
     if len(tokens) <= 0:
         raise (syntax_error.SyntaxError("Invalid Expression"))
     current = tokens[0]
     if len(tokens) > 0:
         if type(tokens) is str:
             tokens = None
         else:
             tokens.pop(0)
     if current == self.ASSIGNMENT_TOKEN:
         if len(tokens) > 0:
             return assignment_node.AssignmentNode(self.__parse(tokens.pop(0)),self.__parse(tokens),self.symTbl,'=')
         else:
             raise syntax_error.SyntaxError('Incomplete statement')
     elif current in self.MATH_TOKENS:
         return math_node.MathNode(self.__parse(tokens),self.__parse(tokens), current)
     elif current == self.PRINT_TOKEN:
         if len(tokens)>0:
             return print_node.PrintNode(self.__parse(tokens))
         else:
             return print_node.PrintNode()
     elif current.isdigit():
         return literal_node.LiteralNode(current)
     elif current.isalpha():
         return variable_node.VariableNode(current,self.symTbl)
     elif current == self.COMMENT_TOKEN:
         pass
     elif current is None:
         raise syntax_error.SyntaxError('Incomplete statement')
     else:
         raise syntax_error.SyntaxError('Invalid token ' + current)
    def __parse(self, tokens):
        """
        The recursive parser that builds the parse tree from one line of
        source code.
        :param tokens: The tokens from the source line separated by whitespace
            in a list of strings.
        :exception: raises a syntax_error.SyntaxError with the message
            'Incomplete statement' if the statement is incomplete (e.g.
            there are no tokens left and this method was called).
        :exception: raises a syntax_error.SyntaxError with the message
            'Invalid token {token}' if an unrecognized token is
            encountered (e.g. not one of the tokens listed above).
        :return:
        """
        # pass
        print('tokens are',tokens)
        token_list = ['+', '-', '*', '//', '#', '=', '@']
        if not tokens:
            raise syntax_error.SyntaxError('Incomplete statement')
        for i in tokens:
            if not i.isdigit() and not i.isidentifier():
                if i not in token_list:
                    raise syntax_error.SyntaxError('Invalid token {i}')
        i =0
        while(i < len(tokens)):
            if tokens[i] == PreTee.COMMENT_TOKEN:
                i+=1

            elif tokens[i].isidentifier():
                variable_node.VariableNode(tokens[i], self.symTbl[tokens[i]])
                i+=1
            elif tokens[i].isdigit():
                literal_node.LiteralNode(tokens[i])
                i+=1
            elif tokens[i] in PreTee.MATH_TOKENS:
                left_val = self.__parse(tokens[i+1])
                right_val = self.__parse(tokens[i+2])
                math_node.MathNode(left_val, right_val, tokens[i])
                i+=2
Esempio n. 6
0
    def __parse(self, tokens):
        """
        The recursive parser that builds the parse tree from one line of
        source code.
        :param tokens: The tokens from the source line separated by whitespace
            in a list of strings.
        :exception: raises a syntax_error.SyntaxError with the message
            'Incomplete statement' if the statement is incomplete (e.g.
            there are no tokens left and this method was called).
        :exception: raises a syntax_error.SyntaxError with the message
            'Invalid token {token}' if an unrecognized token is
            encountered (e.g. not one of the tokens listed above).
        :return: the object of one of node classes based on the type token.
                    Node classes: literal_node.LiteralNode, variable_node.VariableNode,
                                  assignment_node.AssignmentNode, print_node.PrintNode,
                                  math_node.MathNode
        """

        if len(tokens) is 0:
            raise syntax_error.SyntaxError('Incomplete statement')

        token = tokens.pop()

        if token.isdigit():
            return literal_node.LiteralNode(token)
        elif token.isidentifier():
            return variable_node.VariableNode(token, self.symTbl)
        elif token is self.ASSIGNMENT_TOKEN:
            return assignment_node.AssignmentNode(self.__parse(tokens),
                                                  self.__parse(tokens), self.symTbl, token)
        elif token is self.PRINT_TOKEN:
            if len(tokens) > 0:
                return print_node.PrintNode(self.__parse(tokens))
            else:
                return print_node.PrintNode()
        elif token in self.MATH_TOKENS:
            return math_node.MathNode(self.__parse(tokens), self.__parse(tokens), token)
        else:
            raise syntax_error.SyntaxError('Invalid token ' + token)
Esempio n. 7
0
    def __parse(self, tokens):
        """
        The recursive parser that builds the parse tree from one line of
        source code.
        :param tokens: The tokens from the source line separated by whitespace
            in a list of strings.
        :exception: raises a syntax_error.SyntaxError with the message
            'Incomplete statement' if the statement is incomplete (e.g.
            there are no tokens left and this method was called).
        :exception: raises a syntax_error.SyntaxError with the message
            'Invalid token {token}' if an unrecognized token is
            encountered (e.g. not one of the tokens listed above).
        :return:
        """
        # no token left
        if len(tokens) < 1:
            # error message: Incomplete statement
            self.syntaxError = True
            return syntax_error.SyntaxError("Incomplete statement")

        elif len(tokens) == 1:
            if tokens[0].isdigit():
                return literal_node.LiteralNode(int(tokens[0]))

            elif tokens[0].isidentifier():
                return variable_node.VariableNode(tokens[0], self.symTbl)

            else:
                # error message: Invalid token
                self.syntaxError = True
                return syntax_error.SyntaxError("Invalid token %s" % tokens[0])

        elif tokens[0] in self.MATH_TOKENS:
            # leaf nodes required to construct the left expression parse tree
            leavesNeed = 1

            for i in range(1, len(tokens)):
                if tokens[i].isdigit() or tokens[i].isidentifier():
                    # a leaf node
                    leavesNeed -= 1

                elif tokens[i] in self.MATH_TOKENS:
                    # a interior node, need one more leaf node to construct the
                    # full binary tree
                    leavesNeed += 1

                else:
                    # error message: Invalid token
                    self.syntaxError = True
                    return syntax_error.SyntaxError("Invalid token %s" %
                                                    tokens[i])

                # has all nodes required to construct the left expression
                if leavesNeed == 0:
                    # construct the left and right expression
                    left = self.__parse(tokens[1:i + 1])
                    right = self.__parse(tokens[i + 1:])

                    # error raised in construction of left expression
                    if isinstance(left, syntax_error.SyntaxError):
                        return left

                    # error raised in construction of right expression
                    if isinstance(right, syntax_error.SyntaxError):
                        return right

                    return math_node.MathNode(left, right, tokens[0])

        else:
            # error message: Invalid token
            self.syntaxError = True
            return syntax_error.SyntaxError("Invalid token %s" % tokens[0])
Esempio n. 8
0
    def parse(self):
        """
        The public parse is responsible for looping over the lines of
        source code and constructing the parseTree, as a series of
        calls to the helper function that are appended to this list.
        It needs to handle and display any syntax_error.SyntaxError
        exceptions that get raised.
        : return None
        """
        file = open(self.srcFile)

        for line in file:
            self.lineNum += 1
            tokens = line.split()

            # empty line
            if len(tokens) == 0:
                continue

            # assignment statement
            if tokens[0] == self.ASSIGNMENT_TOKEN:
                # lack of tokens
                if len(tokens) < 3:
                    self.syntaxError = True

                    # error message: Incomplete statement
                    print("\nFile \"%s\", line %d" %
                          (self.srcFile, self.lineNum),
                          file=sys.stderr)
                    print("  %sSyntaxError: Incomplete statement" % line,
                          file=sys.stderr)

                    continue

                # left token is not valid variable name
                if not tokens[1].isidentifier():
                    self.syntaxError = True

                    # error message: Bad assignment to non-variable
                    print("\nFile \"%s\", line %d" %
                          (self.srcFile, self.lineNum),
                          file=sys.stderr)
                    print("  %sSyntaxError: Bad assignment to non-variable" %
                          line,
                          file=sys.stderr)

                    continue

                # construct parse tree for expression on the right
                expression = self.__parse(tokens[2:])

                # error raised during the construction of parse tree
                if isinstance(expression, syntax_error.SyntaxError):
                    # print out the error message
                    print("\nFile \"%s\", line %d" %
                          (self.srcFile, self.lineNum),
                          file=sys.stderr)
                    print("  %sSyntaxError: %s" % (line, expression),
                          file=sys.stderr)

                else:
                    # create a new AssignmentNode
                    self.parseTrees.append(
                        assignment_node.AssignmentNode(
                            variable_node.VariableNode(tokens[1], self.symTbl),
                            expression, self.symTbl, tokens[0]))

            # print statement
            elif tokens[0] == self.PRINT_TOKEN:
                # empty expression
                if len(tokens) == 1:
                    self.parseTrees.append(print_node.PrintNode(None))

                else:
                    # construct parse tree for the expression
                    expression = self.__parse(tokens[1:])
                    # create a new PrintNode
                    self.parseTrees.append(print_node.PrintNode(expression))

            # comment line
            elif tokens[0] == self.COMMENT_TOKEN:
                continue

            else:
                self.syntaxError = True

                # error message: Invalid token
                print("\nFile \"%s\", line %d" % (self.srcFile, self.lineNum),
                      file=sys.stderr)
                print("  %sSyntaxError: Invalid token %s" % (line, tokens[0]),
                      file=sys.stderr)

        file.close()