java fixes and parsing

--HG--
branch : pmacs2
This commit is contained in:
moculus 2009-02-03 14:56:22 +00:00
parent ef56ae12bc
commit bfa188627e
2 changed files with 134 additions and 37 deletions

View File

@ -3,6 +3,7 @@ import context
from lex import Grammar, PatternRule, RegionRule from lex import Grammar, PatternRule, RegionRule
from mode.python import StringGrammar2 from mode.python import StringGrammar2
from mode.c import CTabber2 from mode.c import CTabber2
from parse import Any, And, Or, Optional, Name, Match, Matchs
class CommentGrammar(Grammar): class CommentGrammar(Grammar):
rules = [ rules = [
@ -60,6 +61,23 @@ class JavaTabber2(tab.StackTabber2):
'comment.data', 'comment.null', 'comment.end') 'comment.data', 'comment.null', 'comment.end')
class JavaContext(context.Context): class JavaContext(context.Context):
class_match = And(Optional(Name('spaces')),
Matchs('keyword', ('public', 'protected', 'private')),
Name('spaces'),
Match('keyword', 'class'),
Name('spaces'),
Name('identifier'))
class_offset = 1
method_match = And(Optional(Name('spaces')),
Matchs('keyword', ('public', 'protected', 'private')),
Name('spaces'),
Optional(And(Match('keyword', 'static'), Name('spaces'))),
Any(),
Name('spaces'),
Name('identifier'),
Optional(Name('spaces')),
Match('delimiter', '('))
method_offset = 2
def _regen_stack(self, y): def _regen_stack(self, y):
if y > 0 and self.namelines[y - 1][1]: if y > 0 and self.namelines[y - 1][1]:
return list(self.namelines[y - 1][1]) return list(self.namelines[y - 1][1])
@ -78,24 +96,29 @@ class JavaContext(context.Context):
g = highlights.tokens[i] g = highlights.tokens[i]
gl = len(g) gl = len(g)
if gl > 2 and g[0].match('keyword', 'class'): result = self.class_match.match(g)
curr = g[2].string if result:
elif gl > 4 and g[2].match('keyword', 'class'): n = result[0] - self.class_offset
curr = g[4].string curr = g[n].string
result = self.method_match.match(g)
if result:
n = result[0] - self.method_offset
curr = g[n].string
if curr is not None and curr not in self.names: if curr is not None and curr not in self.names:
self.names[curr] = i self.names[curr] = i
if i == y2 - 1 and curr != self.namelines[i][0] and y2 < blen:
y2 += 1
for t in g: for t in g:
if t.match('delimiter', '{'): if t.match('delimiter', '{'):
stack.append(t.string) stack.append(curr)
elif t.match('delimiter', '}'): elif t.match('delimiter', '}'):
#assert stack, "uh oh"
if stack: if stack:
stack.pop(-1) stack.pop(-1)
if stack:
curr = stack[-1]
else:
curr = None
if curr: if curr:
self.namelines[i] = (curr, tuple(stack)) self.namelines[i] = (curr, tuple(stack))

128
parse.py
View File

@ -1,23 +1,80 @@
import re
import lex import lex
MAX_MAX = 1024
class Rule(object): class Rule(object):
def __init__(self, *rules): def __init__(self, *rules):
self.rules = rules self.rules = rules
def match(self, tokens): def match(self, tokens):
if not tokens:
return []
return self._match(tokens)
def _match(self, tokens):
raise Exception("unimplemented") 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): class Match(Rule):
method = lex.Token.match method = lex.Token.match
def __init__(self, *args): def __init__(self, *args):
self.args = args self.args = args
def match(self, tokens): def match(self, tokens):
if not tokens: if not tokens:
return False return []
elif method(tokens[0], *self.args): elif self.method(tokens[0], *self.args):
tokens.pop(0) return [1]
return True
else: else:
return False return []
class Matchs(Match): class Matchs(Match):
method = lex.Token.matchs method = lex.Token.matchs
class Matchp(Match): class Matchp(Match):
@ -32,16 +89,20 @@ class Fqmatchp(Match):
class And(Rule): class And(Rule):
def match(self, tokens): def match(self, tokens):
n = 0
for r in self.rules: for r in self.rules:
if not r.match(tokens): result = r.match(tokens[n:])
return False if not result:
return True return []
n += result[0]
return [n]
class Or(Rule): class Or(Rule):
def match(self, tokens): def match(self, tokens):
for r in self.rules: for r in self.rules:
if r.match(tokens): result = r.match(tokens[n:])
return True if result:
return False return result
return []
class Repeat(Rule): class Repeat(Rule):
def __init__(self, rule, minimum, maximum): def __init__(self, rule, minimum, maximum):
@ -49,27 +110,40 @@ class Repeat(Rule):
self.minimum = minimum self.minimum = minimum
self.maximum = maximum self.maximum = maximum
def match(self, tokens): def match(self, tokens):
n = 0
for i in range(0, self.minimum): for i in range(0, self.minimum):
if not self.rule.match(tokens): result = self.rule.match(tokens[n:])
return False if not result:
while self.rules.match(tokens): return []
pass n += result[0]
return True for i in range(self.minimum, self.maximum):
self.rule.match(tokens) result = self.rule.match(tokens[n:])
return True if not result:
return [n]
n += result[0]
return [n]
class Star(Rule): class Optional(Repeat):
def __init__(self, rule): def __init__(self, rule):
self.rule = rule self.rule = rule
def match(self, tokens): self.minimum = 0
if not self.rule.match(tokens): self.maximum = 1
return False class Star(Repeat):
while self.rules.match(tokens): def __init__(self, rule):
pass self.rule = rule
return True 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): class End(Rule):
def __init__(self): def __init__(self):
pass pass
def match(self, tokens): def match(self, tokens):
return not tokens if tokens:
return []
else:
return [0]