import Test
import exceptions
import sys
from Plex import *
if 1:
debug = sys.stdout
else:
debug = None
#########################################################################
class NaughtyNaughty(exceptions.Exception):
pass
class MyScanner(Scanner):
bracket_nesting_level = 0
indentation_stack = None
indentation_char = None
def current_level(self):
return self.indentation_stack[-1]
def open_bracket_action(self, text):
self.bracket_nesting_level = self.bracket_nesting_level + 1
return text
def close_bracket_action(self, text):
self.bracket_nesting_level = self.bracket_nesting_level - 1
return text
def newline_action(self, text):
if self.bracket_nesting_level == 0:
self.begin('indent')
self.produce('newline', '')
def indentation_action(self, text):
self.begin('')
# Check that tabs and spaces are being used consistently.
if text:
c = text[0]
if self.indentation_char is None:
self.indentation_char = c
else:
if self.indentation_char <> c:
raise NaughtyNaughty("Mixed up tabs and spaces!")
# Figure out how many indents/dedents to do
current_level = self.current_level()
new_level = len(text)
if new_level == current_level:
return
elif new_level > current_level:
self.indentation_stack.append(new_level)
self.produce('INDENT', '')
else:
while new_level < self.current_level():
del self.indentation_stack[-1]
self.produce('DEDENT', '')
if new_level <> self.current_level():
raise NaughtyNaughty("Indentation booboo!")
def eof(self):
while len(self.indentation_stack) > 1:
self.produce('DEDENT', '')
self.indentation_stack.pop()
letter = Range("AZaz") | Any("_")
digit = Range("09")
hexdigit = Range("09AFaf")
indentation = Rep(Str(" ")) | Rep(Str("\t"))
name = letter + Rep(letter | digit)
number = Rep1(digit) | (Str("0x") + Rep1(hexdigit))
sq_string = (
Str("'") +
Rep(AnyBut("\\\n'") | (Str("\\") + AnyChar)) +
Str("'"))
dq_string = (
Str('"') +
Rep(AnyBut('\\\n"') | (Str("\\") + AnyChar)) +
Str('"'))
non_dq = AnyBut('"') | (Str('\\') + AnyChar)
tq_string = (
Str('"""') +
Rep(
non_dq |
(Str('"') + non_dq) |
(Str('""') + non_dq)) + Str('"""'))
stringlit = sq_string | dq_string | tq_string
bra = Any("([{")
ket = Any(")]}")
punct = Any(":,;+-*/|&<>=.%`~^")
diphthong = Str("==", "<>", "!=", "<=", "<<", ">>", "**")
spaces = Rep1(Any(" \t"))
comment = Str("#") + Rep(AnyBut("\n"))
escaped_newline = Str("\\\n")
lineterm = Str("\n") | Eof
lexicon = Lexicon([
(name, 'name'),
(number, 'number'),
(stringlit, 'string'),
(punct | diphthong, TEXT),
(bra, open_bracket_action),
(ket, close_bracket_action),
(lineterm, newline_action),
(comment, IGNORE),
(spaces, IGNORE),
(escaped_newline, IGNORE),
State('indent', [
(indentation + Opt(comment) + lineterm, IGNORE),
(indentation, indentation_action),
]),
],
debug = Test.debug,
debug_flags = 7,
timings = sys.stderr)
def __init__(self, file):
Scanner.__init__(self, self.lexicon, file)
self.indentation_stack = [0]
self.begin('indent')
#########################################################################
#s.machine.dump(sys.stdout)
#print "=" * 70
f = open("test9.in", "rU")
ts = MyScanner(f)
ts.trace = 0
while 1:
value, text = ts.read()
level = len(ts.indentation_stack) - 1
if level:
print (4 * level - 1) * ' ',
if text and text <> value:
print "%s(%s)" % (value, repr(text))
else:
print repr(value)
if value is None:
break
syntax highlighted by Code2HTML, v. 0.9.1