pmacs3/parse.py

150 lines
3.5 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):
if token.name in self.names:
return [1]
else:
return []
class String(Rule):
def __init__(self, s):
self.string = s
def _match(self, tokens):
if token.string == self.string:
return [1]
else:
return []
class Strings(Rule):
def __init__(self, ss):
self.strings = ss
def _match(self, tokens):
if token.string in self.strings:
return [1]
else:
return []
class Stringre(Rule):
def __init__(self, r):
self.regex = re.compile(r)
def _match(self, tokens):
if self.regex.match(token.string):
return [1]
else:
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):
for r in self.rules:
result = r.match(tokens[n:])
if result:
return result
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 i in range(0, self.minimum):
result = self.rule.match(tokens[n:])
if not result:
return []
n += result[0]
for i in range(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]