Mercurial > hg
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): |