Mercurial > hgrepos > Python > libs > pygments-lexer-pseudocode2
comparison pygments_lexer_pseudocode2/lexers/bases.py @ 164:a4317957148b
Move all lexers into a subpackage pygments_lexer_pseudocode2.lexers.
This is to prepare for a new subpackage with filters.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Fri, 08 May 2026 21:19:54 +0200 |
| parents | pygments_lexer_pseudocode2/bases.py@e1663ac707b0 |
| children | afbca50b7dc1 |
comparison
equal
deleted
inserted
replaced
| 163:315cfe0a836f | 164:a4317957148b |
|---|---|
| 1 # -*- coding: utf-8 -*- | |
| 2 # :- | |
| 3 # SPDX-FileCopyrightText: © 2026 Franz Glasner | |
| 4 # SPDX-License-Identifier: MIT | |
| 5 # :- | |
| 6 r"""Some common bases for the lexers.""" | |
| 7 | |
| 8 __all__ = ["LexBase", "uni_name", "py_innerstring_rules", "py_name_rules"] | |
| 9 | |
| 10 | |
| 11 import sys | |
| 12 | |
| 13 from pygments import unistring | |
| 14 from pygments.lexer import RegexLexer, combined, bygroups, include | |
| 15 from pygments.token import (Comment, Error, Name, Number, Other, String) | |
| 16 | |
| 17 | |
| 18 PY2 = sys.version_info[0] <= 2 | |
| 19 | |
| 20 | |
| 21 # | |
| 22 # SPDX-SnippetBegin | |
| 23 # SPDX-License-Identifier: BSD-2-Clause | |
| 24 # SPDX-SnippetCopyrightText: Copyright 2006-2023 by the Pygments team | |
| 25 # SPDX-SnippetCopyrightText: Copyright 2026 by Franz Glasner | |
| 26 # | |
| 27 | |
| 28 uni_name = "[%s][%s]*" % (unistring.xid_start, unistring.xid_continue) | |
| 29 | |
| 30 | |
| 31 """PY3 allows no @staticmethod but PY2 needs it.""" | |
| 32 if PY2: | |
| 33 _staticmethod = staticmethod | |
| 34 else: | |
| 35 def _staticmethod(fn): | |
| 36 return fn | |
| 37 | |
| 38 | |
| 39 def py_innerstring_rules(ttype): | |
| 40 return [ | |
| 41 # the old style '%s' % (...) string formatting (still valid in Py3) | |
| 42 (r'%(\(\w+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?' | |
| 43 '[hlL]?[E-GXc-giorsaux%]', String.Interpol), | |
| 44 # the new style '{}'.format(...) string formatting | |
| 45 (r'\{' | |
| 46 r'((\w+)((\.\w+)|(\[[^\]]+\]))*)?' # field name | |
| 47 r'(\![sra])?' # conversion | |
| 48 r'(\:(.?[<>=\^])?[-+ ]?#?0?(\d+)?,?(\.\d+)?[E-GXb-gnosx%]?)?' | |
| 49 r'\}', String.Interpol), | |
| 50 # | |
| 51 # backslashes, quotes and formatting signs must be parsed | |
| 52 # one at a time | |
| 53 # | |
| 54 (r'[^\\\'"%{\n]+', ttype), | |
| 55 (r'[\'"\\]', ttype), | |
| 56 # unhandled string formatting sign | |
| 57 (r'%|(\{{1,2})', ttype) | |
| 58 # newlines are an error (use "nl" state) | |
| 59 ] | |
| 60 | |
| 61 | |
| 62 def py_name_rules(ttype, deco_ttype=Name.Decorator): | |
| 63 return [ | |
| 64 # We recognize decorator syntax here | |
| 65 (r'@' + uni_name, deco_ttype), | |
| 66 # | |
| 67 # Python's new matrix multiplication operator: | |
| 68 # not used here in pseudocode | |
| 69 # (r'@', Operator), | |
| 70 (uni_name, ttype), | |
| 71 ] | |
| 72 | |
| 73 # SPDX-SnippetEnd | |
| 74 | |
| 75 | |
| 76 class LexBase(RegexLexer): | |
| 77 | |
| 78 """A base that defines some common lexer states. | |
| 79 | |
| 80 Default flags are not important. | |
| 81 | |
| 82 """ | |
| 83 | |
| 84 def op_ignore(lexer, match, ctx=None): | |
| 85 """Unconditionally ignore the match.""" | |
| 86 if False: | |
| 87 yield match.start(), Other, "" | |
| 88 if ctx: | |
| 89 ctx.pos = match.end() | |
| 90 | |
| 91 @_staticmethod | |
| 92 def op_fixed(toktype, value): | |
| 93 """Unconditionally yield a given token type and value.""" | |
| 94 | |
| 95 def _op_fixed(lexer, match, ctx=None): | |
| 96 yield match.start(), toktype, value | |
| 97 if ctx: | |
| 98 ctx.pos = match.end() | |
| 99 | |
| 100 return _op_fixed | |
| 101 | |
| 102 tokens = { | |
| 103 # | |
| 104 # These states are borrowed from Pygment's Python lexer. | |
| 105 # Their names have been prefixed with `py-'. | |
| 106 # | |
| 107 # SPDX-SnippetBegin | |
| 108 # SPDX-License-Identifier: BSD-2-Clause | |
| 109 # SPDX-SnippetCopyrightText: Copyright 2006-2023 by the Pygments team | |
| 110 # SPDX-SnippetCopyrightText: Copyright 2026 by Franz Glasner | |
| 111 # | |
| 112 'py-numbers': [ | |
| 113 (r'(\d(?:_?\d)*\.(?:\d(?:_?\d)*)?|(?:\d(?:_?\d)*)?\.\d(?:_?\d)*)' | |
| 114 r'([eE][+-]?\d(?:_?\d)*)?', Number.Float), | |
| 115 (r'\d(?:_?\d)*[eE][+-]?\d(?:_?\d)*j?', Number.Float), | |
| 116 (r'0[oO](?:_?[0-7])+', Number.Oct), | |
| 117 (r'0[bB](?:_?[01])+', Number.Bin), | |
| 118 (r'0[xX](?:_?[a-fA-F0-9])+', Number.Hex), | |
| 119 (r'\d(?:_?\d)*', Number.Integer), | |
| 120 ], | |
| 121 'py-strings': [ | |
| 122 # non-raw strings | |
| 123 ('([uU]?)(""")', bygroups(String.Affix, String.Double), | |
| 124 combined('py-stringescape', 'py-tdqs')), | |
| 125 ("([uU]?)(''')", bygroups(String.Affix, String.Single), | |
| 126 combined('py-stringescape', 'py-tsqs')), | |
| 127 ('([uU]?)(")', bygroups(String.Affix, String.Double), | |
| 128 combined('py-stringescape', 'py-dqs')), | |
| 129 ("([uU]?)(')", bygroups(String.Affix, String.Single), | |
| 130 combined('py-stringescape', 'py-sqs')), | |
| 131 # non-raw bytes | |
| 132 ('([bB])(""")', bygroups(String.Affix, String.Double), | |
| 133 combined('py-bytesescape', 'py-tdqs')), | |
| 134 ("([bB])(''')", bygroups(String.Affix, String.Single), | |
| 135 combined('py-bytesescape', 'py-tsqs')), | |
| 136 ('([bB])(")', bygroups(String.Affix, String.Double), | |
| 137 combined('py-bytesescape', 'py-dqs')), | |
| 138 ("([bB])(')", bygroups(String.Affix, String.Single), | |
| 139 combined('py-bytesescape', 'py-sqs')), | |
| 140 ], | |
| 141 'py-stringescape': [ | |
| 142 (r'\\(N\{.*?\}|u[a-fA-F0-9]{4}|U[a-fA-F0-9]{8})', String.Escape), | |
| 143 include('py-bytesescape') | |
| 144 ], | |
| 145 'py-bytesescape': [ | |
| 146 (r'\\([\\abfnrtv"\']|\n|x[a-fA-F0-9]{2}|[0-7]{1,3})', | |
| 147 String.Escape) | |
| 148 ], | |
| 149 'py-dqs': [ | |
| 150 (r'"', String.Double, '#pop'), | |
| 151 (r'\\\\|\\"|\\\n', String.Escape), # included here for raw strings | |
| 152 include('py-strings-double'), | |
| 153 (r'\n', Error), # added by fag | |
| 154 ], | |
| 155 'py-sqs': [ | |
| 156 (r"'", String.Single, '#pop'), | |
| 157 (r"\\\\|\\'|\\\n", String.Escape), # included here for raw strings | |
| 158 include('py-strings-single'), | |
| 159 (r'\n', Error), # added by fag | |
| 160 ], | |
| 161 'py-tdqs': [ | |
| 162 (r'"""', String.Double, '#pop'), | |
| 163 include('py-strings-double'), | |
| 164 (r'\n', String.Double) | |
| 165 ], | |
| 166 'py-tsqs': [ | |
| 167 (r"'''", String.Single, '#pop'), | |
| 168 include('py-strings-single'), | |
| 169 (r'\n', String.Single) | |
| 170 ], | |
| 171 'py-strings-single': py_innerstring_rules(String.Single), | |
| 172 'py-strings-double': py_innerstring_rules(String.Double), | |
| 173 'py-name': py_name_rules(Name.Entity), | |
| 174 # SPDX-SnippetEnd | |
| 175 # This snippet is from the Pygments' documentation "Write your own lexer" | |
| 176 'multiline-nested-comment': [ | |
| 177 (r'[^*/]+', Comment.Multiline), | |
| 178 (r'/\*', Comment.Multiline, '#push'), | |
| 179 (r'\*/', Comment.Multiline, '#pop'), | |
| 180 (r'[*/]', Comment.Multiline), | |
| 181 ], | |
| 182 'multiline-nested-comment-alt': [ | |
| 183 (r'[^*()]+', Comment.Multiline), | |
| 184 (r'\(\*', Comment.Multiline, '#push'), | |
| 185 (r'\*\)', Comment.Multiline, '#pop'), | |
| 186 (r'[*()]', Comment.Multiline), | |
| 187 ] | |
| 188 } |
