comparison mercurial/parser.py @ 25654:af329a84310c

parser: accept iterator of tokens instead of tokenizer function and program This can simplify the interface of parse() function. Our tokenizer tends to have optional arguments other than the message to be parsed. Before this patch, the "lookup" argument existed only for the revset, and the templater had to pack [program, start, end] to be passed to its tokenizer.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 21 Jun 2015 00:49:26 +0900
parents c87b05925054
children b8b73652c1c9
comparison
equal deleted inserted replaced
25653:9d1e04f5dca7 25654:af329a84310c
17 17
18 import error 18 import error
19 from i18n import _ 19 from i18n import _
20 20
21 class parser(object): 21 class parser(object):
22 def __init__(self, tokenizer, elements, methods=None): 22 def __init__(self, elements, methods=None):
23 self._tokenizer = tokenizer
24 self._elements = elements 23 self._elements = elements
25 self._methods = methods 24 self._methods = methods
26 self.current = None 25 self.current = None
27 def _advance(self): 26 def _advance(self):
28 'advance the tokenizer' 27 'advance the tokenizer'
70 else: 69 else:
71 expr = (infix[0], expr, self._parse(infix[1])) 70 expr = (infix[0], expr, self._parse(infix[1]))
72 if len(infix) == 3: 71 if len(infix) == 3:
73 self._match(infix[2], pos) 72 self._match(infix[2], pos)
74 return expr 73 return expr
75 def parse(self, message, lookup=None): 74 def parse(self, tokeniter):
76 'generate a parse tree from a message' 75 'generate a parse tree from tokens'
77 if lookup: 76 self._iter = tokeniter
78 self._iter = self._tokenizer(message, lookup)
79 else:
80 self._iter = self._tokenizer(message)
81 self._advance() 77 self._advance()
82 res = self._parse() 78 res = self._parse()
83 token, value, pos = self.current 79 token, value, pos = self.current
84 return res, pos 80 return res, pos
85 def eval(self, tree): 81 def eval(self, tree):
86 'recursively evaluate a parse tree using node methods' 82 'recursively evaluate a parse tree using node methods'
87 if not isinstance(tree, tuple): 83 if not isinstance(tree, tuple):
88 return tree 84 return tree
89 return self._methods[tree[0]](*[self.eval(t) for t in tree[1:]]) 85 return self._methods[tree[0]](*[self.eval(t) for t in tree[1:]])
90 def __call__(self, message): 86 def __call__(self, tokeniter):
91 'parse a message into a parse tree and evaluate if methods given' 87 'parse tokens into a parse tree and evaluate if methods given'
92 t = self.parse(message) 88 t = self.parse(tokeniter)
93 if self._methods: 89 if self._methods:
94 return self.eval(t) 90 return self.eval(t)
95 return t 91 return t
96 92
97 def _prettyformat(tree, leafnodes, level, lines): 93 def _prettyformat(tree, leafnodes, level, lines):