PKϊ}›5“Χ2EGG-INFO/dependency_links.txt PKϊ}›5ΓXnK½½EGG-INFO/PKG-INFOMetadata-Version: 1.0 Name: ZestyParser Version: 0.4.0 Summary: A simple but highly flexible approach to parsing Home-page: http://adamatlas.org/2006/12/ZestyParser Author: Adam Atlas Author-email: adam@atlas.st License: GPL Description: ZestyParser is a small parsing toolkit for Python. It doesn't use the traditional separated lexer/parser approach, nor does it make you learn a new ugly syntax for specifying grammar. It is based entirely on Python regular expressions and callbacks; its flow is very simple, but can accomodate a vast array of parsing situations. Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: GNU General Public License (GPL) Classifier: Natural Language :: English Classifier: Programming Language :: Python Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: Text Processing PKϊ}›5ζzνnnEGG-INFO/SOURCES.txtCHANGES.txt Docs.html Docs.text LICENSE.txt MANIFEST.in setup.py ZestyParser/Parser.py ZestyParser/__init__.py ZestyParser.egg-info/PKG-INFO ZestyParser.egg-info/SOURCES.txt ZestyParser.egg-info/dependency_links.txt ZestyParser.egg-info/top_level.txt examples/bdecode.py examples/calcy.py examples/quotey.py examples/sexp-bench.py examples/sexp.py examples/testy.py PKϊ}›5΅& EGG-INFO/top_level.txtZestyParser PKϊ}›5“Χ2EGG-INFO/zip-safe PK\›5šTτh,,ZestyParser/__init__.py# ZestyParser 0.4.0 -- Parses in Python zestily # Copyright (C) 2006 Adam Atlas # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from Parser import *PKϊ}›5I‘ύ¦¦ZestyParser/__init__.pyc;ς A’Ec@s dkTdS((s*N(sParser(((s9build/bdist.darwin-8.8.2-i386/egg/ZestyParser/__init__.pys?sPK£|›5ˆR΄λλZestyParser/Parser.py# ZestyParser 0.4.0 -- Parses in Python zestily # Copyright (C) 2006 Adam Atlas # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import re, copy __all__ = ('ZestyParser', 'NotMatched', 'ParseError', 'EOF', 'ReturnRaw', 'AbstractToken', 'Token', 'RawToken', 'CompositeToken', 'TokenSequence', 'CallbackFor') class Error(Exception): pass class NotMatched(Error): pass class ParseError(Error): def __init__(self, parser, message): self.parser, self.message, self.coord = parser, message, parser.coord() def __str__(self): return "%s at line %i column %i" % (self.message, self.coord[0], self.coord[1]) def EOF(parser, origCursor): if parser.cursor != parser.len: raise NotMatched def ReturnRaw(matches): return matches.group() class CallbackFor: def __init__(self, token): self.token = token def __call__(self, func): self.token.callback = func return self.token class AbstractToken: def __repr__(self): return '%s %s' % (self.__class__.__name__, (self.name or str(self))) def preprocessResult(self, parser, data, origCursor): if not self.callback: return data try: c = self.callback.func_code.co_argcount if c == 2: return self.callback(parser, data) elif c == 1: return self.callback(data) else: return self.callback(parser, data, origCursor) except NotMatched: parser.cursor = origCursor raise NotMatched def __add__(self, other): return TokenSequence([self, other]) def __or__(self, other): return CompositeToken([self, other]) def __rshift__(self, callback): new = copy.copy(self) new.callback = callback return new class Token (AbstractToken): def __init__(self, regex, callback=None, name=None): self.name, self.regex, self.callback = name, regex, callback if not hasattr(regex, 'match'): self.regex = re.compile(self.regex, re.DOTALL) def __call__(self, parser, origCursor): matches = self.regex.match(parser.data, origCursor) if not matches: raise NotMatched #parser.cursor += len(matches.group()) parser.cursor = matches.end() return self.preprocessResult(parser, matches, origCursor) def __str__(self): return self.regex.pattern class RawToken (AbstractToken): def __init__(self, string, callback=None, name=None): self.string, self.callback, self.name = string, callback, name self.len = len(self.string) def __call__(self, parser, origCursor): if parser.data[origCursor:origCursor+self.len] == self.string: parser.cursor += self.len return self.preprocessResult(parser, self.string, origCursor) else: raise NotMatched def __str__(self): return repr(self.string) class CompositeToken (AbstractToken): def __init__(self, tokens, callback=None, name=None): self.name = name self.tokens = tokens self.callback = callback def __call__(self, parser, origCursor): r = parser.scan(self.tokens) if not r or parser.last is EOF: raise NotMatched return self.preprocessResult(parser, r, origCursor) def __str__(self): return '(' + ' | '.join([str(t) for t in self.tokens]) + ')' def __or__(self, other): if isinstance(other, CompositeToken): return CompositeToken(self.tokens + other.tokens) else: return CompositeToken(self.tokens + [other]) class TokenSequence (AbstractToken): def __init__(self, tokenGroups, callback=None, name=None): self.name = name self.tokenGroups = tokenGroups self.callback = callback def __call__(self, parser, origCursor): o = [] for g in self.tokenGroups: r = parser.scan(g) if not r: parser.cursor = origCursor raise NotMatched o.append(r) return self.preprocessResult(parser, o, origCursor) def __str__(self): return '(' + ' + '.join([str(t) for t in self.tokenGroups]) + ')' def __add__(self, other): if isinstance(other, TokenSequence): return TokenSequence(self.tokenGroups + other.tokenGroups) else: return TokenSequence(self.tokenGroups + [other]) class ZestyParser: tokens = {} data = None cursor = 0 def __init__(self, data=None): if data: self.useData(data) self.last = None def useData(self, data): self.data = data self.cursor = 0 self.len = len(data) def addTokens(self, *tokens, **moreTokens): for t in tokens: self.tokens[t.name] = t for n in moreTokens: self.tokens[n] = moreTokens[n] def scan(self, tokens): if not hasattr(tokens, '__iter__'): tokens = (tokens,) for t in tokens: if t.__class__ is str: t = self.tokens[t] oldCursor = self.cursor try: r = t(self, oldCursor) except NotMatched: self.cursor = oldCursor continue self.last = t return r self.last = None return None def skip(self, t): if t.__class__ is str: t = self.tokens[t] oldCursor = self.cursor try: t(self, oldCursor) except NotMatched: self.cursor = oldCursor return False return True def scanMultiple(self, *tokenGroups): return self.scan([TokenSequence(tokenGroups)]) def take(self, num): r = self.data[self.cursor:self.cursor+num] self.cursor += num return r def iter(self, tokens): return ParserIterator(tokens, self) def coord(self, loc=self.cursor): row = self.data.count('\n', 0, loc) col = loc - self.data.rfind('\n', 0, loc) return (row + 1, col) class ParserIterator: def __init__(self, tokens, parser): self.tokens = tokens self.parser = parser def __iter__(self): return self def next(self): r = self.parser.scan(self.tokens) if not r: raise StopIteration return r PKϊ}›5…L677ZestyParser/Parser.pyc;ς sΩ’Ec @s5dkZdkZddddddddd d d f Zd efd „ƒYZdefd„ƒYZdefd„ƒYZd„Zd„Zd fd„ƒYZ dfd„ƒYZ de fd„ƒYZ de fd„ƒYZ d e fd„ƒYZ d e fd„ƒYZdfd„ƒYZdfd„ƒYZdS(Ns ZestyParsers NotMatcheds ParseErrorsEOFs ReturnRaws AbstractTokensTokensRawTokensCompositeTokens TokenSequences CallbackForsErrorcBstZRS(N(s__name__s __module__(((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pysErrorscBstZRS(N(s__name__s __module__(((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys NotMatchedscBstZd„Zd„ZRS(NcCs+|||iƒf\|_|_|_dS(N(sparsersmessagescoordsself(sselfsparsersmessage((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__init__scCs&d|i|id|idfSdS(Ns%s at line %i column %iii(sselfsmessagescoord(sself((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__str__s(s__name__s __module__s__init__s__str__(((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys ParseErrors cCs!|i|ijo t‚ndS(N(sparserscursorslens NotMatched(sparsers origCursor((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pysEOFscCs|iƒSdS(N(smatchessgroup(smatches((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys ReturnRaw!scBstZd„Zd„ZRS(NcCs ||_dS(N(stokensself(sselfstoken((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__init__$scCs||i_|iSdS(N(sfuncsselfstokenscallback(sselfsfunc((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__call__'s (s__name__s __module__s__init__s__call__(((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys CallbackFor#s cBs5tZd„Zd„Zd„Zd„Zd„ZRS(NcCs(d|ii|ip t|ƒfSdS(Ns%s %s(sselfs __class__s__name__snamesstr(sself((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__repr__,scCs‘|i o|Snye|iii}|djo|i||ƒSn2|djo|i|ƒSn|i|||ƒSWn"tj o||_ t‚nXdS(Nii( sselfscallbacksdatas func_codes co_argcountscsparsers origCursors NotMatchedscursor(sselfsparsersdatas origCursorsc((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pyspreprocessResult/s    cCst||gƒSdS(N(s TokenSequencesselfsother(sselfsother((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__add__;scCst||gƒSdS(N(sCompositeTokensselfsother(sselfsother((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__or__>scCs ti|ƒ}||_|SdS(N(scopysselfsnewscallback(sselfscallbacksnew((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys __rshift__As (s__name__s __module__s__repr__spreprocessResults__add__s__or__s __rshift__(((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys AbstractToken+s    cBs)tZeed„Zd„Zd„ZRS(NcCsU|||f\|_|_|_t|dƒ oti|itiƒ|_ndS(Nsmatch(snamesregexscallbacksselfshasattrsrescompilesDOTALL(sselfsregexscallbacksname((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__init__Gs!cCsP|ii|i|ƒ}| o t‚n|iƒ|_ |i |||ƒSdS(N( sselfsregexsmatchsparsersdatas origCursorsmatchess NotMatchedsendscursorspreprocessResult(sselfsparsers origCursorsmatches((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__call__Ls  cCs|iiSdS(N(sselfsregexspattern(sself((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__str__Ts(s__name__s __module__sNones__init__s__call__s__str__(((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pysTokenFs cBs)tZeed„Zd„Zd„ZRS(NcCs7|||f\|_|_|_t|iƒ|_dS(N(sstringscallbacksnamesselfslen(sselfsstringscallbacksname((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__init__Xs!cCsW|i|||i!|ijo,|i|i7_|i||i|ƒSnt‚dS(N( sparsersdatas origCursorsselfslensstringscursorspreprocessResults NotMatched(sselfsparsers origCursor((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__call__\s!cCst|iƒSdS(N(sreprsselfsstring(sself((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__str__cs(s__name__s __module__sNones__init__s__call__s__str__(((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pysRawTokenWs cBs2tZeed„Zd„Zd„Zd„ZRS(NcCs||_||_||_dS(N(snamesselfstokensscallback(sselfstokensscallbacksname((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__init__gs  cCsK|i|iƒ}| p |itjo t‚n|i|||ƒSdS(N( sparsersscansselfstokenssrslastsEOFs NotMatchedspreprocessResults origCursor(sselfsparsers origCursorsr((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__call__ls cCsCddigi}|iD]}|t|ƒƒq~ƒdSdS(Ns(s | s)(sjoinsappends_[1]sselfstokensstsstr(sselfs_[1]st((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__str__rscCs@t|tƒot|i|iƒSnt|i|gƒSdS(N(s isinstancesothersCompositeTokensselfstokens(sselfsother((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__or__us(s__name__s __module__sNones__init__s__call__s__str__s__or__(((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pysCompositeTokenfs  cBs2tZeed„Zd„Zd„Zd„ZRS(NcCs||_||_||_dS(N(snamesselfs tokenGroupsscallback(sselfs tokenGroupsscallbacksname((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__init__|s  cCshg}xH|iD]=}|i|ƒ}| o||_t ‚n|i |ƒqW|i |||ƒSdS(N( sosselfs tokenGroupssgsparsersscansrs origCursorscursors NotMatchedsappendspreprocessResult(sselfsparsers origCursorsgsosr((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__call__s   cCsCddigi}|iD]}|t|ƒƒq~ƒdSdS(Ns(s + s)(sjoinsappends_[1]sselfs tokenGroupsstsstr(sselfs_[1]st((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__str__‹scCs@t|tƒot|i|iƒSnt|i|gƒSdS(N(s isinstancesothers TokenSequencesselfs tokenGroups(sselfsother((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__add__Žs(s__name__s __module__sNones__init__s__call__s__str__s__add__(((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys TokenSequence{s cBsttZhZeZdZed„Zd„Zd„Zd„Z d„Z d„Z d„Z d „Z eid „ZRS( NicCs%|o|i|ƒnt|_dS(N(sdatasselfsuseDatasNoneslast(sselfsdata((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pys__init__™scCs%||_d|_t|ƒ|_dS(Ni(sdatasselfscursorslen(sselfsdata((s7build/bdist.darwin-8.8.2-i386/egg/ZestyParser/Parser.pysuseDatas  cOsGx|D]}||i|i