|
1 # -*- coding: utf-8 -*- |
|
2 """ |
|
3 pygments.lexers.pawn |
|
4 ~~~~~~~~~~~~~~~~~~~~ |
|
5 |
|
6 Lexers for the Pawn languages. |
|
7 |
|
8 :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS. |
|
9 :license: BSD, see LICENSE for details. |
|
10 """ |
|
11 |
|
12 from pygments.lexer import RegexLexer |
|
13 from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ |
|
14 Number, Punctuation, Error |
|
15 from pygments.util import get_bool_opt |
|
16 |
|
17 __all__ = ['SourcePawnLexer', 'PawnLexer'] |
|
18 |
|
19 |
|
20 class SourcePawnLexer(RegexLexer): |
|
21 """ |
|
22 For SourcePawn source code with preprocessor directives. |
|
23 |
|
24 .. versionadded:: 1.6 |
|
25 """ |
|
26 name = 'SourcePawn' |
|
27 aliases = ['sp'] |
|
28 filenames = ['*.sp'] |
|
29 mimetypes = ['text/x-sourcepawn'] |
|
30 |
|
31 #: optional Comment or Whitespace |
|
32 _ws = r'(?:\s|//.*?\n|/\*.*?\*/)+' |
|
33 #: only one /* */ style comment |
|
34 _ws1 = r'\s*(?:/[*].*?[*]/\s*)*' |
|
35 |
|
36 tokens = { |
|
37 'root': [ |
|
38 # preprocessor directives: without whitespace |
|
39 ('^#if\s+0', Comment.Preproc, 'if0'), |
|
40 ('^#', Comment.Preproc, 'macro'), |
|
41 # or with whitespace |
|
42 ('^' + _ws1 + r'#if\s+0', Comment.Preproc, 'if0'), |
|
43 ('^' + _ws1 + '#', Comment.Preproc, 'macro'), |
|
44 (r'\n', Text), |
|
45 (r'\s+', Text), |
|
46 (r'\\\n', Text), # line continuation |
|
47 (r'/(\\\n)?/(\n|(.|\n)*?[^\\]\n)', Comment.Single), |
|
48 (r'/(\\\n)?\*(.|\n)*?\*(\\\n)?/', Comment.Multiline), |
|
49 (r'[{}]', Punctuation), |
|
50 (r'L?"', String, 'string'), |
|
51 (r"L?'(\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\\'\n])'", String.Char), |
|
52 (r'(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+[LlUu]*', Number.Float), |
|
53 (r'(\d+\.\d*|\.\d+|\d+[fF])[fF]?', Number.Float), |
|
54 (r'0x[0-9a-fA-F]+[LlUu]*', Number.Hex), |
|
55 (r'0[0-7]+[LlUu]*', Number.Oct), |
|
56 (r'\d+[LlUu]*', Number.Integer), |
|
57 (r'\*/', Error), |
|
58 (r'[~!%^&*+=|?:<>/-]', Operator), |
|
59 (r'[()\[\],.;]', Punctuation), |
|
60 (r'(case|const|continue|native|' |
|
61 r'default|else|enum|for|if|new|operator|' |
|
62 r'public|return|sizeof|static|decl|struct|switch)\b', Keyword), |
|
63 (r'(bool|Float)\b', Keyword.Type), |
|
64 (r'(true|false)\b', Keyword.Constant), |
|
65 ('[a-zA-Z_]\w*', Name), |
|
66 ], |
|
67 'string': [ |
|
68 (r'"', String, '#pop'), |
|
69 (r'\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})', String.Escape), |
|
70 (r'[^\\"\n]+', String), # all other characters |
|
71 (r'\\\n', String), # line continuation |
|
72 (r'\\', String), # stray backslash |
|
73 ], |
|
74 'macro': [ |
|
75 (r'[^/\n]+', Comment.Preproc), |
|
76 (r'/\*(.|\n)*?\*/', Comment.Multiline), |
|
77 (r'//.*?\n', Comment.Single, '#pop'), |
|
78 (r'/', Comment.Preproc), |
|
79 (r'(?<=\\)\n', Comment.Preproc), |
|
80 (r'\n', Comment.Preproc, '#pop'), |
|
81 ], |
|
82 'if0': [ |
|
83 (r'^\s*#if.*?(?<!\\)\n', Comment.Preproc, '#push'), |
|
84 (r'^\s*#endif.*?(?<!\\)\n', Comment.Preproc, '#pop'), |
|
85 (r'.*?\n', Comment), |
|
86 ] |
|
87 } |
|
88 |
|
89 SM_TYPES = set(('Action', 'bool', 'Float', 'Plugin', 'String', 'any', |
|
90 'AdminFlag', 'OverrideType', 'OverrideRule', 'ImmunityType', |
|
91 'GroupId', 'AdminId', 'AdmAccessMode', 'AdminCachePart', |
|
92 'CookieAccess', 'CookieMenu', 'CookieMenuAction', 'NetFlow', |
|
93 'ConVarBounds', 'QueryCookie', 'ReplySource', |
|
94 'ConVarQueryResult', 'ConVarQueryFinished', 'Function', |
|
95 'Action', 'Identity', 'PluginStatus', 'PluginInfo', 'DBResult', |
|
96 'DBBindType', 'DBPriority', 'PropType', 'PropFieldType', |
|
97 'MoveType', 'RenderMode', 'RenderFx', 'EventHookMode', |
|
98 'EventHook', 'FileType', 'FileTimeMode', 'PathType', |
|
99 'ParamType', 'ExecType', 'DialogType', 'Handle', 'KvDataTypes', |
|
100 'NominateResult', 'MapChange', 'MenuStyle', 'MenuAction', |
|
101 'MenuSource', 'RegexError', 'SDKCallType', 'SDKLibrary', |
|
102 'SDKFuncConfSource', 'SDKType', 'SDKPassMethod', 'RayType', |
|
103 'TraceEntityFilter', 'ListenOverride', 'SortOrder', 'SortType', |
|
104 'SortFunc2D', 'APLRes', 'FeatureType', 'FeatureStatus', |
|
105 'SMCResult', 'SMCError', 'TFClassType', 'TFTeam', 'TFCond', |
|
106 'TFResourceType', 'Timer', 'TopMenuAction', 'TopMenuObjectType', |
|
107 'TopMenuPosition', 'TopMenuObject', 'UserMsg')) |
|
108 |
|
109 def __init__(self, **options): |
|
110 self.smhighlighting = get_bool_opt(options, |
|
111 'sourcemod', True) |
|
112 |
|
113 self._functions = set() |
|
114 if self.smhighlighting: |
|
115 from pygments.lexers._sourcemod_builtins import FUNCTIONS |
|
116 self._functions.update(FUNCTIONS) |
|
117 RegexLexer.__init__(self, **options) |
|
118 |
|
119 def get_tokens_unprocessed(self, text): |
|
120 for index, token, value in \ |
|
121 RegexLexer.get_tokens_unprocessed(self, text): |
|
122 if token is Name: |
|
123 if self.smhighlighting: |
|
124 if value in self.SM_TYPES: |
|
125 token = Keyword.Type |
|
126 elif value in self._functions: |
|
127 token = Name.Builtin |
|
128 yield index, token, value |
|
129 |
|
130 |
|
131 class PawnLexer(RegexLexer): |
|
132 """ |
|
133 For Pawn source code. |
|
134 |
|
135 .. versionadded:: 2.0 |
|
136 """ |
|
137 |
|
138 name = 'Pawn' |
|
139 aliases = ['pawn'] |
|
140 filenames = ['*.p', '*.pwn', '*.inc'] |
|
141 mimetypes = ['text/x-pawn'] |
|
142 |
|
143 #: optional Comment or Whitespace |
|
144 _ws = r'(?:\s|//.*?\n|/[*][\w\W]*?[*]/)+' |
|
145 #: only one /* */ style comment |
|
146 _ws1 = r'\s*(?:/[*].*?[*]/\s*)*' |
|
147 |
|
148 tokens = { |
|
149 'root': [ |
|
150 # preprocessor directives: without whitespace |
|
151 ('^#if\s+0', Comment.Preproc, 'if0'), |
|
152 ('^#', Comment.Preproc, 'macro'), |
|
153 # or with whitespace |
|
154 ('^' + _ws1 + r'#if\s+0', Comment.Preproc, 'if0'), |
|
155 ('^' + _ws1 + '#', Comment.Preproc, 'macro'), |
|
156 (r'\n', Text), |
|
157 (r'\s+', Text), |
|
158 (r'\\\n', Text), # line continuation |
|
159 (r'/(\\\n)?/(\n|(.|\n)*?[^\\]\n)', Comment.Single), |
|
160 (r'/(\\\n)?\*[\w\W]*?\*(\\\n)?/', Comment.Multiline), |
|
161 (r'[{}]', Punctuation), |
|
162 (r'L?"', String, 'string'), |
|
163 (r"L?'(\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\\'\n])'", String.Char), |
|
164 (r'(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+[LlUu]*', Number.Float), |
|
165 (r'(\d+\.\d*|\.\d+|\d+[fF])[fF]?', Number.Float), |
|
166 (r'0x[0-9a-fA-F]+[LlUu]*', Number.Hex), |
|
167 (r'0[0-7]+[LlUu]*', Number.Oct), |
|
168 (r'\d+[LlUu]*', Number.Integer), |
|
169 (r'\*/', Error), |
|
170 (r'[~!%^&*+=|?:<>/-]', Operator), |
|
171 (r'[()\[\],.;]', Punctuation), |
|
172 (r'(switch|case|default|const|new|static|char|continue|break|' |
|
173 r'if|else|for|while|do|operator|enum|' |
|
174 r'public|return|sizeof|tagof|state|goto)\b', Keyword), |
|
175 (r'(bool|Float)\b', Keyword.Type), |
|
176 (r'(true|false)\b', Keyword.Constant), |
|
177 ('[a-zA-Z_]\w*', Name), |
|
178 ], |
|
179 'string': [ |
|
180 (r'"', String, '#pop'), |
|
181 (r'\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})', String.Escape), |
|
182 (r'[^\\"\n]+', String), # all other characters |
|
183 (r'\\\n', String), # line continuation |
|
184 (r'\\', String), # stray backslash |
|
185 ], |
|
186 'macro': [ |
|
187 (r'[^/\n]+', Comment.Preproc), |
|
188 (r'/\*(.|\n)*?\*/', Comment.Multiline), |
|
189 (r'//.*?\n', Comment.Single, '#pop'), |
|
190 (r'/', Comment.Preproc), |
|
191 (r'(?<=\\)\n', Comment.Preproc), |
|
192 (r'\n', Comment.Preproc, '#pop'), |
|
193 ], |
|
194 'if0': [ |
|
195 (r'^\s*#if.*?(?<!\\)\n', Comment.Preproc, '#push'), |
|
196 (r'^\s*#endif.*?(?<!\\)\n', Comment.Preproc, '#pop'), |
|
197 (r'.*?\n', Comment), |
|
198 ] |
|
199 } |