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:
        """
        #self, variable, expression, symTbl, token
        if len(tokens) > 0:
            token = tokens.pop(0)
        else:
            return  #raise syntax_error.SyntaxError('Incomplete statement')
        if token == self.COMMENT_TOKEN:
            return None

        elif token in self.PRINT_TOKEN:
            if len(tokens) > 0:
                return print_node.PrintNode(self.__parse(tokens))
            else:
                return print_node.PrintNode(None)
        elif token in self.MATH_TOKENS:
            leftChild = self.__parse(tokens)
            rightChild = self.__parse(tokens)
            if not isinstance(leftChild,
                              (literal_node.LiteralNode, math_node.MathNode,
                               variable_node.VariableNode)):
                raise syntax_error.SyntaxError('Invalid Statement')
            if not isinstance(rightChild,
                              (literal_node.LiteralNode, math_node.MathNode,
                               variable_node.VariableNode)):
                raise syntax_error.SyntaxError('Invalid Statement')
            return math_node.MathNode(leftChild, rightChild, token)
        elif token == self.ASSIGNMENT_TOKEN:
            return assignment_node.AssignmentNode(self.__parse(tokens),
                                                  self.__parse(tokens),
                                                  self.symTbl, token)
        elif token.isdigit():
            return literal_node.LiteralNode(token)
        elif token.isidentifier():
            return variable_node.VariableNode(token, self.symTbl)
        else:
            raise syntax_error.SyntaxError('Invalid token ' + token)
        pass
Beispiel #2
0
 def emit(self):
     """
     Prints an infiex string representation of the source code that
     is contained as root nodes in parseTree.
     :return None
     """
     for node in self.parseTrees:
         str = print_node.PrintNode(node).emit()
         print(str)
Beispiel #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:
         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)
Beispiel #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: 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)
Beispiel #5
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:])
        """
Beispiel #6
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
        """

        count = 1
        fh = open(self.srcFile)
        for i in fh:
            try:
                self.lineNum = count
                tokens = i.split()
                if i[0] == '#' or tokens == []:
                    count += 1
                    continue
                elif any(self.MATH_TOKENS) in tokens:
                    if len(tokens) < 3:
                        raise syntax_error.SyntaxError("Incomplete Statement")
                if '=' in tokens[1:]:
                    count += 1
                    raise syntax_error.SyntaxError("Invalid Token")

                if i[0] == '=' or i[0] == '@':
                    count += 1
                    if len(tokens) == 1:
                        if tokens[0] == '@':
                            node = print_node.PrintNode(
                                literal_node.LiteralNode(' '))
                            self.parseTrees.append(node)
                        else:
                            if '@' in tokens[1:]:
                                raise syntax_error.SyntaxError(
                                    "Bad assignment expression")
                            raise syntax_error.SyntaxError(
                                "Incomplete Statement")
                    self.__parse(tokens[::-1])
                else:
                    count += 1
                    if not (i[0] in self.MATH_TOKENS):
                        raise syntax_error.SyntaxError("Invalid Token")
            except syntax_error.SyntaxError as syn:
                self.syntaxError = True
                print("Line ", self.lineNum, " ", syn)
Beispiel #7
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()