def checkBalancedParens(str, refs): m = RE_BRACES.search(str) stack = [] try: while m: if m.group(0) == '{': stack.append(m) else: stack.pop() m = RE_BRACES.search(str, m.end()) except IndexError: row, _ = calcRowCol(str, m.start()) try: info = refs[row] except KeyError: info = None raise spyceException.spyceSyntaxError("unbalanced open brace '{'", info) if stack: m = stack[-1] row, _ = calcRowCol(str, m.start()) try: info = refs[row] except KeyError: info = None raise spyceException.spyceSyntaxError("unbalanced close brace '}'", info)
class spyceTagChecker: def __init__(self, server): self._server = server self._taglibs = {} self._stack = [] def loadLib(self, libname, libfrom, libas, rel_file, info=None): if not libas: libas = libname try: self._taglibs[(libname, libfrom)] = \ self._server.loadModule(libname, libfrom, rel_file)(libas) except (SyntaxError, TypeError): raise except: raise spyceException.spyceSyntaxError( 'unable to load module: %s' % libname, info) def startTag(self, (libname, libfrom), name, attrs, pair, info): lib = self._taglibs[(libname, libfrom)] try: tag = lib.getTag(name, attrs, pair, None) except: raise spyceException.spyceSyntaxError( 'unknown tag "%s:%s"' % (libname, name), info) try: error = tag.syntax() except spyceTagSyntaxException, e: raise spyceException.spyceSyntaxError(str(e), info)
def emitPython(out, bracedPythonCode, spyceRefs): out = LineWriter(out) spyceRefs2 = {} braceConv = BraceConverter(out) def eatToken(type, string, begin, end, _, out=out, braceConv=braceConv, spyceRefs=spyceRefs, spyceRefs2=spyceRefs2): try: beginrow, _ = begin line1 = out.lineno braceConv.emitToken(type, string) line2 = out.lineno if spyceRefs.has_key(beginrow): for l in range(line1, line2): spyceRefs2[l] = spyceRefs[beginrow] except: raise spyceException.spyceSyntaxError(sys.exc_info()[0]) try: tokenize.tokenize(StringIO(bracedPythonCode).readline, eatToken) except tokenize.TokenError, e: msg, (row, col) = e raise spyceException.spyceSyntaxError(msg)
def processLambda(self): # collect lambda self.popToken() begin = self._tokenBegin lamb = '' depth = 1 while self._tokenType!=T_EOF: if self._tokenType in [T_END,]: depth = depth - 1 if not depth: break lamb = lamb + self._tokenText elif self._tokenType in [T_EVAL, T_STMT, T_CHUNK, T_CHUNKG, T_DIRECT, T_LAMBDA]: depth = depth + 1 lamb = lamb + self._tokenText elif self._tokenType==T_CMNT: self.processComment() else: lamb = lamb + self._tokenText end = self._tokenEnd self.popToken() # process lambda lamb = string.split(lamb, ':') try: params = lamb[0] memoize = 0 if params and params[0]=='!': params = params[1:] memoize = 1 lamb = string.join(lamb[1:],':') except: raise spyceException.spyceSyntaxError('invalid spyce lambda', (begin, end, lamb, self._curfile)) self._load_spylambda = 1 lamb = 'spylambda.define(%s,%s,%d)' % (`string.strip(params)`, `lamb`, memoize) return lamb
def loadLib(self, libname, libfrom, libas, rel_file, info=None): if not libas: libas = libname try: self._taglibs[(libname, libfrom)] = self._server.loadModule(libname, libfrom, rel_file)(libas) except (SyntaxError, TypeError): raise except: raise spyceException.spyceSyntaxError("unable to load module: %s" % libname, info)
def loadLib(self, libname, libfrom, libas, rel_file, info=None): if not libas: libas = libname try: self._taglibs[(libname, libfrom)] = \ self._server.loadModule(libname, libfrom, rel_file)(libas) except (SyntaxError, TypeError): raise except: raise spyceException.spyceSyntaxError( 'unable to load module: %s' % libname, info)
def checkBalancedParens(str, refs): m = RE_BRACES.search(str) stack = [] try: while m: if m.group(0)=='{': stack.append(m) else: stack.pop() m = RE_BRACES.search(str, m.end()) except IndexError: row, _ = calcRowCol(str, m.start()) try: info = refs[row] except KeyError: info =None raise spyceException.spyceSyntaxError("unbalanced open brace '{'", info) if stack: m = stack[-1] row, _ = calcRowCol(str, m.start()) try: info = refs[row] except KeyError: info =None raise spyceException.spyceSyntaxError("unbalanced close brace '}'", info)
def eatToken(type, string, begin, end, _, out=out, braceConv=braceConv, spyceRefs=spyceRefs, spyceRefs2=spyceRefs2): try: beginrow, _ = begin line1 = out.lineno braceConv.emitToken(type, string) line2 = out.lineno if spyceRefs.has_key(beginrow): for l in range(line1, line2): spyceRefs2[l] = spyceRefs[beginrow] except: raise spyceException.spyceSyntaxError(sys.exc_info()[0])
def processChunk(self, globalChunk=0): # collect chunk self.popToken() begin = self._tokenBegin chunk = '' while self._tokenType not in [T_END, T_EOF]: if self._tokenType == T_TEXT: chunk = chunk + self._tokenText elif self._tokenType == T_LAMBDA: chunk = chunk + self.processLambda() else: self.processUnexpected() end = self._tokenEnd self.popToken() chunk = string.split(chunk, '\n') # eliminate initial blank lines brow, bcol = begin while chunk and not string.strip(chunk[0]): chunk = chunk[1:] brow = brow + 1 bcol = 0 begin = brow, bcol if not chunk: self.processUnexpected() # outdent chunk based on first line # note: modifies multi-line strings having more spaces than first line outdent # by removing outdent number of spaces at the beginning of each line. # -- difficult to deal with efficiently (without parsing python) so just # don't do this! outdent = len(chunk[0]) - len(string.lstrip(chunk[0])) for i in range(len(chunk)): if string.strip(chunk[i][:outdent]): chunk[i] = ' ' * outdent + chunk[i] chunk = map(lambda l, outdent=outdent: l[outdent:], chunk) chunk = string.join(chunk, '\n') # add chunk block at ast if chunk: try: self._ast.addCodeIndented(chunk, (begin, end, chunk, self._curfile), globalChunk) except tokenize.TokenError, e: msg, _ = e raise spyceException.spyceSyntaxError( msg, (begin, end, chunk, self._curfile))
def processLambda(self): # collect lambda self.popToken() begin = self._tokenBegin lamb = '' depth = 1 while self._tokenType != T_EOF: if self._tokenType in [ T_END, ]: depth = depth - 1 if not depth: break lamb = lamb + self._tokenText elif self._tokenType in [ T_EVAL, T_STMT, T_CHUNK, T_CHUNKG, T_DIRECT, T_LAMBDA ]: depth = depth + 1 lamb = lamb + self._tokenText elif self._tokenType == T_CMNT: self.processComment() else: lamb = lamb + self._tokenText end = self._tokenEnd self.popToken() # process lambda lamb = string.split(lamb, ':') try: params = lamb[0] memoize = 0 if params and params[0] == '!': params = params[1:] memoize = 1 lamb = string.join(lamb[1:], ':') except: raise spyceException.spyceSyntaxError( 'invalid spyce lambda', (begin, end, lamb, self._curfile)) self._load_spylambda = 1 lamb = 'spylambda.define(%s,%s,%d)' % ( ` string.strip(params) `, ` lamb `, memoize) return lamb
def processChunk(self, globalChunk=0): # collect chunk self.popToken() begin = self._tokenBegin chunk = '' while self._tokenType not in [T_END, T_EOF]: if self._tokenType==T_TEXT: chunk = chunk + self._tokenText elif self._tokenType==T_LAMBDA: chunk = chunk + self.processLambda() else: self.processUnexpected() end = self._tokenEnd self.popToken() chunk = string.split(chunk, '\n') # eliminate initial blank lines brow, bcol = begin while chunk and not string.strip(chunk[0]): chunk = chunk[1:] brow = brow + 1 bcol = 0 begin = brow, bcol if not chunk: self.processUnexpected() # outdent chunk based on first line # note: modifies multi-line strings having more spaces than first line outdent # by removing outdent number of spaces at the beginning of each line. # -- difficult to deal with efficiently (without parsing python) so just # don't do this! outdent = len(chunk[0]) - len(string.lstrip(chunk[0])) for i in range(len(chunk)): if string.strip(chunk[i][:outdent]): chunk[i] = ' '*outdent + chunk[i] chunk = map(lambda l, outdent=outdent: l[outdent:], chunk) chunk = string.join(chunk, '\n') # add chunk block at ast if chunk: try: self._ast.addCodeIndented(chunk, (begin, end, chunk, self._curfile), globalChunk) except tokenize.TokenError, e: msg, _ = e raise spyceException.spyceSyntaxError(msg, (begin, end, chunk, self._curfile) )
def finish(self): if self._stack: libname, libfrom, name, info = self._stack.pop() raise spyceException.spyceSyntaxError( 'unmatched open tag', info)
raise spyceException.spyceSyntaxError( 'unable to load module: %s' % libname, info) def startTag(self, (libname, libfrom), name, attrs, pair, info): lib = self._taglibs[(libname, libfrom)] try: tag = lib.getTag(name, attrs, pair, None) except: raise spyceException.spyceSyntaxError( 'unknown tag "%s:%s"' % (libname, name), info) try: error = tag.syntax() except spyceTagSyntaxException, e: raise spyceException.spyceSyntaxError(str(e), info) if error: raise spyceException.spyceSyntaxError(error, info) if pair: self._stack.append((libname, libfrom, name, info)) def endTag(self, (libname, libfrom), name, info): try: libname1, libfrom1, name1, info1 = self._stack.pop() except IndexError: raise spyceException.spyceSyntaxError('unmatched close tag', info) if (libname1, libfrom1, name1) != (libname, libfrom, name): raise spyceException.spyceSyntaxError( 'unmatched close tag, expected <%s:%s>' % (libname1, name1), info) def finish(self): if self._stack:
def processUnexpected(self): raise spyceException.spyceSyntaxError( 'unexpected token: "%s"' % self._tokenText, (self._tokenBegin, self._tokenEnd, self._tokenText, self._curfile))
def processDirective(self): # collect directive begin = self._tokenBegin self.popToken() directive = '' while self._tokenType not in [T_END, T_EOF]: if self._tokenType == T_TEXT: directive = directive + self._tokenText else: self.processUnexpected() end = self._tokenEnd self.popToken() directive = string.strip(directive) if not directive: self.processUnexpected() # process directives name, attrs = parseDirective(directive) if name == 'compact': compact_mode = COMPACT_FULL if attrs.has_key('mode'): mode = string.lower(attrs['mode']) if mode == 'off': compact_mode = COMPACT_OFF elif mode == 'line': compact_mode = COMPACT_LINE elif mode == 'space': compact_mode = COMPACT_SPACE elif mode == 'full': compact_mode = COMPACT_FULL else: raise spyceException.spyceSyntaxError( 'invalid compacting mode "%s" specified' % mode, (begin, end, directive, self._curfile)) self._ast.addCompact( compact_mode, (begin, end, '<spyce compact directive>', self._curfile)) elif name in ('module', 'import'): if not attrs.has_key('name') and not attrs.has_key('names'): raise spyceException.spyceSyntaxError( 'name or names attribute required', (begin, end, directive, self._curfile)) if attrs.has_key('names'): mod_names = filter( None, map(string.strip, string.split(attrs['names'], ','))) for mod_name in mod_names: self._ast.addModule(mod_name, None, None) self._ast.addCode('%s.init()' % mod_name, (begin, end, directive, self._curfile)) else: mod_name = attrs['name'] mod_from = spyceUtil.extractValue(attrs, 'from') mod_as = spyceUtil.extractValue(attrs, 'as') mod_args = spyceUtil.extractValue(attrs, 'args', '') if mod_as: theName = mod_as else: theName = mod_name self._ast.addModule(mod_name, mod_from, mod_as) self._ast.addCode('%s.init(%s)' % (theName, mod_args), (begin, end, directive, self._curfile)) elif name in ('taglib', ): if not attrs.has_key('name') and not attrs.has_key('names'): raise spyceException.spyceSyntaxError( 'name or names attribute required', (begin, end, directive, self._curfile)) fullfile = os.path.join(self._curdir, self._curfile) if attrs.has_key('names'): taglib_names = filter( None, map(string.strip, string.split(attrs['names'], ','))) for taglib_name in taglib_names: self._tagChecker.loadLib( taglib_name, None, None, fullfile, (begin, end, directive, self._curfile)) self._ast.addTaglib(taglib_name) self._load_taglib = 1 self._ast.addCode('taglib.load(%s)' % repr(taglib_name), (begin, end, directive, self._curfile)) else: taglib_name = attrs['name'] taglib_from = spyceUtil.extractValue(attrs, 'from') taglib_as = spyceUtil.extractValue(attrs, 'as') self._tagChecker.loadLib( taglib_name, taglib_from, taglib_as, fullfile, (begin, end, directive, self._curfile)) self._ast.addTaglib(taglib_name, taglib_from, taglib_as) self._load_taglib = 1 self._ast.addCode( 'taglib.load(%s, %s, %s)' % (repr(taglib_name), repr(taglib_from), repr(taglib_as)), (begin, end, directive, self._curfile)) elif name == 'include': if not attrs.has_key('file'): raise spyceException.spyceSyntaxError( 'file attribute missing', (begin, end, directive, self._curfile)) filename = os.path.join(self._curdir, attrs['file']) f = None try: try: f = open(filename) buf = f.read() finally: if f: f.close() except KeyboardInterrupt: raise except: raise spyceException.spyceSyntaxError( 'unable to open included file: %s' % filename, (begin, end, directive, self._curfile)) prev = (self._curdir, self._curfile, self._tokens, self._tokenType, self._tokenText, self._tokenBegin, self._tokenEnd) self._curdir, self._curfile = os.path.dirname(filename), filename self._tokens = spyceTokenize4Parse(processMagic(buf)) self.popToken() self.processSpyce() (self._curdir, self._curfile, self._tokens, self._tokenType, self._tokenText, self._tokenBegin, self._tokenEnd) = prev else: raise spyceException.spyceSyntaxError( 'invalid spyce directive', (begin, end, directive, self._curfile))
def processDirective(self): # collect directive begin = self._tokenBegin self.popToken() directive = '' while self._tokenType not in [T_END, T_EOF]: if self._tokenType==T_TEXT: directive = directive + self._tokenText else: self.processUnexpected() end = self._tokenEnd self.popToken() directive = string.strip(directive) if not directive: self.processUnexpected() # process directives name, attrs = parseDirective(directive) if name=='compact': compact_mode = COMPACT_FULL if attrs.has_key('mode'): mode = string.lower(attrs['mode']) if mode=='off': compact_mode = COMPACT_OFF elif mode=='line': compact_mode = COMPACT_LINE elif mode=='space': compact_mode = COMPACT_SPACE elif mode=='full': compact_mode = COMPACT_FULL else: raise spyceException.spyceSyntaxError('invalid compacting mode "%s" specified'%mode, (begin, end, directive, self._curfile)) self._ast.addCompact(compact_mode, (begin, end, '<spyce compact directive>', self._curfile)) elif name in ('module', 'import'): if not attrs.has_key('name') and not attrs.has_key('names'): raise spyceException.spyceSyntaxError('name or names attribute required', (begin, end, directive, self._curfile) ) if attrs.has_key('names'): mod_names = filter(None, map(string.strip, string.split(attrs['names'],','))) for mod_name in mod_names: self._ast.addModule(mod_name, None, None) self._ast.addCode('%s.init()'%mod_name, (begin, end, directive, self._curfile)) else: mod_name = attrs['name'] mod_from = spyceUtil.extractValue(attrs, 'from') mod_as = spyceUtil.extractValue(attrs, 'as') mod_args = spyceUtil.extractValue(attrs, 'args', '') if mod_as: theName=mod_as else: theName=mod_name self._ast.addModule(mod_name, mod_from, mod_as) self._ast.addCode('%s.init(%s)'%(theName,mod_args), (begin, end, directive, self._curfile)) elif name in ('taglib',): if not attrs.has_key('name') and not attrs.has_key('names'): raise spyceException.spyceSyntaxError('name or names attribute required', (begin, end, directive, self._curfile) ) fullfile = os.path.join(self._curdir, self._curfile) if attrs.has_key('names'): taglib_names = filter(None, map(string.strip, string.split(attrs['names'],','))) for taglib_name in taglib_names: self._tagChecker.loadLib(taglib_name, None, None, fullfile, (begin, end, directive, self._curfile)) self._ast.addTaglib(taglib_name) self._load_taglib = 1 self._ast.addCode('taglib.load(%s)'%repr(taglib_name), (begin, end, directive, self._curfile)) else: taglib_name = attrs['name'] taglib_from = spyceUtil.extractValue(attrs, 'from') taglib_as = spyceUtil.extractValue(attrs, 'as') self._tagChecker.loadLib(taglib_name, taglib_from, taglib_as, fullfile, (begin, end, directive, self._curfile)) self._ast.addTaglib(taglib_name, taglib_from, taglib_as) self._load_taglib = 1 self._ast.addCode('taglib.load(%s, %s, %s)'%(repr(taglib_name), repr(taglib_from), repr(taglib_as)), (begin, end, directive, self._curfile)) elif name=='include': if not attrs.has_key('file'): raise spyceException.spyceSyntaxError('file attribute missing', (begin, end, directive, self._curfile) ) filename = os.path.join(self._curdir, attrs['file']) f = None try: try: f = open(filename) buf = f.read() finally: if f: f.close() except KeyboardInterrupt: raise except: raise spyceException.spyceSyntaxError('unable to open included file: %s'%filename, (begin, end, directive, self._curfile) ) prev = (self._curdir, self._curfile, self._tokens, self._tokenType, self._tokenText, self._tokenBegin, self._tokenEnd) self._curdir, self._curfile = os.path.dirname(filename), filename self._tokens = spyceTokenize4Parse(processMagic(buf)) self.popToken() self.processSpyce() (self._curdir, self._curfile, self._tokens, self._tokenType, self._tokenText, self._tokenBegin, self._tokenEnd) = prev else: raise spyceException.spyceSyntaxError('invalid spyce directive', (begin, end, directive, self._curfile) )
except: raise spyceException.spyceSyntaxError( 'unable to load module: %s'%libname, info) def getTag(self, (libname,libfrom), name, attrs, pair, info): lib = self._taglibs[(libname, libfrom)] try: return lib.getTag(name, attrs, pair, None) except: raise spyceException.spyceSyntaxError( 'unknown tag "%s:%s"'%(libname, name), info) def getTagClass(self, (libname, libfrom), name, info): lib = self._taglibs[(libname, libfrom)] try: return lib.getTagClass(name) except: raise spyceException.spyceSyntaxError( 'unknown tag "%s:%s"'%(libname, name), info) def startTag(self, (libname,libfrom), name, attrs, pair, info): tag = self.getTag((libname, libfrom), name, attrs, pair, info) try: error = tag.syntax() except spyceTagSyntaxException, e: raise spyceException.spyceSyntaxError(str(e), info) if error: raise spyceException.spyceSyntaxError(error, info) if pair: self._stack.append( (libname, libfrom, name, info) ) def endTag(self, (libname,libfrom), name, info): try: libname1, libfrom1, name1, info1 = self._stack.pop() except IndexError: raise spyceException.spyceSyntaxError(
def processUnexpected(self): raise spyceException.spyceSyntaxError('unexpected token: "%s"'%self._tokenText, (self._tokenBegin, self._tokenEnd, self._tokenText, self._curfile))
def finish(self): if self._stack: libname, libfrom, name, info = self._stack.pop() raise spyceException.spyceSyntaxError('unmatched open tag', info)
raise except: raise spyceException.spyceSyntaxError("unable to load module: %s" % libname, info) def startTag(self, (libname, libfrom), name, attrs, pair, info): lib = self._taglibs[(libname, libfrom)] try: tag = lib.getTag(name, attrs, pair, None) except: raise spyceException.spyceSyntaxError('unknown tag "%s:%s"' % (libname, name), info) try: error = tag.syntax() except spyceTagSyntaxException, e: raise spyceException.spyceSyntaxError(str(e), info) if error: raise spyceException.spyceSyntaxError(error, info) if pair: self._stack.append((libname, libfrom, name, info)) def endTag(self, (libname, libfrom), name, info): try: libname1, libfrom1, name1, info1 = self._stack.pop() except IndexError: raise spyceException.spyceSyntaxError("unmatched close tag", info) if (libname1, libfrom1, name1) != (libname, libfrom, name): raise spyceException.spyceSyntaxError("unmatched close tag, expected <%s:%s>" % (libname1, name1), info) def finish(self): if self._stack: libname, libfrom, name, info = self._stack.pop() raise spyceException.spyceSyntaxError("unmatched open tag", info)