summaryrefslogtreecommitdiff
path: root/scss/src/scanner.py
diff options
context:
space:
mode:
Diffstat (limited to 'scss/src/scanner.py')
-rwxr-xr-xscss/src/scanner.py288
1 files changed, 0 insertions, 288 deletions
diff --git a/scss/src/scanner.py b/scss/src/scanner.py
deleted file mode 100755
index 777fd67..0000000
--- a/scss/src/scanner.py
+++ /dev/null
@@ -1,288 +0,0 @@
-#!/usr/bin/env python
-
-## locate_blocks() needs heavy optimizations... is way too slow right now!
-## Any suggestion from python wizards? :-)
-
-import re
-import sys
-from datetime import datetime
-
-from six.moves import xrange
-
-import pstats
-import cProfile
-from cStringIO import StringIO
-def profile(fn):
- def wrapper(*args, **kwargs):
- profiler = cProfile.Profile()
- stream = StringIO()
- profiler.enable()
- try:
- res = fn(*args, **kwargs)
- finally:
- profiler.disable()
- stats = pstats.Stats(profiler, stream=stream)
- stats.sort_stats('time')
- print >>stream, ""
- print >>stream, "=" * 100
- print >>stream, "Stats:"
- stats.print_stats()
-
- print >>stream, "=" * 100
- print >>stream, "Callers:"
- stats.print_callers()
-
- print >>stream, "=" * 100
- print >>stream, "Callees:"
- stats.print_callees()
- print >>sys.stderr, stream.getvalue()
- stream.close()
- return res
- return wrapper
-
-
-DEBUG = False
-################################################################################
-# Helpers
-
-_units = ['em', 'ex', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'deg', 'rad'
- 'grad', 'ms', 's', 'hz', 'khz', '%']
-PATTERNS = [
- ('":"', ':'),
- ('[ \r\t\n]+', '[ \r\t\n]+'),
- ('COMMA', ','),
- ('LPAR', '\\(|\\['),
- ('RPAR', '\\)|\\]'),
- ('END', '$'),
- ('MUL', '[*]'),
- ('DIV', '/'),
- ('ADD', '[+]'),
- ('SUB', '-\\s'),
- ('SIGN', '-(?![a-zA-Z_])'),
- ('AND', '(?<![-\\w])and(?![-\\w])'),
- ('OR', '(?<![-\\w])or(?![-\\w])'),
- ('NOT', '(?<![-\\w])not(?![-\\w])'),
- ('NE', '!='),
- ('INV', '!'),
- ('EQ', '=='),
- ('LE', '<='),
- ('GE', '>='),
- ('LT', '<'),
- ('GT', '>'),
- ('STR', "'[^']*'"),
- ('QSTR', '"[^"]*"'),
- ('UNITS', '(?<!\\s)(?:' + '|'.join(_units) + ')(?![-\\w])'),
- ('NUM', '(?:\\d+(?:\\.\\d*)?|\\.\\d+)'),
- ('BOOL', '(?<![-\\w])(?:true|false)(?![-\\w])'),
- ('COLOR', '#(?:[a-fA-F0-9]{6}|[a-fA-F0-9]{3})(?![a-fA-F0-9])'),
- ('VAR', '\\$[-a-zA-Z0-9_]+'),
- ('FNCT', '[-a-zA-Z_][-a-zA-Z0-9_]*(?=\\()'),
- ('ID', '[-a-zA-Z_][-a-zA-Z0-9_]*'),
-]
-
-
-################################################################################
-
-class NoMoreTokens(Exception):
- """
- Another exception object, for when we run out of tokens
- """
- pass
-
-
-class Scanner(object):
- def __init__(self, patterns, ignore, input=None):
- """
- Patterns is [(terminal,regex)...]
- Ignore is [terminal,...];
- Input is a string
- """
- self.reset(input)
- self.ignore = ignore
- # The stored patterns are a pair (compiled regex,source
- # regex). If the patterns variable passed in to the
- # constructor is None, we assume that the class already has a
- # proper .patterns list constructed
- if patterns is not None:
- self.patterns = []
- for k, r in patterns:
- self.patterns.append((k, re.compile(r)))
-
- def reset(self, input):
- self.tokens = []
- self.restrictions = []
- self.input = input
- self.pos = 0
-
- def __repr__(self):
- """
- Print the last 10 tokens that have been scanned in
- """
- output = ''
- for t in self.tokens[-10:]:
- output = "%s\n (@%s) %s = %s" % (output, t[0], t[2], repr(t[3]))
- return output
-
- def _scan(self, restrict):
- """
- Should scan another token and add it to the list, self.tokens,
- and add the restriction to self.restrictions
- """
- # Keep looking for a token, ignoring any in self.ignore
- token = None
- while True:
- best_pat = None
- # Search the patterns for a match, with earlier
- # tokens in the list having preference
- best_pat_len = 0
- for tok, regex in self.patterns:
- if DEBUG:
- print("\tTrying %s: %s at pos %d -> %s" % (repr(tok), repr(regex.pattern), self.pos, repr(self.input)))
- # First check to see if we're restricting to this token
- if restrict and tok not in restrict and tok not in self.ignore:
- if DEBUG:
- print "\tSkipping %s!" % repr(tok)
- continue
- m = regex.match(self.input, self.pos)
- if m:
- # We got a match
- best_pat = tok
- best_pat_len = len(m.group(0))
- if DEBUG:
- print("Match OK! %s: %s at pos %d" % (repr(tok), repr(regex.pattern), self.pos))
- break
-
- # If we didn't find anything, raise an error
- if best_pat is None:
- msg = "Bad Token"
- if restrict:
- msg = "Trying to find one of " + ", ".join(restrict)
- raise SyntaxError("SyntaxError[@ char %s: %s]" % (repr(self.pos), msg))
-
- # If we found something that isn't to be ignored, return it
- if best_pat in self.ignore:
- # This token should be ignored...
- self.pos += best_pat_len
- else:
- end_pos = self.pos + best_pat_len
- # Create a token with this data
- token = (
- self.pos,
- end_pos,
- best_pat,
- self.input[self.pos:end_pos]
- )
- break
- if token is not None:
- self.pos = token[1]
- # Only add this token if it's not in the list
- # (to prevent looping)
- if not self.tokens or token != self.tokens[-1]:
- self.tokens.append(token)
- self.restrictions.append(restrict)
- return 1
- return 0
-
- def token(self, i, restrict=None):
- """
- Get the i'th token, and if i is one past the end, then scan
- for another token; restrict is a list of tokens that
- are allowed, or 0 for any token.
- """
- tokens_len = len(self.tokens)
- if i == tokens_len: # We are at the end, get the next...
- tokens_len += self._scan(restrict)
- elif i >= 0 and i < tokens_len:
- if restrict and self.restrictions[i] and restrict > self.restrictions[i]:
- raise NotImplementedError("Unimplemented: restriction set changed")
- if i >= 0 and i < tokens_len:
- return self.tokens[i]
- raise NoMoreTokens()
-
- def rewind(self, i):
- tokens_len = len(self.tokens)
- if i <= tokens_len:
- token = self.tokens[i]
- self.tokens = self.tokens[:i]
- self.restrictions = self.restrictions[:i]
- self.pos = token[0]
-
-
-class _Scanner_a(Scanner):
- patterns = None
- _patterns = PATTERNS
-
- def __init__(self, input=None):
- if hasattr(self, 'setup_patterns'):
- self.setup_patterns(self._patterns)
- elif self.patterns is None:
- self.__class__.patterns = []
- for t, p in self._patterns:
- self.patterns.append((t, re.compile(p)))
- super(_Scanner_a, self).__init__(None, ['[ \r\t\n]+'], input)
-
-
-################################################################################
-
-try:
- from _speedups import Scanner
-
- class _Scanner_b(Scanner):
- patterns = None
- _patterns = PATTERNS
-
- def __init__(self, input=None):
- if hasattr(self, 'setup_patterns'):
- self.setup_patterns(self._patterns)
- elif self.patterns is None:
- self.__class__.patterns = []
- for t, p in self._patterns:
- self.patterns.append((t, re.compile(p)))
- super(_Scanner_b, self).__init__(None, ['[ \r\t\n]+'], input)
-
-except ImportError:
- _Scanner_b = None
-
-
-def process_scan(Scanner, level=0, dump=False):
- ret = '' if dump else None
- s = Scanner('[(5px - 3) * (5px - 3)]')
- i = 0
- while True:
- try:
- s.token(i)
- i += 1
- if dump:
- ret += '%s\n%s\n' % ('-' * 70, repr(s))
- except:
- break
- return ret
-
-
-verify = "----------------------------------------------------------------------\n\n (@0) LPAR = '['\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n----------------------------------------------------------------------\n\n (@0) LPAR = '['\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n (@14) NUM = '5'\n----------------------------------------------------------------------\n\n (@1) LPAR = '('\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n (@14) NUM = '5'\n (@15) UNITS = 'px'\n----------------------------------------------------------------------\n\n (@2) NUM = '5'\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n (@14) NUM = '5'\n (@15) UNITS = 'px'\n (@18) SUB = '- '\n----------------------------------------------------------------------\n\n (@3) UNITS = 'px'\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n (@14) NUM = '5'\n (@15) UNITS = 'px'\n (@18) SUB = '- '\n (@20) NUM = '3'\n----------------------------------------------------------------------\n\n (@6) SUB = '- '\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n (@14) NUM = '5'\n (@15) UNITS = 'px'\n (@18) SUB = '- '\n (@20) NUM = '3'\n (@21) RPAR = ')'\n----------------------------------------------------------------------\n\n (@8) NUM = '3'\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n (@14) NUM = '5'\n (@15) UNITS = 'px'\n (@18) SUB = '- '\n (@20) NUM = '3'\n (@21) RPAR = ')'\n (@22) RPAR = ']'\n----------------------------------------------------------------------\n\n (@9) RPAR = ')'\n (@11) MUL = '*'\n (@13) LPAR = '('\n (@14) NUM = '5'\n (@15) UNITS = 'px'\n (@18) SUB = '- '\n (@20) NUM = '3'\n (@21) RPAR = ')'\n (@22) RPAR = ']'\n (@23) END = ''\n"
-
-
-def process_scans(Scanner):
- for q in xrange(20000):
- process_scan(Scanner)
-profiled_process_scans = profile(process_scans)
-
-if __name__ == "__main__":
- for scanner, desc in (
- (_Scanner_a, "Pure Python, Full algorithm (_Scanner_a)"),
- (_Scanner_b, "Builtin C Function, Full algorithm (_Scanner_b)"),
- ):
- if scanner:
- ret = process_scan(scanner, dump=True)
- # print "This is what %s returned:" % desc
- # print ret
- # print repr(ret)
- assert ret == verify, '\nFrom %s, got:\n%s\nShould be:\n%s' % (desc, ret, verify)
-
- start = datetime.now()
- print >>sys.stderr, "Timing: %s..." % desc,
- process_scans(scanner)
- elap = datetime.now() - start
-
- elapms = elap.seconds * 1000.0 + elap.microseconds / 1000.0
- print >>sys.stderr, "Done! took %06.3fms" % elapms