def parse(self, tokens, debug=None):
        """This is the main entry point from outside.

        Passing in a debug dictionary changes the default debug
        setting.
        """

        self.tokens = tokens

        if debug:
            self.debug = debug

        sets = [ [(1, 0), (2, 0)] ]
        self.links = {}

        if self.ruleschanged:
            self.computeNull()
            self.newrules = {}
            self.new2old = {}
            self.makeNewRules()
            self.ruleschanged = False
            self.edges, self.cores = {}, {}
            self.states = { 0: self.makeState0() }
            self.makeState(0, self._BOF)

        for i in range(len(tokens)):
            sets.append([])

            if sets[i] == []:
                break
            self.makeSet(tokens, sets, i)
        else:
            sets.append([])
            self.makeSet(None, sets, len(tokens))

        finalitem = (self.finalState(tokens), 0)
        if finalitem not in sets[-2]:
            if len(tokens) > 0:
                if self.debug.get('errorstack', False):
                    self.errorstack(tokens, i-1, str(self.debug['errorstack']) == 'full')
                self.error(tokens, i-1)
            else:
                self.error(None, None)

        if self.profile_info is not None:
            self.dump_profile_info()

        return self.buildTree(self._START, finalitem,
                    tokens, len(sets)-2)
This is the main entry point from outside.

        Passing in a debug dictionary changes the default debug
        setting.