This is the central parsing class Jinja2 uses. It's passed to extensions and can be used to parse expressions or statements.
| 30 | |
| 31 | |
| 32 | class Parser(object): |
| 33 | """This is the central parsing class Jinja2 uses. It's passed to |
| 34 | extensions and can be used to parse expressions or statements. |
| 35 | """ |
| 36 | |
| 37 | def __init__(self, environment, source, name=None, filename=None, |
| 38 | state=None): |
| 39 | self.environment = environment |
| 40 | self.stream = environment._tokenize(source, name, filename, state) |
| 41 | self.name = name |
| 42 | self.filename = filename |
| 43 | self.closed = False |
| 44 | self.extensions = {} |
| 45 | for extension in environment.iter_extensions(): |
| 46 | for tag in extension.tags: |
| 47 | self.extensions[tag] = extension.parse |
| 48 | self._last_identifier = 0 |
| 49 | self._tag_stack = [] |
| 50 | self._end_token_stack = [] |
| 51 | |
| 52 | def fail(self, msg, lineno=None, exc=TemplateSyntaxError): |
| 53 | """Convenience method that raises `exc` with the message, passed |
| 54 | line number or last line number as well as the current name and |
| 55 | filename. |
| 56 | """ |
| 57 | if lineno is None: |
| 58 | lineno = self.stream.current.lineno |
| 59 | raise exc(msg, lineno, self.name, self.filename) |
| 60 | |
| 61 | def _fail_ut_eof(self, name, end_token_stack, lineno): |
| 62 | expected = [] |
| 63 | for exprs in end_token_stack: |
| 64 | expected.extend(imap(describe_token_expr, exprs)) |
| 65 | if end_token_stack: |
| 66 | currently_looking = ' or '.join( |
| 67 | "'%s'" % describe_token_expr(expr) |
| 68 | for expr in end_token_stack[-1]) |
| 69 | else: |
| 70 | currently_looking = None |
| 71 | |
| 72 | if name is None: |
| 73 | message = ['Unexpected end of template.'] |
| 74 | else: |
| 75 | message = ['Encountered unknown tag \'%s\'.' % name] |
| 76 | |
| 77 | if currently_looking: |
| 78 | if name is not None and name in expected: |
| 79 | message.append('You probably made a nesting mistake. Jinja ' |
| 80 | 'is expecting this tag, but currently looking ' |
| 81 | 'for %s.' % currently_looking) |
| 82 | else: |
| 83 | message.append('Jinja was looking for the following tags: ' |
| 84 | '%s.' % currently_looking) |
| 85 | |
| 86 | if self._tag_stack: |
| 87 | message.append('The innermost block that needs to be ' |
| 88 | 'closed is \'%s\'.' % self._tag_stack[-1]) |
| 89 |
no outgoing calls
no test coverage detected
searching dependent graphs…