summaryrefslogtreecommitdiff
path: root/scss/src/yapps/runtime.py
diff options
context:
space:
mode:
Diffstat (limited to 'scss/src/yapps/runtime.py')
-rw-r--r--scss/src/yapps/runtime.py84
1 files changed, 36 insertions, 48 deletions
diff --git a/scss/src/yapps/runtime.py b/scss/src/yapps/runtime.py
index e23210a..6920fdb 100644
--- a/scss/src/yapps/runtime.py
+++ b/scss/src/yapps/runtime.py
@@ -21,7 +21,6 @@ import re
import sys
DEBUG = False
-MIN_WINDOW = 4096
# File lookup window
@@ -71,9 +70,6 @@ class Token(object):
return output
-in_name = 0
-
-
class Scanner(object):
"""Yapps scanner.
@@ -85,9 +81,11 @@ class Scanner(object):
restriction (the set is always the full set of tokens).
"""
+ MIN_WINDOW = 4096
+ in_name = 0
def __init__(self, patterns, ignore, input="",
- file=None, filename=None, stacked=False):
+ file=None, filename=None):
"""Initialize the scanner.
Parameters:
@@ -106,13 +104,11 @@ class Scanner(object):
"""
if not filename:
- global in_name
- filename = "<f.%d>" % in_name
- in_name += 1
+ filename = "<f.%d>" % self.__class__.in_name
+ self.__class__.in_name += 1
self.reset(input, file, filename)
self.ignore = ignore
- self.stacked = stacked
if patterns is not None:
# Compile the regex strings into regex objects
@@ -216,19 +212,19 @@ class Scanner(object):
"""Get more input if possible."""
if not self.file:
return
- if len(self.input) - self.pos >= MIN_WINDOW:
+ if len(self.input) - self.pos >= self.MIN_WINDOW:
return
- data = self.file.read(MIN_WINDOW)
+ data = self.file.read(self.MIN_WINDOW)
if data is None or data == "":
self.file = None
# Drop bytes from the start, if necessary.
- if self.pos > 2 * MIN_WINDOW:
- self.del_pos += MIN_WINDOW
- self.del_line += self.input[:MIN_WINDOW].count("\n")
- self.pos -= MIN_WINDOW
- self.input = self.input[MIN_WINDOW:] + data
+ if self.pos > 2 * self.MIN_WINDOW:
+ self.del_pos += self.MIN_WINDOW
+ self.del_line += self.input[:self.MIN_WINDOW].count("\n")
+ self.pos -= self.MIN_WINDOW
+ self.input = self.input[self.MIN_WINDOW:] + data
else:
self.input = self.input + data
@@ -245,21 +241,17 @@ class Scanner(object):
Should scan another token and add it to the list, self.tokens,
and add the restriction to self.restrictions
"""
+ token = None
# Keep looking for a token, ignoring any in self.ignore
while True:
tok = None
self.grab_input()
- # special handling for end-of-file
- if self.stacked and self.pos == len(self.input):
- raise StopIteration
-
# Search the patterns for the longest match, with earlier
# tokens in the list having preference
- best_match = -1
+ best_pat_len = -1
best_pat = None
- best_m = None
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)))
@@ -269,56 +261,44 @@ class Scanner(object):
print "\tSkipping %s!" % repr(tok)
continue
m = regex.match(self.input, self.pos)
- if m and m.end() - m.start() > best_match:
+ if m and m.end() - m.start() > best_pat_len:
# We got a match that's better than the previous one
best_pat = tok
- best_match = m.end() - m.start()
- best_m = m
+ best_pat_len = m.end() - m.start()
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 or best_match < 0:
+ if best_pat is None or best_pat_len < 0:
msg = "Bad token: %s" % ("???" if tok is None else repr(tok),)
if restrict:
msg = "%s found while trying to find one of the restricted tokens: %s" % ("???" if tok is None else repr(tok), ", ".join(repr(r) for r in restrict))
raise SyntaxError(self.get_pos(), msg, context=context)
- ignore = best_pat in self.ignore
- end_pos = self.pos + best_match
- value = self.input[self.pos:end_pos]
+ ignore = best_pat in self.ignore # Should this token be ignored?
+ start_pos = self.pos
+ end_pos = start_pos + best_pat_len
+ self.pos = end_pos
+
+ # If we found something that isn't to be ignored, return it
if not ignore:
+ value = self.input[start_pos:end_pos]
# token = Token(type=best_pat, value=value, pos=self.get_pos())
token = (
- self.pos,
+ start_pos,
end_pos,
best_pat,
value,
)
- self.pos = end_pos
-
- npos = value.rfind("\n")
- if npos > -1:
- self.col = best_match - npos
- self.line += value.count('\n')
- else:
- self.col += best_match
-
- # If we found something that isn't to be ignored, return it
- if not ignore:
# print repr(token)
if not self.tokens or token != self.last_read_token:
- # Only add this token if it's not in the list
- # (to prevent looping)
+ # Only add this token if it's not in the list (to prevent looping)
self.last_read_token = token
self.tokens.append(token)
self.restrictions.append(restrict)
return 1
return 0
- else:
- ignore = self.ignore[best_pat]
- if ignore:
- ignore(self, best_m)
def token(self, i, restrict=None, **kwargs):
"""
@@ -335,7 +315,15 @@ class Scanner(object):
raise NotImplementedError("Unimplemented: restriction set changed")
if i >= 0 and i < tokens_len:
return self.tokens[i]
- raise NoMoreTokens
+ 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 Parser(object):