152 lines
3.6 KiB
Python
152 lines
3.6 KiB
Python
import re
|
|
import lex
|
|
|
|
MAX_MAX = 1024
|
|
|
|
class Rule(object):
|
|
def __init__(self, *rules):
|
|
self.rules = rules
|
|
def match(self, tokens):
|
|
if not tokens:
|
|
return []
|
|
return self._match(tokens)
|
|
def _match(self, tokens):
|
|
raise Exception("unimplemented")
|
|
|
|
class Any(Rule):
|
|
def __init__(self):
|
|
pass
|
|
def _match(self, tokens):
|
|
if tokens:
|
|
return [1]
|
|
else:
|
|
return []
|
|
|
|
class Name(Rule):
|
|
def __init__(self, name):
|
|
self.name = name
|
|
def _match(self, tokens):
|
|
if tokens[0].name == self.name:
|
|
return [1]
|
|
else:
|
|
return []
|
|
class Names(Rule):
|
|
def __init__(self, names):
|
|
self.names = names
|
|
def _match(self, tokens):
|
|
for token in tokens:
|
|
if token.name in self.names:
|
|
return [1]
|
|
return []
|
|
|
|
class String(Rule):
|
|
def __init__(self, s):
|
|
self.string = s
|
|
def _match(self, tokens):
|
|
for token in tokens:
|
|
if token.string == self.string:
|
|
return [1]
|
|
return []
|
|
class Strings(Rule):
|
|
def __init__(self, ss):
|
|
self.strings = ss
|
|
def _match(self, tokens):
|
|
for token in tokens:
|
|
if token.string in self.strings:
|
|
return [1]
|
|
return []
|
|
class Stringre(Rule):
|
|
def __init__(self, r):
|
|
self.regex = re.compile(r)
|
|
def _match(self, tokens):
|
|
for token in tokens:
|
|
if self.regex.match(token.string):
|
|
return [1]
|
|
return []
|
|
|
|
class Match(Rule):
|
|
method = lex.Token.match
|
|
def __init__(self, *args):
|
|
self.args = args
|
|
def match(self, tokens):
|
|
if not tokens:
|
|
return []
|
|
elif self.method(tokens[0], *self.args):
|
|
return [1]
|
|
else:
|
|
return []
|
|
class Matchs(Match):
|
|
method = lex.Token.matchs
|
|
class Matchp(Match):
|
|
method = lex.Token.matchp
|
|
|
|
class Fqmatch(Match):
|
|
method = lex.Token.fqmatch
|
|
class Fqmatchs(Match):
|
|
method = lex.Token.fqmatchs
|
|
class Fqmatchp(Match):
|
|
method = lex.Token.fqmatchp
|
|
|
|
class And(Rule):
|
|
def match(self, tokens):
|
|
n = 0
|
|
for r in self.rules:
|
|
result = r.match(tokens[n:])
|
|
if not result:
|
|
return []
|
|
n += result[0]
|
|
return [n]
|
|
class Or(Rule):
|
|
def match(self, tokens):
|
|
n = 0
|
|
for r in self.rules:
|
|
result = r.match(tokens[n:])
|
|
if result:
|
|
return result
|
|
n += result[0]
|
|
return []
|
|
|
|
class Repeat(Rule):
|
|
def __init__(self, rule, minimum, maximum):
|
|
self.rule = rule
|
|
self.minimum = minimum
|
|
self.maximum = maximum
|
|
def match(self, tokens):
|
|
n = 0
|
|
for _ in xrange(0, self.minimum):
|
|
result = self.rule.match(tokens[n:])
|
|
if not result:
|
|
return []
|
|
n += result[0]
|
|
for _ in xrange(self.minimum, self.maximum):
|
|
result = self.rule.match(tokens[n:])
|
|
if not result:
|
|
return [n]
|
|
n += result[0]
|
|
return [n]
|
|
|
|
class Optional(Repeat):
|
|
def __init__(self, rule):
|
|
self.rule = rule
|
|
self.minimum = 0
|
|
self.maximum = 1
|
|
class Star(Repeat):
|
|
def __init__(self, rule):
|
|
self.rule = rule
|
|
self.minimum = 0
|
|
self.maximum = MAX_MAX
|
|
class Plus(Repeat):
|
|
def __init__(self, rule):
|
|
self.rule = rule
|
|
self.minimum = 1
|
|
self.maximum = MAX_MAX
|
|
|
|
class End(Rule):
|
|
def __init__(self):
|
|
pass
|
|
def match(self, tokens):
|
|
if tokens:
|
|
return []
|
|
else:
|
|
return [0]
|