eric6/ThirdParty/Pygments/pygments/lexer.py

Thu, 14 Jan 2021 18:14:15 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Thu, 14 Jan 2021 18:14:15 +0100
changeset 7983
54c5cfbb1e29
parent 7701
25f42e208e08
permissions
-rw-r--r--

Third Party packages
- updated Pygments to 2.7.4

7983
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
1 # -*- coding: utf-8 -*-
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
2 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
3 pygments.lexer
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
4 ~~~~~~~~~~~~~~
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
5
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
6 Base lexer classes.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
7
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
8 :copyright: Copyright 2006-2021 by the Pygments team, see AUTHORS.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
9 :license: BSD, see LICENSE for details.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
10 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
11
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
12 import re
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
13 import sys
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
14 import time
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
15
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
16 from pygments.filter import apply_filters, Filter
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
17 from pygments.filters import get_filter_by_name
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
18 from pygments.token import Error, Text, Other, _TokenType
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
19 from pygments.util import get_bool_opt, get_int_opt, get_list_opt, \
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
20 make_analysator, Future, guess_decode
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
21 from pygments.regexopt import regex_opt
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
22
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
23 __all__ = ['Lexer', 'RegexLexer', 'ExtendedRegexLexer', 'DelegatingLexer',
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
24 'LexerContext', 'include', 'inherit', 'bygroups', 'using', 'this',
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
25 'default', 'words']
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
26
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
27
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
28 _encoding_map = [(b'\xef\xbb\xbf', 'utf-8'),
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
29 (b'\xff\xfe\0\0', 'utf-32'),
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
30 (b'\0\0\xfe\xff', 'utf-32be'),
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
31 (b'\xff\xfe', 'utf-16'),
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
32 (b'\xfe\xff', 'utf-16be')]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
33
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
34 _default_analyse = staticmethod(lambda x: 0.0)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
35
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
36
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
37 class LexerMeta(type):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
38 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
39 This metaclass automagically converts ``analyse_text`` methods into
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
40 static methods which always return float values.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
41 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
42
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
43 def __new__(mcs, name, bases, d):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
44 if 'analyse_text' in d:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
45 d['analyse_text'] = make_analysator(d['analyse_text'])
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
46 return type.__new__(mcs, name, bases, d)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
47
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
48
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
49 class Lexer(metaclass=LexerMeta):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
50 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
51 Lexer for a specific language.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
52
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
53 Basic options recognized:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
54 ``stripnl``
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
55 Strip leading and trailing newlines from the input (default: True).
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
56 ``stripall``
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
57 Strip all leading and trailing whitespace from the input
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
58 (default: False).
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
59 ``ensurenl``
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
60 Make sure that the input ends with a newline (default: True). This
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
61 is required for some lexers that consume input linewise.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
62
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
63 .. versionadded:: 1.3
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
64
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
65 ``tabsize``
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
66 If given and greater than 0, expand tabs in the input (default: 0).
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
67 ``encoding``
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
68 If given, must be an encoding name. This encoding will be used to
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
69 convert the input string to Unicode, if it is not already a Unicode
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
70 string (default: ``'guess'``, which uses a simple UTF-8 / Locale /
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
71 Latin1 detection. Can also be ``'chardet'`` to use the chardet
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
72 library, if it is installed.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
73 ``inencoding``
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
74 Overrides the ``encoding`` if given.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
75 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
76
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
77 #: Name of the lexer
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
78 name = None
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
79
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
80 #: Shortcuts for the lexer
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
81 aliases = []
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
82
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
83 #: File name globs
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
84 filenames = []
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
85
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
86 #: Secondary file name globs
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
87 alias_filenames = []
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
88
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
89 #: MIME types
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
90 mimetypes = []
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
91
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
92 #: Priority, should multiple lexers match and no content is provided
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
93 priority = 0
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
94
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
95 def __init__(self, **options):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
96 self.options = options
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
97 self.stripnl = get_bool_opt(options, 'stripnl', True)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
98 self.stripall = get_bool_opt(options, 'stripall', False)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
99 self.ensurenl = get_bool_opt(options, 'ensurenl', True)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
100 self.tabsize = get_int_opt(options, 'tabsize', 0)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
101 self.encoding = options.get('encoding', 'guess')
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
102 self.encoding = options.get('inencoding') or self.encoding
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
103 self.filters = []
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
104 for filter_ in get_list_opt(options, 'filters', ()):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
105 self.add_filter(filter_)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
106
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
107 def __repr__(self):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
108 if self.options:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
109 return '<pygments.lexers.%s with %r>' % (self.__class__.__name__,
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
110 self.options)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
111 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
112 return '<pygments.lexers.%s>' % self.__class__.__name__
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
113
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
114 def add_filter(self, filter_, **options):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
115 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
116 Add a new stream filter to this lexer.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
117 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
118 if not isinstance(filter_, Filter):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
119 filter_ = get_filter_by_name(filter_, **options)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
120 self.filters.append(filter_)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
121
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
122 def analyse_text(text):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
123 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
124 Has to return a float between ``0`` and ``1`` that indicates
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
125 if a lexer wants to highlight this text. Used by ``guess_lexer``.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
126 If this method returns ``0`` it won't highlight it in any case, if
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
127 it returns ``1`` highlighting with this lexer is guaranteed.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
128
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
129 The `LexerMeta` metaclass automatically wraps this function so
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
130 that it works like a static method (no ``self`` or ``cls``
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
131 parameter) and the return value is automatically converted to
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
132 `float`. If the return value is an object that is boolean `False`
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
133 it's the same as if the return values was ``0.0``.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
134 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
135
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
136 def get_tokens(self, text, unfiltered=False):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
137 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
138 Return an iterable of (tokentype, value) pairs generated from
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
139 `text`. If `unfiltered` is set to `True`, the filtering mechanism
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
140 is bypassed even if filters are defined.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
141
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
142 Also preprocess the text, i.e. expand tabs and strip it if
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
143 wanted and applies registered filters.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
144 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
145 if not isinstance(text, str):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
146 if self.encoding == 'guess':
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
147 text, _ = guess_decode(text)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
148 elif self.encoding == 'chardet':
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
149 try:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
150 import chardet
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
151 except ImportError as e:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
152 raise ImportError('To enable chardet encoding guessing, '
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
153 'please install the chardet library '
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
154 'from http://chardet.feedparser.org/') from e
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
155 # check for BOM first
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
156 decoded = None
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
157 for bom, encoding in _encoding_map:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
158 if text.startswith(bom):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
159 decoded = text[len(bom):].decode(encoding, 'replace')
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
160 break
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
161 # no BOM found, so use chardet
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
162 if decoded is None:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
163 enc = chardet.detect(text[:1024]) # Guess using first 1KB
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
164 decoded = text.decode(enc.get('encoding') or 'utf-8',
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
165 'replace')
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
166 text = decoded
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
167 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
168 text = text.decode(self.encoding)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
169 if text.startswith('\ufeff'):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
170 text = text[len('\ufeff'):]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
171 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
172 if text.startswith('\ufeff'):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
173 text = text[len('\ufeff'):]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
174
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
175 # text now *is* a unicode string
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
176 text = text.replace('\r\n', '\n')
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
177 text = text.replace('\r', '\n')
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
178 if self.stripall:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
179 text = text.strip()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
180 elif self.stripnl:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
181 text = text.strip('\n')
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
182 if self.tabsize > 0:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
183 text = text.expandtabs(self.tabsize)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
184 if self.ensurenl and not text.endswith('\n'):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
185 text += '\n'
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
186
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
187 def streamer():
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
188 for _, t, v in self.get_tokens_unprocessed(text):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
189 yield t, v
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
190 stream = streamer()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
191 if not unfiltered:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
192 stream = apply_filters(stream, self.filters, self)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
193 return stream
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
194
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
195 def get_tokens_unprocessed(self, text):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
196 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
197 Return an iterable of (index, tokentype, value) pairs where "index"
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
198 is the starting position of the token within the input text.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
199
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
200 In subclasses, implement this method as a generator to
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
201 maximize effectiveness.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
202 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
203 raise NotImplementedError
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
204
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
205
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
206 class DelegatingLexer(Lexer):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
207 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
208 This lexer takes two lexer as arguments. A root lexer and
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
209 a language lexer. First everything is scanned using the language
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
210 lexer, afterwards all ``Other`` tokens are lexed using the root
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
211 lexer.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
212
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
213 The lexers from the ``template`` lexer package use this base lexer.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
214 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
215
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
216 def __init__(self, _root_lexer, _language_lexer, _needle=Other, **options):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
217 self.root_lexer = _root_lexer(**options)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
218 self.language_lexer = _language_lexer(**options)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
219 self.needle = _needle
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
220 Lexer.__init__(self, **options)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
221
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
222 def get_tokens_unprocessed(self, text):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
223 buffered = ''
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
224 insertions = []
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
225 lng_buffer = []
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
226 for i, t, v in self.language_lexer.get_tokens_unprocessed(text):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
227 if t is self.needle:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
228 if lng_buffer:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
229 insertions.append((len(buffered), lng_buffer))
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
230 lng_buffer = []
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
231 buffered += v
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
232 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
233 lng_buffer.append((i, t, v))
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
234 if lng_buffer:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
235 insertions.append((len(buffered), lng_buffer))
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
236 return do_insertions(insertions,
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
237 self.root_lexer.get_tokens_unprocessed(buffered))
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
238
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
239
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
240 # ------------------------------------------------------------------------------
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
241 # RegexLexer and ExtendedRegexLexer
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
242 #
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
243
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
244
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
245 class include(str): # pylint: disable=invalid-name
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
246 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
247 Indicates that a state should include rules from another state.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
248 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
249 pass
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
250
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
251
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
252 class _inherit:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
253 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
254 Indicates the a state should inherit from its superclass.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
255 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
256 def __repr__(self):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
257 return 'inherit'
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
258
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
259 inherit = _inherit() # pylint: disable=invalid-name
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
260
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
261
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
262 class combined(tuple): # pylint: disable=invalid-name
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
263 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
264 Indicates a state combined from multiple states.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
265 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
266
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
267 def __new__(cls, *args):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
268 return tuple.__new__(cls, args)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
269
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
270 def __init__(self, *args):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
271 # tuple.__init__ doesn't do anything
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
272 pass
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
273
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
274
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
275 class _PseudoMatch:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
276 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
277 A pseudo match object constructed from a string.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
278 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
279
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
280 def __init__(self, start, text):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
281 self._text = text
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
282 self._start = start
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
283
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
284 def start(self, arg=None):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
285 return self._start
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
286
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
287 def end(self, arg=None):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
288 return self._start + len(self._text)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
289
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
290 def group(self, arg=None):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
291 if arg:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
292 raise IndexError('No such group')
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
293 return self._text
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
294
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
295 def groups(self):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
296 return (self._text,)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
297
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
298 def groupdict(self):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
299 return {}
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
300
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
301
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
302 def bygroups(*args):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
303 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
304 Callback that yields multiple actions for each group in the match.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
305 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
306 def callback(lexer, match, ctx=None):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
307 for i, action in enumerate(args):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
308 if action is None:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
309 continue
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
310 elif type(action) is _TokenType:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
311 data = match.group(i + 1)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
312 if data:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
313 yield match.start(i + 1), action, data
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
314 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
315 data = match.group(i + 1)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
316 if data is not None:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
317 if ctx:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
318 ctx.pos = match.start(i + 1)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
319 for item in action(lexer,
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
320 _PseudoMatch(match.start(i + 1), data), ctx):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
321 if item:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
322 yield item
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
323 if ctx:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
324 ctx.pos = match.end()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
325 return callback
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
326
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
327
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
328 class _This:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
329 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
330 Special singleton used for indicating the caller class.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
331 Used by ``using``.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
332 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
333
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
334 this = _This()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
335
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
336
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
337 def using(_other, **kwargs):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
338 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
339 Callback that processes the match with a different lexer.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
340
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
341 The keyword arguments are forwarded to the lexer, except `state` which
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
342 is handled separately.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
343
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
344 `state` specifies the state that the new lexer will start in, and can
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
345 be an enumerable such as ('root', 'inline', 'string') or a simple
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
346 string which is assumed to be on top of the root state.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
347
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
348 Note: For that to work, `_other` must not be an `ExtendedRegexLexer`.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
349 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
350 gt_kwargs = {}
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
351 if 'state' in kwargs:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
352 s = kwargs.pop('state')
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
353 if isinstance(s, (list, tuple)):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
354 gt_kwargs['stack'] = s
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
355 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
356 gt_kwargs['stack'] = ('root', s)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
357
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
358 if _other is this:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
359 def callback(lexer, match, ctx=None):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
360 # if keyword arguments are given the callback
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
361 # function has to create a new lexer instance
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
362 if kwargs:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
363 # XXX: cache that somehow
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
364 kwargs.update(lexer.options)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
365 lx = lexer.__class__(**kwargs)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
366 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
367 lx = lexer
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
368 s = match.start()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
369 for i, t, v in lx.get_tokens_unprocessed(match.group(), **gt_kwargs):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
370 yield i + s, t, v
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
371 if ctx:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
372 ctx.pos = match.end()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
373 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
374 def callback(lexer, match, ctx=None):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
375 # XXX: cache that somehow
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
376 kwargs.update(lexer.options)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
377 lx = _other(**kwargs)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
378
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
379 s = match.start()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
380 for i, t, v in lx.get_tokens_unprocessed(match.group(), **gt_kwargs):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
381 yield i + s, t, v
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
382 if ctx:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
383 ctx.pos = match.end()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
384 return callback
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
385
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
386
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
387 class default:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
388 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
389 Indicates a state or state action (e.g. #pop) to apply.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
390 For example default('#pop') is equivalent to ('', Token, '#pop')
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
391 Note that state tuples may be used as well.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
392
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
393 .. versionadded:: 2.0
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
394 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
395 def __init__(self, state):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
396 self.state = state
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
397
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
398
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
399 class words(Future):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
400 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
401 Indicates a list of literal words that is transformed into an optimized
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
402 regex that matches any of the words.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
403
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
404 .. versionadded:: 2.0
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
405 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
406 def __init__(self, words, prefix='', suffix=''):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
407 self.words = words
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
408 self.prefix = prefix
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
409 self.suffix = suffix
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
410
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
411 def get(self):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
412 return regex_opt(self.words, prefix=self.prefix, suffix=self.suffix)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
413
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
414
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
415 class RegexLexerMeta(LexerMeta):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
416 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
417 Metaclass for RegexLexer, creates the self._tokens attribute from
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
418 self.tokens on the first instantiation.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
419 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
420
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
421 def _process_regex(cls, regex, rflags, state):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
422 """Preprocess the regular expression component of a token definition."""
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
423 if isinstance(regex, Future):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
424 regex = regex.get()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
425 return re.compile(regex, rflags).match
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
426
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
427 def _process_token(cls, token):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
428 """Preprocess the token component of a token definition."""
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
429 assert type(token) is _TokenType or callable(token), \
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
430 'token type must be simple type or callable, not %r' % (token,)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
431 return token
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
432
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
433 def _process_new_state(cls, new_state, unprocessed, processed):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
434 """Preprocess the state transition action of a token definition."""
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
435 if isinstance(new_state, str):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
436 # an existing state
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
437 if new_state == '#pop':
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
438 return -1
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
439 elif new_state in unprocessed:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
440 return (new_state,)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
441 elif new_state == '#push':
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
442 return new_state
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
443 elif new_state[:5] == '#pop:':
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
444 return -int(new_state[5:])
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
445 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
446 assert False, 'unknown new state %r' % new_state
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
447 elif isinstance(new_state, combined):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
448 # combine a new state from existing ones
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
449 tmp_state = '_tmp_%d' % cls._tmpname
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
450 cls._tmpname += 1
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
451 itokens = []
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
452 for istate in new_state:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
453 assert istate != new_state, 'circular state ref %r' % istate
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
454 itokens.extend(cls._process_state(unprocessed,
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
455 processed, istate))
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
456 processed[tmp_state] = itokens
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
457 return (tmp_state,)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
458 elif isinstance(new_state, tuple):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
459 # push more than one state
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
460 for istate in new_state:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
461 assert (istate in unprocessed or
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
462 istate in ('#pop', '#push')), \
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
463 'unknown new state ' + istate
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
464 return new_state
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
465 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
466 assert False, 'unknown new state def %r' % new_state
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
467
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
468 def _process_state(cls, unprocessed, processed, state):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
469 """Preprocess a single state definition."""
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
470 assert type(state) is str, "wrong state name %r" % state
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
471 assert state[0] != '#', "invalid state name %r" % state
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
472 if state in processed:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
473 return processed[state]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
474 tokens = processed[state] = []
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
475 rflags = cls.flags
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
476 for tdef in unprocessed[state]:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
477 if isinstance(tdef, include):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
478 # it's a state reference
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
479 assert tdef != state, "circular state reference %r" % state
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
480 tokens.extend(cls._process_state(unprocessed, processed,
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
481 str(tdef)))
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
482 continue
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
483 if isinstance(tdef, _inherit):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
484 # should be processed already, but may not in the case of:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
485 # 1. the state has no counterpart in any parent
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
486 # 2. the state includes more than one 'inherit'
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
487 continue
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
488 if isinstance(tdef, default):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
489 new_state = cls._process_new_state(tdef.state, unprocessed, processed)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
490 tokens.append((re.compile('').match, None, new_state))
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
491 continue
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
492
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
493 assert type(tdef) is tuple, "wrong rule def %r" % tdef
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
494
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
495 try:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
496 rex = cls._process_regex(tdef[0], rflags, state)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
497 except Exception as err:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
498 raise ValueError("uncompilable regex %r in state %r of %r: %s" %
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
499 (tdef[0], state, cls, err)) from err
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
500
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
501 token = cls._process_token(tdef[1])
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
502
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
503 if len(tdef) == 2:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
504 new_state = None
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
505 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
506 new_state = cls._process_new_state(tdef[2],
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
507 unprocessed, processed)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
508
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
509 tokens.append((rex, token, new_state))
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
510 return tokens
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
511
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
512 def process_tokendef(cls, name, tokendefs=None):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
513 """Preprocess a dictionary of token definitions."""
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
514 processed = cls._all_tokens[name] = {}
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
515 tokendefs = tokendefs or cls.tokens[name]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
516 for state in list(tokendefs):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
517 cls._process_state(tokendefs, processed, state)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
518 return processed
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
519
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
520 def get_tokendefs(cls):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
521 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
522 Merge tokens from superclasses in MRO order, returning a single tokendef
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
523 dictionary.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
524
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
525 Any state that is not defined by a subclass will be inherited
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
526 automatically. States that *are* defined by subclasses will, by
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
527 default, override that state in the superclass. If a subclass wishes to
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
528 inherit definitions from a superclass, it can use the special value
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
529 "inherit", which will cause the superclass' state definition to be
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
530 included at that point in the state.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
531 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
532 tokens = {}
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
533 inheritable = {}
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
534 for c in cls.__mro__:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
535 toks = c.__dict__.get('tokens', {})
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
536
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
537 for state, items in toks.items():
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
538 curitems = tokens.get(state)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
539 if curitems is None:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
540 # N.b. because this is assigned by reference, sufficiently
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
541 # deep hierarchies are processed incrementally (e.g. for
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
542 # A(B), B(C), C(RegexLexer), B will be premodified so X(B)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
543 # will not see any inherits in B).
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
544 tokens[state] = items
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
545 try:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
546 inherit_ndx = items.index(inherit)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
547 except ValueError:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
548 continue
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
549 inheritable[state] = inherit_ndx
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
550 continue
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
551
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
552 inherit_ndx = inheritable.pop(state, None)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
553 if inherit_ndx is None:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
554 continue
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
555
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
556 # Replace the "inherit" value with the items
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
557 curitems[inherit_ndx:inherit_ndx+1] = items
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
558 try:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
559 # N.b. this is the index in items (that is, the superclass
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
560 # copy), so offset required when storing below.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
561 new_inh_ndx = items.index(inherit)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
562 except ValueError:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
563 pass
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
564 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
565 inheritable[state] = inherit_ndx + new_inh_ndx
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
566
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
567 return tokens
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
568
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
569 def __call__(cls, *args, **kwds):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
570 """Instantiate cls after preprocessing its token definitions."""
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
571 if '_tokens' not in cls.__dict__:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
572 cls._all_tokens = {}
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
573 cls._tmpname = 0
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
574 if hasattr(cls, 'token_variants') and cls.token_variants:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
575 # don't process yet
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
576 pass
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
577 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
578 cls._tokens = cls.process_tokendef('', cls.get_tokendefs())
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
579
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
580 return type.__call__(cls, *args, **kwds)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
581
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
582
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
583 class RegexLexer(Lexer, metaclass=RegexLexerMeta):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
584 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
585 Base for simple stateful regular expression-based lexers.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
586 Simplifies the lexing process so that you need only
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
587 provide a list of states and regular expressions.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
588 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
589
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
590 #: Flags for compiling the regular expressions.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
591 #: Defaults to MULTILINE.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
592 flags = re.MULTILINE
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
593
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
594 #: Dict of ``{'state': [(regex, tokentype, new_state), ...], ...}``
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
595 #:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
596 #: The initial state is 'root'.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
597 #: ``new_state`` can be omitted to signify no state transition.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
598 #: If it is a string, the state is pushed on the stack and changed.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
599 #: If it is a tuple of strings, all states are pushed on the stack and
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
600 #: the current state will be the topmost.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
601 #: It can also be ``combined('state1', 'state2', ...)``
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
602 #: to signify a new, anonymous state combined from the rules of two
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
603 #: or more existing ones.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
604 #: Furthermore, it can be '#pop' to signify going back one step in
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
605 #: the state stack, or '#push' to push the current state on the stack
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
606 #: again.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
607 #:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
608 #: The tuple can also be replaced with ``include('state')``, in which
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
609 #: case the rules from the state named by the string are included in the
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
610 #: current one.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
611 tokens = {}
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
612
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
613 def get_tokens_unprocessed(self, text, stack=('root',)):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
614 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
615 Split ``text`` into (tokentype, text) pairs.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
616
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
617 ``stack`` is the inital stack (default: ``['root']``)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
618 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
619 pos = 0
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
620 tokendefs = self._tokens
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
621 statestack = list(stack)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
622 statetokens = tokendefs[statestack[-1]]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
623 while 1:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
624 for rexmatch, action, new_state in statetokens:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
625 m = rexmatch(text, pos)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
626 if m:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
627 if action is not None:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
628 if type(action) is _TokenType:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
629 yield pos, action, m.group()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
630 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
631 yield from action(self, m)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
632 pos = m.end()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
633 if new_state is not None:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
634 # state transition
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
635 if isinstance(new_state, tuple):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
636 for state in new_state:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
637 if state == '#pop':
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
638 if len(statestack) > 1:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
639 statestack.pop()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
640 elif state == '#push':
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
641 statestack.append(statestack[-1])
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
642 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
643 statestack.append(state)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
644 elif isinstance(new_state, int):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
645 # pop, but keep at least one state on the stack
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
646 # (random code leading to unexpected pops should
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
647 # not allow exceptions)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
648 if abs(new_state) >= len(statestack):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
649 del statestack[1:]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
650 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
651 del statestack[new_state:]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
652 elif new_state == '#push':
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
653 statestack.append(statestack[-1])
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
654 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
655 assert False, "wrong state def: %r" % new_state
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
656 statetokens = tokendefs[statestack[-1]]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
657 break
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
658 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
659 # We are here only if all state tokens have been considered
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
660 # and there was not a match on any of them.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
661 try:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
662 if text[pos] == '\n':
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
663 # at EOL, reset state to "root"
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
664 statestack = ['root']
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
665 statetokens = tokendefs['root']
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
666 yield pos, Text, '\n'
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
667 pos += 1
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
668 continue
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
669 yield pos, Error, text[pos]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
670 pos += 1
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
671 except IndexError:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
672 break
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
673
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
674
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
675 class LexerContext:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
676 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
677 A helper object that holds lexer position data.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
678 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
679
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
680 def __init__(self, text, pos, stack=None, end=None):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
681 self.text = text
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
682 self.pos = pos
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
683 self.end = end or len(text) # end=0 not supported ;-)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
684 self.stack = stack or ['root']
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
685
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
686 def __repr__(self):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
687 return 'LexerContext(%r, %r, %r)' % (
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
688 self.text, self.pos, self.stack)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
689
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
690
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
691 class ExtendedRegexLexer(RegexLexer):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
692 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
693 A RegexLexer that uses a context object to store its state.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
694 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
695
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
696 def get_tokens_unprocessed(self, text=None, context=None):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
697 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
698 Split ``text`` into (tokentype, text) pairs.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
699 If ``context`` is given, use this lexer context instead.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
700 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
701 tokendefs = self._tokens
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
702 if not context:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
703 ctx = LexerContext(text, 0)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
704 statetokens = tokendefs['root']
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
705 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
706 ctx = context
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
707 statetokens = tokendefs[ctx.stack[-1]]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
708 text = ctx.text
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
709 while 1:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
710 for rexmatch, action, new_state in statetokens:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
711 m = rexmatch(text, ctx.pos, ctx.end)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
712 if m:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
713 if action is not None:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
714 if type(action) is _TokenType:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
715 yield ctx.pos, action, m.group()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
716 ctx.pos = m.end()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
717 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
718 yield from action(self, m, ctx)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
719 if not new_state:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
720 # altered the state stack?
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
721 statetokens = tokendefs[ctx.stack[-1]]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
722 # CAUTION: callback must set ctx.pos!
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
723 if new_state is not None:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
724 # state transition
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
725 if isinstance(new_state, tuple):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
726 for state in new_state:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
727 if state == '#pop':
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
728 if len(ctx.stack) > 1:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
729 ctx.stack.pop()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
730 elif state == '#push':
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
731 ctx.stack.append(ctx.stack[-1])
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
732 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
733 ctx.stack.append(state)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
734 elif isinstance(new_state, int):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
735 # see RegexLexer for why this check is made
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
736 if abs(new_state) >= len(ctx.stack):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
737 del ctx.state[1:]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
738 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
739 del ctx.stack[new_state:]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
740 elif new_state == '#push':
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
741 ctx.stack.append(ctx.stack[-1])
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
742 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
743 assert False, "wrong state def: %r" % new_state
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
744 statetokens = tokendefs[ctx.stack[-1]]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
745 break
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
746 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
747 try:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
748 if ctx.pos >= ctx.end:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
749 break
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
750 if text[ctx.pos] == '\n':
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
751 # at EOL, reset state to "root"
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
752 ctx.stack = ['root']
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
753 statetokens = tokendefs['root']
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
754 yield ctx.pos, Text, '\n'
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
755 ctx.pos += 1
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
756 continue
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
757 yield ctx.pos, Error, text[ctx.pos]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
758 ctx.pos += 1
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
759 except IndexError:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
760 break
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
761
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
762
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
763 def do_insertions(insertions, tokens):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
764 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
765 Helper for lexers which must combine the results of several
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
766 sublexers.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
767
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
768 ``insertions`` is a list of ``(index, itokens)`` pairs.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
769 Each ``itokens`` iterable should be inserted at position
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
770 ``index`` into the token stream given by the ``tokens``
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
771 argument.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
772
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
773 The result is a combined token stream.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
774
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
775 TODO: clean up the code here.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
776 """
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
777 insertions = iter(insertions)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
778 try:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
779 index, itokens = next(insertions)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
780 except StopIteration:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
781 # no insertions
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
782 yield from tokens
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
783 return
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
784
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
785 realpos = None
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
786 insleft = True
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
787
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
788 # iterate over the token stream where we want to insert
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
789 # the tokens from the insertion list.
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
790 for i, t, v in tokens:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
791 # first iteration. store the postition of first item
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
792 if realpos is None:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
793 realpos = i
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
794 oldi = 0
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
795 while insleft and i + len(v) >= index:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
796 tmpval = v[oldi:index - i]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
797 if tmpval:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
798 yield realpos, t, tmpval
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
799 realpos += len(tmpval)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
800 for it_index, it_token, it_value in itokens:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
801 yield realpos, it_token, it_value
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
802 realpos += len(it_value)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
803 oldi = index - i
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
804 try:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
805 index, itokens = next(insertions)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
806 except StopIteration:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
807 insleft = False
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
808 break # not strictly necessary
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
809 if oldi < len(v):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
810 yield realpos, t, v[oldi:]
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
811 realpos += len(v) - oldi
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
812
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
813 # leftover tokens
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
814 while insleft:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
815 # no normal tokens, set realpos to zero
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
816 realpos = realpos or 0
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
817 for p, t, v in itokens:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
818 yield realpos, t, v
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
819 realpos += len(v)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
820 try:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
821 index, itokens = next(insertions)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
822 except StopIteration:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
823 insleft = False
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
824 break # not strictly necessary
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
825
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
826
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
827 class ProfilingRegexLexerMeta(RegexLexerMeta):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
828 """Metaclass for ProfilingRegexLexer, collects regex timing info."""
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
829
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
830 def _process_regex(cls, regex, rflags, state):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
831 if isinstance(regex, words):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
832 rex = regex_opt(regex.words, prefix=regex.prefix,
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
833 suffix=regex.suffix)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
834 else:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
835 rex = regex
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
836 compiled = re.compile(rex, rflags)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
837
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
838 def match_func(text, pos, endpos=sys.maxsize):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
839 info = cls._prof_data[-1].setdefault((state, rex), [0, 0.0])
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
840 t0 = time.time()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
841 res = compiled.match(text, pos, endpos)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
842 t1 = time.time()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
843 info[0] += 1
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
844 info[1] += t1 - t0
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
845 return res
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
846 return match_func
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
847
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
848
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
849 class ProfilingRegexLexer(RegexLexer, metaclass=ProfilingRegexLexerMeta):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
850 """Drop-in replacement for RegexLexer that does profiling of its regexes."""
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
851
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
852 _prof_data = []
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
853 _prof_sort_index = 4 # defaults to time per call
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
854
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
855 def get_tokens_unprocessed(self, text, stack=('root',)):
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
856 # this needs to be a stack, since using(this) will produce nested calls
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
857 self.__class__._prof_data.append({})
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
858 yield from RegexLexer.get_tokens_unprocessed(self, text, stack)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
859 rawdata = self.__class__._prof_data.pop()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
860 data = sorted(((s, repr(r).strip('u\'').replace('\\\\', '\\')[:65],
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
861 n, 1000 * t, 1000 * t / n)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
862 for ((s, r), (n, t)) in rawdata.items()),
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
863 key=lambda x: x[self._prof_sort_index],
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
864 reverse=True)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
865 sum_total = sum(x[3] for x in data)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
866
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
867 print()
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
868 print('Profiling result for %s lexing %d chars in %.3f ms' %
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
869 (self.__class__.__name__, len(text), sum_total))
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
870 print('=' * 110)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
871 print('%-20s %-64s ncalls tottime percall' % ('state', 'regex'))
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
872 print('-' * 110)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
873 for d in data:
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
874 print('%-20s %-65s %5d %8.4f %8.4f' % d)
54c5cfbb1e29 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 7701
diff changeset
875 print('=' * 110)

eric ide

mercurial