def _followups(self, nonterm): """Return the set of token types that could follow the given nonterminal.""" res = {} for nonterm2, symb in self._parse_table.keys(): if nonterm == nonterm2: set_add(res, symb) return seq_sorted([Token.type_description(key) for key in res.keys()])
def parse_error(self, top, _previous_token, token): "Raises a ParserException describing a parse error." if is_nonterminal(top): follow = self._followups(top) else: follow = [Token.type_description(top)] if len(follow) == 1: msg = i18n.i18n('Found: %s\nExpected: %s') % (token, follow[0]) else: msg = '' msg += i18n.i18n('\n'.join([ 'Found: %s', 'Expected one of the following tokens:'])) % ( token,) msg += '\n' + utils.indent('\n'.join(follow)) raise ParserException(msg, position.ProgramAreaNear(token))