eric6/ThirdParty/Pygments/pygments/lexers/scripting.py

changeset 6942
2602857055c5
parent 6651
e8f3b5568b21
child 7547
21b0534faebc
equal deleted inserted replaced
6941:f99d60d6b59b 6942:2602857055c5
1 # -*- coding: utf-8 -*-
2 """
3 pygments.lexers.scripting
4 ~~~~~~~~~~~~~~~~~~~~~~~~~
5
6 Lexer for scripting and embedded languages.
7
8 :copyright: Copyright 2006-2017 by the Pygments team, see AUTHORS.
9 :license: BSD, see LICENSE for details.
10 """
11
12 import re
13
14 from pygments.lexer import RegexLexer, include, bygroups, default, combined, \
15 words
16 from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
17 Number, Punctuation, Error, Whitespace, Other
18 from pygments.util import get_bool_opt, get_list_opt, iteritems
19
20 __all__ = ['LuaLexer', 'MoonScriptLexer', 'ChaiscriptLexer', 'LSLLexer',
21 'AppleScriptLexer', 'RexxLexer', 'MOOCodeLexer', 'HybrisLexer',
22 'EasytrieveLexer', 'JclLexer']
23
24
25 class LuaLexer(RegexLexer):
26 """
27 For `Lua <http://www.lua.org>`_ source code.
28
29 Additional options accepted:
30
31 `func_name_highlighting`
32 If given and ``True``, highlight builtin function names
33 (default: ``True``).
34 `disabled_modules`
35 If given, must be a list of module names whose function names
36 should not be highlighted. By default all modules are highlighted.
37
38 To get a list of allowed modules have a look into the
39 `_lua_builtins` module:
40
41 .. sourcecode:: pycon
42
43 >>> from pygments.lexers._lua_builtins import MODULES
44 >>> MODULES.keys()
45 ['string', 'coroutine', 'modules', 'io', 'basic', ...]
46 """
47
48 name = 'Lua'
49 aliases = ['lua']
50 filenames = ['*.lua', '*.wlua']
51 mimetypes = ['text/x-lua', 'application/x-lua']
52
53 _comment_multiline = r'(?:--\[(?P<level>=*)\[[\w\W]*?\](?P=level)\])'
54 _comment_single = r'(?:--.*$)'
55 _space = r'(?:\s+)'
56 _s = r'(?:%s|%s|%s)' % (_comment_multiline, _comment_single, _space)
57 _name = r'(?:[^\W\d]\w*)'
58
59 tokens = {
60 'root': [
61 # Lua allows a file to start with a shebang.
62 (r'#!.*', Comment.Preproc),
63 default('base'),
64 ],
65 'ws': [
66 (_comment_multiline, Comment.Multiline),
67 (_comment_single, Comment.Single),
68 (_space, Text),
69 ],
70 'base': [
71 include('ws'),
72
73 (r'(?i)0x[\da-f]*(\.[\da-f]*)?(p[+-]?\d+)?', Number.Hex),
74 (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number.Float),
75 (r'(?i)\d+e[+-]?\d+', Number.Float),
76 (r'\d+', Number.Integer),
77
78 # multiline strings
79 (r'(?s)\[(=*)\[.*?\]\1\]', String),
80
81 (r'::', Punctuation, 'label'),
82 (r'\.{3}', Punctuation),
83 (r'[=<>|~&+\-*/%#^]+|\.\.', Operator),
84 (r'[\[\]{}().,:;]', Punctuation),
85 (r'(and|or|not)\b', Operator.Word),
86
87 ('(break|do|else|elseif|end|for|if|in|repeat|return|then|until|'
88 r'while)\b', Keyword.Reserved),
89 (r'goto\b', Keyword.Reserved, 'goto'),
90 (r'(local)\b', Keyword.Declaration),
91 (r'(true|false|nil)\b', Keyword.Constant),
92
93 (r'(function)\b', Keyword.Reserved, 'funcname'),
94
95 (r'[A-Za-z_]\w*(\.[A-Za-z_]\w*)?', Name),
96
97 ("'", String.Single, combined('stringescape', 'sqs')),
98 ('"', String.Double, combined('stringescape', 'dqs'))
99 ],
100
101 'funcname': [
102 include('ws'),
103 (r'[.:]', Punctuation),
104 (r'%s(?=%s*[.:])' % (_name, _s), Name.Class),
105 (_name, Name.Function, '#pop'),
106 # inline function
107 (r'\(', Punctuation, '#pop'),
108 ],
109
110 'goto': [
111 include('ws'),
112 (_name, Name.Label, '#pop'),
113 ],
114
115 'label': [
116 include('ws'),
117 (r'::', Punctuation, '#pop'),
118 (_name, Name.Label),
119 ],
120
121 'stringescape': [
122 (r'\\([abfnrtv\\"\']|[\r\n]{1,2}|z\s*|x[0-9a-fA-F]{2}|\d{1,3}|'
123 r'u\{[0-9a-fA-F]+\})', String.Escape),
124 ],
125
126 'sqs': [
127 (r"'", String.Single, '#pop'),
128 (r"[^\\']+", String.Single),
129 ],
130
131 'dqs': [
132 (r'"', String.Double, '#pop'),
133 (r'[^\\"]+', String.Double),
134 ]
135 }
136
137 def __init__(self, **options):
138 self.func_name_highlighting = get_bool_opt(
139 options, 'func_name_highlighting', True)
140 self.disabled_modules = get_list_opt(options, 'disabled_modules', [])
141
142 self._functions = set()
143 if self.func_name_highlighting:
144 from pygments.lexers._lua_builtins import MODULES
145 for mod, func in iteritems(MODULES):
146 if mod not in self.disabled_modules:
147 self._functions.update(func)
148 RegexLexer.__init__(self, **options)
149
150 def get_tokens_unprocessed(self, text):
151 for index, token, value in \
152 RegexLexer.get_tokens_unprocessed(self, text):
153 if token is Name:
154 if value in self._functions:
155 yield index, Name.Builtin, value
156 continue
157 elif '.' in value:
158 a, b = value.split('.')
159 yield index, Name, a
160 yield index + len(a), Punctuation, u'.'
161 yield index + len(a) + 1, Name, b
162 continue
163 yield index, token, value
164
165
166 class MoonScriptLexer(LuaLexer):
167 """
168 For `MoonScript <http://moonscript.org>`_ source code.
169
170 .. versionadded:: 1.5
171 """
172
173 name = "MoonScript"
174 aliases = ["moon", "moonscript"]
175 filenames = ["*.moon"]
176 mimetypes = ['text/x-moonscript', 'application/x-moonscript']
177
178 tokens = {
179 'root': [
180 (r'#!(.*?)$', Comment.Preproc),
181 default('base'),
182 ],
183 'base': [
184 ('--.*$', Comment.Single),
185 (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number.Float),
186 (r'(?i)\d+e[+-]?\d+', Number.Float),
187 (r'(?i)0x[0-9a-f]*', Number.Hex),
188 (r'\d+', Number.Integer),
189 (r'\n', Text),
190 (r'[^\S\n]+', Text),
191 (r'(?s)\[(=*)\[.*?\]\1\]', String),
192 (r'(->|=>)', Name.Function),
193 (r':[a-zA-Z_]\w*', Name.Variable),
194 (r'(==|!=|~=|<=|>=|\.\.\.|\.\.|[=+\-*/%^<>#!.\\:])', Operator),
195 (r'[;,]', Punctuation),
196 (r'[\[\]{}()]', Keyword.Type),
197 (r'[a-zA-Z_]\w*:', Name.Variable),
198 (words((
199 'class', 'extends', 'if', 'then', 'super', 'do', 'with',
200 'import', 'export', 'while', 'elseif', 'return', 'for', 'in',
201 'from', 'when', 'using', 'else', 'and', 'or', 'not', 'switch',
202 'break'), suffix=r'\b'),
203 Keyword),
204 (r'(true|false|nil)\b', Keyword.Constant),
205 (r'(and|or|not)\b', Operator.Word),
206 (r'(self)\b', Name.Builtin.Pseudo),
207 (r'@@?([a-zA-Z_]\w*)?', Name.Variable.Class),
208 (r'[A-Z]\w*', Name.Class), # proper name
209 (r'[A-Za-z_]\w*(\.[A-Za-z_]\w*)?', Name),
210 ("'", String.Single, combined('stringescape', 'sqs')),
211 ('"', String.Double, combined('stringescape', 'dqs'))
212 ],
213 'stringescape': [
214 (r'''\\([abfnrtv\\"']|\d{1,3})''', String.Escape)
215 ],
216 'sqs': [
217 ("'", String.Single, '#pop'),
218 (".", String)
219 ],
220 'dqs': [
221 ('"', String.Double, '#pop'),
222 (".", String)
223 ]
224 }
225
226 def get_tokens_unprocessed(self, text):
227 # set . as Operator instead of Punctuation
228 for index, token, value in LuaLexer.get_tokens_unprocessed(self, text):
229 if token == Punctuation and value == ".":
230 token = Operator
231 yield index, token, value
232
233
234 class ChaiscriptLexer(RegexLexer):
235 """
236 For `ChaiScript <http://chaiscript.com/>`_ source code.
237
238 .. versionadded:: 2.0
239 """
240
241 name = 'ChaiScript'
242 aliases = ['chai', 'chaiscript']
243 filenames = ['*.chai']
244 mimetypes = ['text/x-chaiscript', 'application/x-chaiscript']
245
246 flags = re.DOTALL | re.MULTILINE
247
248 tokens = {
249 'commentsandwhitespace': [
250 (r'\s+', Text),
251 (r'//.*?\n', Comment.Single),
252 (r'/\*.*?\*/', Comment.Multiline),
253 (r'^\#.*?\n', Comment.Single)
254 ],
255 'slashstartsregex': [
256 include('commentsandwhitespace'),
257 (r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
258 r'([gim]+\b|\B)', String.Regex, '#pop'),
259 (r'(?=/)', Text, ('#pop', 'badregex')),
260 default('#pop')
261 ],
262 'badregex': [
263 (r'\n', Text, '#pop')
264 ],
265 'root': [
266 include('commentsandwhitespace'),
267 (r'\n', Text),
268 (r'[^\S\n]+', Text),
269 (r'\+\+|--|~|&&|\?|:|\|\||\\(?=\n)|\.\.'
270 r'(<<|>>>?|==?|!=?|[-<>+*%&|^/])=?', Operator, 'slashstartsregex'),
271 (r'[{(\[;,]', Punctuation, 'slashstartsregex'),
272 (r'[})\].]', Punctuation),
273 (r'[=+\-*/]', Operator),
274 (r'(for|in|while|do|break|return|continue|if|else|'
275 r'throw|try|catch'
276 r')\b', Keyword, 'slashstartsregex'),
277 (r'(var)\b', Keyword.Declaration, 'slashstartsregex'),
278 (r'(attr|def|fun)\b', Keyword.Reserved),
279 (r'(true|false)\b', Keyword.Constant),
280 (r'(eval|throw)\b', Name.Builtin),
281 (r'`\S+`', Name.Builtin),
282 (r'[$a-zA-Z_]\w*', Name.Other),
283 (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
284 (r'0x[0-9a-fA-F]+', Number.Hex),
285 (r'[0-9]+', Number.Integer),
286 (r'"', String.Double, 'dqstring'),
287 (r"'(\\\\|\\'|[^'])*'", String.Single),
288 ],
289 'dqstring': [
290 (r'\$\{[^"}]+?\}', String.Interpol),
291 (r'\$', String.Double),
292 (r'\\\\', String.Double),
293 (r'\\"', String.Double),
294 (r'[^\\"$]+', String.Double),
295 (r'"', String.Double, '#pop'),
296 ],
297 }
298
299
300 class LSLLexer(RegexLexer):
301 """
302 For Second Life's Linden Scripting Language source code.
303
304 .. versionadded:: 2.0
305 """
306
307 name = 'LSL'
308 aliases = ['lsl']
309 filenames = ['*.lsl']
310 mimetypes = ['text/x-lsl']
311
312 flags = re.MULTILINE
313
314 lsl_keywords = r'\b(?:do|else|for|if|jump|return|while)\b'
315 lsl_types = r'\b(?:float|integer|key|list|quaternion|rotation|string|vector)\b'
316 lsl_states = r'\b(?:(?:state)\s+\w+|default)\b'
317 lsl_events = r'\b(?:state_(?:entry|exit)|touch(?:_(?:start|end))?|(?:land_)?collision(?:_(?:start|end))?|timer|listen|(?:no_)?sensor|control|(?:not_)?at_(?:rot_)?target|money|email|run_time_permissions|changed|attach|dataserver|moving_(?:start|end)|link_message|(?:on|object)_rez|remote_data|http_re(?:sponse|quest)|path_update|transaction_result)\b'
318 lsl_functions_builtin = r'\b(?:ll(?:ReturnObjectsBy(?:ID|Owner)|Json(?:2List|[GS]etValue|ValueType)|Sin|Cos|Tan|Atan2|Sqrt|Pow|Abs|Fabs|Frand|Floor|Ceil|Round|Vec(?:Mag|Norm|Dist)|Rot(?:Between|2(?:Euler|Fwd|Left|Up))|(?:Euler|Axes)2Rot|Whisper|(?:Region|Owner)?Say|Shout|Listen(?:Control|Remove)?|Sensor(?:Repeat|Remove)?|Detected(?:Name|Key|Owner|Type|Pos|Vel|Grab|Rot|Group|LinkNumber)|Die|Ground|Wind|(?:[GS]et)(?:AnimationOverride|MemoryLimit|PrimMediaParams|ParcelMusicURL|Object(?:Desc|Name)|PhysicsMaterial|Status|Scale|Color|Alpha|Texture|Pos|Rot|Force|Torque)|ResetAnimationOverride|(?:Scale|Offset|Rotate)Texture|(?:Rot)?Target(?:Remove)?|(?:Stop)?MoveToTarget|Apply(?:Rotational)?Impulse|Set(?:KeyframedMotion|ContentType|RegionPos|(?:Angular)?Velocity|Buoyancy|HoverHeight|ForceAndTorque|TimerEvent|ScriptState|Damage|TextureAnim|Sound(?:Queueing|Radius)|Vehicle(?:Type|(?:Float|Vector|Rotation)Param)|(?:Touch|Sit)?Text|Camera(?:Eye|At)Offset|PrimitiveParams|ClickAction|Link(?:Alpha|Color|PrimitiveParams(?:Fast)?|Texture(?:Anim)?|Camera|Media)|RemoteScriptAccessPin|PayPrice|LocalRot)|ScaleByFactor|Get(?:(?:Max|Min)ScaleFactor|ClosestNavPoint|StaticPath|SimStats|Env|PrimitiveParams|Link(?:PrimitiveParams|Number(?:OfSides)?|Key|Name|Media)|HTTPHeader|FreeURLs|Object(?:Details|PermMask|PrimCount)|Parcel(?:MaxPrims|Details|Prim(?:Count|Owners))|Attached|(?:SPMax|Free|Used)Memory|Region(?:Name|TimeDilation|FPS|Corner|AgentCount)|Root(?:Position|Rotation)|UnixTime|(?:Parcel|Region)Flags|(?:Wall|GMT)clock|SimulatorHostname|BoundingBox|GeometricCenter|Creator|NumberOf(?:Prims|NotecardLines|Sides)|Animation(?:List)?|(?:Camera|Local)(?:Pos|Rot)|Vel|Accel|Omega|Time(?:stamp|OfDay)|(?:Object|CenterOf)?Mass|MassMKS|Energy|Owner|(?:Owner)?Key|SunDirection|Texture(?:Offset|Scale|Rot)|Inventory(?:Number|Name|Key|Type|Creator|PermMask)|Permissions(?:Key)?|StartParameter|List(?:Length|EntryType)|Date|Agent(?:Size|Info|Language|List)|LandOwnerAt|NotecardLine|Script(?:Name|State))|(?:Get|Reset|GetAndReset)Time|PlaySound(?:Slave)?|LoopSound(?:Master|Slave)?|(?:Trigger|Stop|Preload)Sound|(?:(?:Get|Delete)Sub|Insert)String|To(?:Upper|Lower)|Give(?:InventoryList|Money)|RezObject|(?:Stop)?LookAt|Sleep|CollisionFilter|(?:Take|Release)Controls|DetachFromAvatar|AttachToAvatar(?:Temp)?|InstantMessage|(?:GetNext)?Email|StopHover|MinEventDelay|RotLookAt|String(?:Length|Trim)|(?:Start|Stop)Animation|TargetOmega|RequestPermissions|(?:Create|Break)Link|BreakAllLinks|(?:Give|Remove)Inventory|Water|PassTouches|Request(?:Agent|Inventory)Data|TeleportAgent(?:Home|GlobalCoords)?|ModifyLand|CollisionSound|ResetScript|MessageLinked|PushObject|PassCollisions|AxisAngle2Rot|Rot2(?:Axis|Angle)|A(?:cos|sin)|AngleBetween|AllowInventoryDrop|SubStringIndex|List2(?:CSV|Integer|Json|Float|String|Key|Vector|Rot|List(?:Strided)?)|DeleteSubList|List(?:Statistics|Sort|Randomize|(?:Insert|Find|Replace)List)|EdgeOfWorld|AdjustSoundVolume|Key2Name|TriggerSoundLimited|EjectFromLand|(?:CSV|ParseString)2List|OverMyLand|SameGroup|UnSit|Ground(?:Slope|Normal|Contour)|GroundRepel|(?:Set|Remove)VehicleFlags|(?:AvatarOn)?(?:Link)?SitTarget|Script(?:Danger|Profiler)|Dialog|VolumeDetect|ResetOtherScript|RemoteLoadScriptPin|(?:Open|Close)RemoteDataChannel|SendRemoteData|RemoteDataReply|(?:Integer|String)ToBase64|XorBase64|Log(?:10)?|Base64To(?:String|Integer)|ParseStringKeepNulls|RezAtRoot|RequestSimulatorData|ForceMouselook|(?:Load|Release|(?:E|Une)scape)URL|ParcelMedia(?:CommandList|Query)|ModPow|MapDestination|(?:RemoveFrom|AddTo|Reset)Land(?:Pass|Ban)List|(?:Set|Clear)CameraParams|HTTP(?:Request|Response)|TextBox|DetectedTouch(?:UV|Face|Pos|(?:N|Bin)ormal|ST)|(?:MD5|SHA1|DumpList2)String|Request(?:Secure)?URL|Clear(?:Prim|Link)Media|(?:Link)?ParticleSystem|(?:Get|Request)(?:Username|DisplayName)|RegionSayTo|CastRay|GenerateKey|TransferLindenDollars|ManageEstateAccess|(?:Create|Delete)Character|ExecCharacterCmd|Evade|FleeFrom|NavigateTo|PatrolPoints|Pursue|UpdateCharacter|WanderWithin))\b'
319 lsl_constants_float = r'\b(?:DEG_TO_RAD|PI(?:_BY_TWO)?|RAD_TO_DEG|SQRT2|TWO_PI)\b'
320 lsl_constants_integer = r'\b(?:JSON_APPEND|STATUS_(?:PHYSICS|ROTATE_[XYZ]|PHANTOM|SANDBOX|BLOCK_GRAB(?:_OBJECT)?|(?:DIE|RETURN)_AT_EDGE|CAST_SHADOWS|OK|MALFORMED_PARAMS|TYPE_MISMATCH|BOUNDS_ERROR|NOT_(?:FOUND|SUPPORTED)|INTERNAL_ERROR|WHITELIST_FAILED)|AGENT(?:_(?:BY_(?:LEGACY_|USER)NAME|FLYING|ATTACHMENTS|SCRIPTED|MOUSELOOK|SITTING|ON_OBJECT|AWAY|WALKING|IN_AIR|TYPING|CROUCHING|BUSY|ALWAYS_RUN|AUTOPILOT|LIST_(?:PARCEL(?:_OWNER)?|REGION)))?|CAMERA_(?:PITCH|DISTANCE|BEHINDNESS_(?:ANGLE|LAG)|(?:FOCUS|POSITION)(?:_(?:THRESHOLD|LOCKED|LAG))?|FOCUS_OFFSET|ACTIVE)|ANIM_ON|LOOP|REVERSE|PING_PONG|SMOOTH|ROTATE|SCALE|ALL_SIDES|LINK_(?:ROOT|SET|ALL_(?:OTHERS|CHILDREN)|THIS)|ACTIVE|PASSIVE|SCRIPTED|CONTROL_(?:FWD|BACK|(?:ROT_)?(?:LEFT|RIGHT)|UP|DOWN|(?:ML_)?LBUTTON)|PERMISSION_(?:RETURN_OBJECTS|DEBIT|OVERRIDE_ANIMATIONS|SILENT_ESTATE_MANAGEMENT|TAKE_CONTROLS|TRIGGER_ANIMATION|ATTACH|CHANGE_LINKS|(?:CONTROL|TRACK)_CAMERA|TELEPORT)|INVENTORY_(?:TEXTURE|SOUND|OBJECT|SCRIPT|LANDMARK|CLOTHING|NOTECARD|BODYPART|ANIMATION|GESTURE|ALL|NONE)|CHANGED_(?:INVENTORY|COLOR|SHAPE|SCALE|TEXTURE|LINK|ALLOWED_DROP|OWNER|REGION(?:_START)?|TELEPORT|MEDIA)|OBJECT_(?:(?:PHYSICS|SERVER|STREAMING)_COST|UNKNOWN_DETAIL|CHARACTER_TIME|PHANTOM|PHYSICS|TEMP_ON_REZ|NAME|DESC|POS|PRIM_EQUIVALENCE|RETURN_(?:PARCEL(?:_OWNER)?|REGION)|ROO?T|VELOCITY|OWNER|GROUP|CREATOR|ATTACHED_POINT|RENDER_WEIGHT|PATHFINDING_TYPE|(?:RUNNING|TOTAL)_SCRIPT_COUNT|SCRIPT_(?:MEMORY|TIME))|TYPE_(?:INTEGER|FLOAT|STRING|KEY|VECTOR|ROTATION|INVALID)|(?:DEBUG|PUBLIC)_CHANNEL|ATTACH_(?:AVATAR_CENTER|CHEST|HEAD|BACK|PELVIS|MOUTH|CHIN|NECK|NOSE|BELLY|[LR](?:SHOULDER|HAND|FOOT|EAR|EYE|[UL](?:ARM|LEG)|HIP)|(?:LEFT|RIGHT)_PEC|HUD_(?:CENTER_[12]|TOP_(?:RIGHT|CENTER|LEFT)|BOTTOM(?:_(?:RIGHT|LEFT))?))|LAND_(?:LEVEL|RAISE|LOWER|SMOOTH|NOISE|REVERT)|DATA_(?:ONLINE|NAME|BORN|SIM_(?:POS|STATUS|RATING)|PAYINFO)|PAYMENT_INFO_(?:ON_FILE|USED)|REMOTE_DATA_(?:CHANNEL|REQUEST|REPLY)|PSYS_(?:PART_(?:BF_(?:ZERO|ONE(?:_MINUS_(?:DEST_COLOR|SOURCE_(ALPHA|COLOR)))?|DEST_COLOR|SOURCE_(ALPHA|COLOR))|BLEND_FUNC_(DEST|SOURCE)|FLAGS|(?:START|END)_(?:COLOR|ALPHA|SCALE|GLOW)|MAX_AGE|(?:RIBBON|WIND|INTERP_(?:COLOR|SCALE)|BOUNCE|FOLLOW_(?:SRC|VELOCITY)|TARGET_(?:POS|LINEAR)|EMISSIVE)_MASK)|SRC_(?:MAX_AGE|PATTERN|ANGLE_(?:BEGIN|END)|BURST_(?:RATE|PART_COUNT|RADIUS|SPEED_(?:MIN|MAX))|ACCEL|TEXTURE|TARGET_KEY|OMEGA|PATTERN_(?:DROP|EXPLODE|ANGLE(?:_CONE(?:_EMPTY)?)?)))|VEHICLE_(?:REFERENCE_FRAME|TYPE_(?:NONE|SLED|CAR|BOAT|AIRPLANE|BALLOON)|(?:LINEAR|ANGULAR)_(?:FRICTION_TIMESCALE|MOTOR_DIRECTION)|LINEAR_MOTOR_OFFSET|HOVER_(?:HEIGHT|EFFICIENCY|TIMESCALE)|BUOYANCY|(?:LINEAR|ANGULAR)_(?:DEFLECTION_(?:EFFICIENCY|TIMESCALE)|MOTOR_(?:DECAY_)?TIMESCALE)|VERTICAL_ATTRACTION_(?:EFFICIENCY|TIMESCALE)|BANKING_(?:EFFICIENCY|MIX|TIMESCALE)|FLAG_(?:NO_DEFLECTION_UP|LIMIT_(?:ROLL_ONLY|MOTOR_UP)|HOVER_(?:(?:WATER|TERRAIN|UP)_ONLY|GLOBAL_HEIGHT)|MOUSELOOK_(?:STEER|BANK)|CAMERA_DECOUPLED))|PRIM_(?:TYPE(?:_(?:BOX|CYLINDER|PRISM|SPHERE|TORUS|TUBE|RING|SCULPT))?|HOLE_(?:DEFAULT|CIRCLE|SQUARE|TRIANGLE)|MATERIAL(?:_(?:STONE|METAL|GLASS|WOOD|FLESH|PLASTIC|RUBBER))?|SHINY_(?:NONE|LOW|MEDIUM|HIGH)|BUMP_(?:NONE|BRIGHT|DARK|WOOD|BARK|BRICKS|CHECKER|CONCRETE|TILE|STONE|DISKS|GRAVEL|BLOBS|SIDING|LARGETILE|STUCCO|SUCTION|WEAVE)|TEXGEN_(?:DEFAULT|PLANAR)|SCULPT_(?:TYPE_(?:SPHERE|TORUS|PLANE|CYLINDER|MASK)|FLAG_(?:MIRROR|INVERT))|PHYSICS(?:_(?:SHAPE_(?:CONVEX|NONE|PRIM|TYPE)))?|(?:POS|ROT)_LOCAL|SLICE|TEXT|FLEXIBLE|POINT_LIGHT|TEMP_ON_REZ|PHANTOM|POSITION|SIZE|ROTATION|TEXTURE|NAME|OMEGA|DESC|LINK_TARGET|COLOR|BUMP_SHINY|FULLBRIGHT|TEXGEN|GLOW|MEDIA_(?:ALT_IMAGE_ENABLE|CONTROLS|(?:CURRENT|HOME)_URL|AUTO_(?:LOOP|PLAY|SCALE|ZOOM)|FIRST_CLICK_INTERACT|(?:WIDTH|HEIGHT)_PIXELS|WHITELIST(?:_ENABLE)?|PERMS_(?:INTERACT|CONTROL)|PARAM_MAX|CONTROLS_(?:STANDARD|MINI)|PERM_(?:NONE|OWNER|GROUP|ANYONE)|MAX_(?:URL_LENGTH|WHITELIST_(?:SIZE|COUNT)|(?:WIDTH|HEIGHT)_PIXELS)))|MASK_(?:BASE|OWNER|GROUP|EVERYONE|NEXT)|PERM_(?:TRANSFER|MODIFY|COPY|MOVE|ALL)|PARCEL_(?:MEDIA_COMMAND_(?:STOP|PAUSE|PLAY|LOOP|TEXTURE|URL|TIME|AGENT|UNLOAD|AUTO_ALIGN|TYPE|SIZE|DESC|LOOP_SET)|FLAG_(?:ALLOW_(?:FLY|(?:GROUP_)?SCRIPTS|LANDMARK|TERRAFORM|DAMAGE|CREATE_(?:GROUP_)?OBJECTS)|USE_(?:ACCESS_(?:GROUP|LIST)|BAN_LIST|LAND_PASS_LIST)|LOCAL_SOUND_ONLY|RESTRICT_PUSHOBJECT|ALLOW_(?:GROUP|ALL)_OBJECT_ENTRY)|COUNT_(?:TOTAL|OWNER|GROUP|OTHER|SELECTED|TEMP)|DETAILS_(?:NAME|DESC|OWNER|GROUP|AREA|ID|SEE_AVATARS))|LIST_STAT_(?:MAX|MIN|MEAN|MEDIAN|STD_DEV|SUM(?:_SQUARES)?|NUM_COUNT|GEOMETRIC_MEAN|RANGE)|PAY_(?:HIDE|DEFAULT)|REGION_FLAG_(?:ALLOW_DAMAGE|FIXED_SUN|BLOCK_TERRAFORM|SANDBOX|DISABLE_(?:COLLISIONS|PHYSICS)|BLOCK_FLY|ALLOW_DIRECT_TELEPORT|RESTRICT_PUSHOBJECT)|HTTP_(?:METHOD|MIMETYPE|BODY_(?:MAXLENGTH|TRUNCATED)|CUSTOM_HEADER|PRAGMA_NO_CACHE|VERBOSE_THROTTLE|VERIFY_CERT)|STRING_(?:TRIM(?:_(?:HEAD|TAIL))?)|CLICK_ACTION_(?:NONE|TOUCH|SIT|BUY|PAY|OPEN(?:_MEDIA)?|PLAY|ZOOM)|TOUCH_INVALID_FACE|PROFILE_(?:NONE|SCRIPT_MEMORY)|RC_(?:DATA_FLAGS|DETECT_PHANTOM|GET_(?:LINK_NUM|NORMAL|ROOT_KEY)|MAX_HITS|REJECT_(?:TYPES|AGENTS|(?:NON)?PHYSICAL|LAND))|RCERR_(?:CAST_TIME_EXCEEDED|SIM_PERF_LOW|UNKNOWN)|ESTATE_ACCESS_(?:ALLOWED_(?:AGENT|GROUP)_(?:ADD|REMOVE)|BANNED_AGENT_(?:ADD|REMOVE))|DENSITY|FRICTION|RESTITUTION|GRAVITY_MULTIPLIER|KFM_(?:COMMAND|CMD_(?:PLAY|STOP|PAUSE|SET_MODE)|MODE|FORWARD|LOOP|PING_PONG|REVERSE|DATA|ROTATION|TRANSLATION)|ERR_(?:GENERIC|PARCEL_PERMISSIONS|MALFORMED_PARAMS|RUNTIME_PERMISSIONS|THROTTLED)|CHARACTER_(?:CMD_(?:(?:SMOOTH_)?STOP|JUMP)|DESIRED_(?:TURN_)?SPEED|RADIUS|STAY_WITHIN_PARCEL|LENGTH|ORIENTATION|ACCOUNT_FOR_SKIPPED_FRAMES|AVOIDANCE_MODE|TYPE(?:_(?:[A-D]|NONE))?|MAX_(?:DECEL|TURN_RADIUS|(?:ACCEL|SPEED)))|PURSUIT_(?:OFFSET|FUZZ_FACTOR|GOAL_TOLERANCE|INTERCEPT)|REQUIRE_LINE_OF_SIGHT|FORCE_DIRECT_PATH|VERTICAL|HORIZONTAL|AVOID_(?:CHARACTERS|DYNAMIC_OBSTACLES|NONE)|PU_(?:EVADE_(?:HIDDEN|SPOTTED)|FAILURE_(?:DYNAMIC_PATHFINDING_DISABLED|INVALID_(?:GOAL|START)|NO_(?:NAVMESH|VALID_DESTINATION)|OTHER|TARGET_GONE|(?:PARCEL_)?UNREACHABLE)|(?:GOAL|SLOWDOWN_DISTANCE)_REACHED)|TRAVERSAL_TYPE(?:_(?:FAST|NONE|SLOW))?|CONTENT_TYPE_(?:ATOM|FORM|HTML|JSON|LLSD|RSS|TEXT|XHTML|XML)|GCNP_(?:RADIUS|STATIC)|(?:PATROL|WANDER)_PAUSE_AT_WAYPOINTS|OPT_(?:AVATAR|CHARACTER|EXCLUSION_VOLUME|LEGACY_LINKSET|MATERIAL_VOLUME|OTHER|STATIC_OBSTACLE|WALKABLE)|SIM_STAT_PCT_CHARS_STEPPED)\b'
321 lsl_constants_integer_boolean = r'\b(?:FALSE|TRUE)\b'
322 lsl_constants_rotation = r'\b(?:ZERO_ROTATION)\b'
323 lsl_constants_string = r'\b(?:EOF|JSON_(?:ARRAY|DELETE|FALSE|INVALID|NULL|NUMBER|OBJECT|STRING|TRUE)|NULL_KEY|TEXTURE_(?:BLANK|DEFAULT|MEDIA|PLYWOOD|TRANSPARENT)|URL_REQUEST_(?:GRANTED|DENIED))\b'
324 lsl_constants_vector = r'\b(?:TOUCH_INVALID_(?:TEXCOORD|VECTOR)|ZERO_VECTOR)\b'
325 lsl_invalid_broken = r'\b(?:LAND_(?:LARGE|MEDIUM|SMALL)_BRUSH)\b'
326 lsl_invalid_deprecated = r'\b(?:ATTACH_[LR]PEC|DATA_RATING|OBJECT_ATTACHMENT_(?:GEOMETRY_BYTES|SURFACE_AREA)|PRIM_(?:CAST_SHADOWS|MATERIAL_LIGHT|TYPE_LEGACY)|PSYS_SRC_(?:INNER|OUTER)ANGLE|VEHICLE_FLAG_NO_FLY_UP|ll(?:Cloud|Make(?:Explosion|Fountain|Smoke|Fire)|RemoteDataSetRegion|Sound(?:Preload)?|XorBase64Strings(?:Correct)?))\b'
327 lsl_invalid_illegal = r'\b(?:event)\b'
328 lsl_invalid_unimplemented = r'\b(?:CHARACTER_(?:MAX_ANGULAR_(?:ACCEL|SPEED)|TURN_SPEED_MULTIPLIER)|PERMISSION_(?:CHANGE_(?:JOINTS|PERMISSIONS)|RELEASE_OWNERSHIP|REMAP_CONTROLS)|PRIM_PHYSICS_MATERIAL|PSYS_SRC_OBJ_REL_MASK|ll(?:CollisionSprite|(?:Stop)?PointAt|(?:(?:Refresh|Set)Prim)URL|(?:Take|Release)Camera|RemoteLoadScript))\b'
329 lsl_reserved_godmode = r'\b(?:ll(?:GodLikeRezObject|Set(?:Inventory|Object)PermMask))\b'
330 lsl_reserved_log = r'\b(?:print)\b'
331 lsl_operators = r'\+\+|\-\-|<<|>>|&&?|\|\|?|\^|~|[!%<>=*+\-/]=?'
332
333 tokens = {
334 'root':
335 [
336 (r'//.*?\n', Comment.Single),
337 (r'/\*', Comment.Multiline, 'comment'),
338 (r'"', String.Double, 'string'),
339 (lsl_keywords, Keyword),
340 (lsl_types, Keyword.Type),
341 (lsl_states, Name.Class),
342 (lsl_events, Name.Builtin),
343 (lsl_functions_builtin, Name.Function),
344 (lsl_constants_float, Keyword.Constant),
345 (lsl_constants_integer, Keyword.Constant),
346 (lsl_constants_integer_boolean, Keyword.Constant),
347 (lsl_constants_rotation, Keyword.Constant),
348 (lsl_constants_string, Keyword.Constant),
349 (lsl_constants_vector, Keyword.Constant),
350 (lsl_invalid_broken, Error),
351 (lsl_invalid_deprecated, Error),
352 (lsl_invalid_illegal, Error),
353 (lsl_invalid_unimplemented, Error),
354 (lsl_reserved_godmode, Keyword.Reserved),
355 (lsl_reserved_log, Keyword.Reserved),
356 (r'\b([a-zA-Z_]\w*)\b', Name.Variable),
357 (r'(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d*', Number.Float),
358 (r'(\d+\.\d*|\.\d+)', Number.Float),
359 (r'0[xX][0-9a-fA-F]+', Number.Hex),
360 (r'\d+', Number.Integer),
361 (lsl_operators, Operator),
362 (r':=?', Error),
363 (r'[,;{}()\[\]]', Punctuation),
364 (r'\n+', Whitespace),
365 (r'\s+', Whitespace)
366 ],
367 'comment':
368 [
369 (r'[^*/]+', Comment.Multiline),
370 (r'/\*', Comment.Multiline, '#push'),
371 (r'\*/', Comment.Multiline, '#pop'),
372 (r'[*/]', Comment.Multiline)
373 ],
374 'string':
375 [
376 (r'\\([nt"\\])', String.Escape),
377 (r'"', String.Double, '#pop'),
378 (r'\\.', Error),
379 (r'[^"\\]+', String.Double),
380 ]
381 }
382
383
384 class AppleScriptLexer(RegexLexer):
385 """
386 For `AppleScript source code
387 <http://developer.apple.com/documentation/AppleScript/
388 Conceptual/AppleScriptLangGuide>`_,
389 including `AppleScript Studio
390 <http://developer.apple.com/documentation/AppleScript/
391 Reference/StudioReference>`_.
392 Contributed by Andreas Amann <aamann@mac.com>.
393
394 .. versionadded:: 1.0
395 """
396
397 name = 'AppleScript'
398 aliases = ['applescript']
399 filenames = ['*.applescript']
400
401 flags = re.MULTILINE | re.DOTALL
402
403 Identifiers = r'[a-zA-Z]\w*'
404
405 # XXX: use words() for all of these
406 Literals = ('AppleScript', 'current application', 'false', 'linefeed',
407 'missing value', 'pi', 'quote', 'result', 'return', 'space',
408 'tab', 'text item delimiters', 'true', 'version')
409 Classes = ('alias ', 'application ', 'boolean ', 'class ', 'constant ',
410 'date ', 'file ', 'integer ', 'list ', 'number ', 'POSIX file ',
411 'real ', 'record ', 'reference ', 'RGB color ', 'script ',
412 'text ', 'unit types', '(?:Unicode )?text', 'string')
413 BuiltIn = ('attachment', 'attribute run', 'character', 'day', 'month',
414 'paragraph', 'word', 'year')
415 HandlerParams = ('about', 'above', 'against', 'apart from', 'around',
416 'aside from', 'at', 'below', 'beneath', 'beside',
417 'between', 'for', 'given', 'instead of', 'on', 'onto',
418 'out of', 'over', 'since')
419 Commands = ('ASCII (character|number)', 'activate', 'beep', 'choose URL',
420 'choose application', 'choose color', 'choose file( name)?',
421 'choose folder', 'choose from list',
422 'choose remote application', 'clipboard info',
423 'close( access)?', 'copy', 'count', 'current date', 'delay',
424 'delete', 'display (alert|dialog)', 'do shell script',
425 'duplicate', 'exists', 'get eof', 'get volume settings',
426 'info for', 'launch', 'list (disks|folder)', 'load script',
427 'log', 'make', 'mount volume', 'new', 'offset',
428 'open( (for access|location))?', 'path to', 'print', 'quit',
429 'random number', 'read', 'round', 'run( script)?',
430 'say', 'scripting components',
431 'set (eof|the clipboard to|volume)', 'store script',
432 'summarize', 'system attribute', 'system info',
433 'the clipboard', 'time to GMT', 'write', 'quoted form')
434 References = ('(in )?back of', '(in )?front of', '[0-9]+(st|nd|rd|th)',
435 'first', 'second', 'third', 'fourth', 'fifth', 'sixth',
436 'seventh', 'eighth', 'ninth', 'tenth', 'after', 'back',
437 'before', 'behind', 'every', 'front', 'index', 'last',
438 'middle', 'some', 'that', 'through', 'thru', 'where', 'whose')
439 Operators = ("and", "or", "is equal", "equals", "(is )?equal to", "is not",
440 "isn't", "isn't equal( to)?", "is not equal( to)?",
441 "doesn't equal", "does not equal", "(is )?greater than",
442 "comes after", "is not less than or equal( to)?",
443 "isn't less than or equal( to)?", "(is )?less than",
444 "comes before", "is not greater than or equal( to)?",
445 "isn't greater than or equal( to)?",
446 "(is )?greater than or equal( to)?", "is not less than",
447 "isn't less than", "does not come before",
448 "doesn't come before", "(is )?less than or equal( to)?",
449 "is not greater than", "isn't greater than",
450 "does not come after", "doesn't come after", "starts? with",
451 "begins? with", "ends? with", "contains?", "does not contain",
452 "doesn't contain", "is in", "is contained by", "is not in",
453 "is not contained by", "isn't contained by", "div", "mod",
454 "not", "(a )?(ref( to)?|reference to)", "is", "does")
455 Control = ('considering', 'else', 'error', 'exit', 'from', 'if',
456 'ignoring', 'in', 'repeat', 'tell', 'then', 'times', 'to',
457 'try', 'until', 'using terms from', 'while', 'whith',
458 'with timeout( of)?', 'with transaction', 'by', 'continue',
459 'end', 'its?', 'me', 'my', 'return', 'of', 'as')
460 Declarations = ('global', 'local', 'prop(erty)?', 'set', 'get')
461 Reserved = ('but', 'put', 'returning', 'the')
462 StudioClasses = ('action cell', 'alert reply', 'application', 'box',
463 'browser( cell)?', 'bundle', 'button( cell)?', 'cell',
464 'clip view', 'color well', 'color-panel',
465 'combo box( item)?', 'control',
466 'data( (cell|column|item|row|source))?', 'default entry',
467 'dialog reply', 'document', 'drag info', 'drawer',
468 'event', 'font(-panel)?', 'formatter',
469 'image( (cell|view))?', 'matrix', 'menu( item)?', 'item',
470 'movie( view)?', 'open-panel', 'outline view', 'panel',
471 'pasteboard', 'plugin', 'popup button',
472 'progress indicator', 'responder', 'save-panel',
473 'scroll view', 'secure text field( cell)?', 'slider',
474 'sound', 'split view', 'stepper', 'tab view( item)?',
475 'table( (column|header cell|header view|view))',
476 'text( (field( cell)?|view))?', 'toolbar( item)?',
477 'user-defaults', 'view', 'window')
478 StudioEvents = ('accept outline drop', 'accept table drop', 'action',
479 'activated', 'alert ended', 'awake from nib', 'became key',
480 'became main', 'begin editing', 'bounds changed',
481 'cell value', 'cell value changed', 'change cell value',
482 'change item value', 'changed', 'child of item',
483 'choose menu item', 'clicked', 'clicked toolbar item',
484 'closed', 'column clicked', 'column moved',
485 'column resized', 'conclude drop', 'data representation',
486 'deminiaturized', 'dialog ended', 'document nib name',
487 'double clicked', 'drag( (entered|exited|updated))?',
488 'drop', 'end editing', 'exposed', 'idle', 'item expandable',
489 'item value', 'item value changed', 'items changed',
490 'keyboard down', 'keyboard up', 'launched',
491 'load data representation', 'miniaturized', 'mouse down',
492 'mouse dragged', 'mouse entered', 'mouse exited',
493 'mouse moved', 'mouse up', 'moved',
494 'number of browser rows', 'number of items',
495 'number of rows', 'open untitled', 'opened', 'panel ended',
496 'parameters updated', 'plugin loaded', 'prepare drop',
497 'prepare outline drag', 'prepare outline drop',
498 'prepare table drag', 'prepare table drop',
499 'read from file', 'resigned active', 'resigned key',
500 'resigned main', 'resized( sub views)?',
501 'right mouse down', 'right mouse dragged',
502 'right mouse up', 'rows changed', 'scroll wheel',
503 'selected tab view item', 'selection changed',
504 'selection changing', 'should begin editing',
505 'should close', 'should collapse item',
506 'should end editing', 'should expand item',
507 'should open( untitled)?',
508 'should quit( after last window closed)?',
509 'should select column', 'should select item',
510 'should select row', 'should select tab view item',
511 'should selection change', 'should zoom', 'shown',
512 'update menu item', 'update parameters',
513 'update toolbar item', 'was hidden', 'was miniaturized',
514 'will become active', 'will close', 'will dismiss',
515 'will display browser cell', 'will display cell',
516 'will display item cell', 'will display outline cell',
517 'will finish launching', 'will hide', 'will miniaturize',
518 'will move', 'will open', 'will pop up', 'will quit',
519 'will resign active', 'will resize( sub views)?',
520 'will select tab view item', 'will show', 'will zoom',
521 'write to file', 'zoomed')
522 StudioCommands = ('animate', 'append', 'call method', 'center',
523 'close drawer', 'close panel', 'display',
524 'display alert', 'display dialog', 'display panel', 'go',
525 'hide', 'highlight', 'increment', 'item for',
526 'load image', 'load movie', 'load nib', 'load panel',
527 'load sound', 'localized string', 'lock focus', 'log',
528 'open drawer', 'path for', 'pause', 'perform action',
529 'play', 'register', 'resume', 'scroll', 'select( all)?',
530 'show', 'size to fit', 'start', 'step back',
531 'step forward', 'stop', 'synchronize', 'unlock focus',
532 'update')
533 StudioProperties = ('accepts arrow key', 'action method', 'active',
534 'alignment', 'allowed identifiers',
535 'allows branch selection', 'allows column reordering',
536 'allows column resizing', 'allows column selection',
537 'allows customization',
538 'allows editing text attributes',
539 'allows empty selection', 'allows mixed state',
540 'allows multiple selection', 'allows reordering',
541 'allows undo', 'alpha( value)?', 'alternate image',
542 'alternate increment value', 'alternate title',
543 'animation delay', 'associated file name',
544 'associated object', 'auto completes', 'auto display',
545 'auto enables items', 'auto repeat',
546 'auto resizes( outline column)?',
547 'auto save expanded items', 'auto save name',
548 'auto save table columns', 'auto saves configuration',
549 'auto scroll', 'auto sizes all columns to fit',
550 'auto sizes cells', 'background color', 'bezel state',
551 'bezel style', 'bezeled', 'border rect', 'border type',
552 'bordered', 'bounds( rotation)?', 'box type',
553 'button returned', 'button type',
554 'can choose directories', 'can choose files',
555 'can draw', 'can hide',
556 'cell( (background color|size|type))?', 'characters',
557 'class', 'click count', 'clicked( data)? column',
558 'clicked data item', 'clicked( data)? row',
559 'closeable', 'collating', 'color( (mode|panel))',
560 'command key down', 'configuration',
561 'content(s| (size|view( margins)?))?', 'context',
562 'continuous', 'control key down', 'control size',
563 'control tint', 'control view',
564 'controller visible', 'coordinate system',
565 'copies( on scroll)?', 'corner view', 'current cell',
566 'current column', 'current( field)? editor',
567 'current( menu)? item', 'current row',
568 'current tab view item', 'data source',
569 'default identifiers', 'delta (x|y|z)',
570 'destination window', 'directory', 'display mode',
571 'displayed cell', 'document( (edited|rect|view))?',
572 'double value', 'dragged column', 'dragged distance',
573 'dragged items', 'draws( cell)? background',
574 'draws grid', 'dynamically scrolls', 'echos bullets',
575 'edge', 'editable', 'edited( data)? column',
576 'edited data item', 'edited( data)? row', 'enabled',
577 'enclosing scroll view', 'ending page',
578 'error handling', 'event number', 'event type',
579 'excluded from windows menu', 'executable path',
580 'expanded', 'fax number', 'field editor', 'file kind',
581 'file name', 'file type', 'first responder',
582 'first visible column', 'flipped', 'floating',
583 'font( panel)?', 'formatter', 'frameworks path',
584 'frontmost', 'gave up', 'grid color', 'has data items',
585 'has horizontal ruler', 'has horizontal scroller',
586 'has parent data item', 'has resize indicator',
587 'has shadow', 'has sub menu', 'has vertical ruler',
588 'has vertical scroller', 'header cell', 'header view',
589 'hidden', 'hides when deactivated', 'highlights by',
590 'horizontal line scroll', 'horizontal page scroll',
591 'horizontal ruler view', 'horizontally resizable',
592 'icon image', 'id', 'identifier',
593 'ignores multiple clicks',
594 'image( (alignment|dims when disabled|frame style|scaling))?',
595 'imports graphics', 'increment value',
596 'indentation per level', 'indeterminate', 'index',
597 'integer value', 'intercell spacing', 'item height',
598 'key( (code|equivalent( modifier)?|window))?',
599 'knob thickness', 'label', 'last( visible)? column',
600 'leading offset', 'leaf', 'level', 'line scroll',
601 'loaded', 'localized sort', 'location', 'loop mode',
602 'main( (bunde|menu|window))?', 'marker follows cell',
603 'matrix mode', 'maximum( content)? size',
604 'maximum visible columns',
605 'menu( form representation)?', 'miniaturizable',
606 'miniaturized', 'minimized image', 'minimized title',
607 'minimum column width', 'minimum( content)? size',
608 'modal', 'modified', 'mouse down state',
609 'movie( (controller|file|rect))?', 'muted', 'name',
610 'needs display', 'next state', 'next text',
611 'number of tick marks', 'only tick mark values',
612 'opaque', 'open panel', 'option key down',
613 'outline table column', 'page scroll', 'pages across',
614 'pages down', 'palette label', 'pane splitter',
615 'parent data item', 'parent window', 'pasteboard',
616 'path( (names|separator))?', 'playing',
617 'plays every frame', 'plays selection only', 'position',
618 'preferred edge', 'preferred type', 'pressure',
619 'previous text', 'prompt', 'properties',
620 'prototype cell', 'pulls down', 'rate',
621 'released when closed', 'repeated',
622 'requested print time', 'required file type',
623 'resizable', 'resized column', 'resource path',
624 'returns records', 'reuses columns', 'rich text',
625 'roll over', 'row height', 'rulers visible',
626 'save panel', 'scripts path', 'scrollable',
627 'selectable( identifiers)?', 'selected cell',
628 'selected( data)? columns?', 'selected data items?',
629 'selected( data)? rows?', 'selected item identifier',
630 'selection by rect', 'send action on arrow key',
631 'sends action when done editing', 'separates columns',
632 'separator item', 'sequence number', 'services menu',
633 'shared frameworks path', 'shared support path',
634 'sheet', 'shift key down', 'shows alpha',
635 'shows state by', 'size( mode)?',
636 'smart insert delete enabled', 'sort case sensitivity',
637 'sort column', 'sort order', 'sort type',
638 'sorted( data rows)?', 'sound', 'source( mask)?',
639 'spell checking enabled', 'starting page', 'state',
640 'string value', 'sub menu', 'super menu', 'super view',
641 'tab key traverses cells', 'tab state', 'tab type',
642 'tab view', 'table view', 'tag', 'target( printer)?',
643 'text color', 'text container insert',
644 'text container origin', 'text returned',
645 'tick mark position', 'time stamp',
646 'title(d| (cell|font|height|position|rect))?',
647 'tool tip', 'toolbar', 'trailing offset', 'transparent',
648 'treat packages as directories', 'truncated labels',
649 'types', 'unmodified characters', 'update views',
650 'use sort indicator', 'user defaults',
651 'uses data source', 'uses ruler',
652 'uses threaded animation',
653 'uses title from previous column', 'value wraps',
654 'version',
655 'vertical( (line scroll|page scroll|ruler view))?',
656 'vertically resizable', 'view',
657 'visible( document rect)?', 'volume', 'width', 'window',
658 'windows menu', 'wraps', 'zoomable', 'zoomed')
659
660 tokens = {
661 'root': [
662 (r'\s+', Text),
663 (u'¬\\n', String.Escape),
664 (r"'s\s+", Text), # This is a possessive, consider moving
665 (r'(--|#).*?$', Comment),
666 (r'\(\*', Comment.Multiline, 'comment'),
667 (r'[(){}!,.:]', Punctuation),
668 (u'(«)([^»]+)(»)',
669 bygroups(Text, Name.Builtin, Text)),
670 (r'\b((?:considering|ignoring)\s*)'
671 r'(application responses|case|diacriticals|hyphens|'
672 r'numeric strings|punctuation|white space)',
673 bygroups(Keyword, Name.Builtin)),
674 (u'(-|\\*|\\+|&|≠|>=?|<=?|=|≥|≤|/|÷|\\^)', Operator),
675 (r"\b(%s)\b" % '|'.join(Operators), Operator.Word),
676 (r'^(\s*(?:on|end)\s+)'
677 r'(%s)' % '|'.join(StudioEvents[::-1]),
678 bygroups(Keyword, Name.Function)),
679 (r'^(\s*)(in|on|script|to)(\s+)', bygroups(Text, Keyword, Text)),
680 (r'\b(as )(%s)\b' % '|'.join(Classes),
681 bygroups(Keyword, Name.Class)),
682 (r'\b(%s)\b' % '|'.join(Literals), Name.Constant),
683 (r'\b(%s)\b' % '|'.join(Commands), Name.Builtin),
684 (r'\b(%s)\b' % '|'.join(Control), Keyword),
685 (r'\b(%s)\b' % '|'.join(Declarations), Keyword),
686 (r'\b(%s)\b' % '|'.join(Reserved), Name.Builtin),
687 (r'\b(%s)s?\b' % '|'.join(BuiltIn), Name.Builtin),
688 (r'\b(%s)\b' % '|'.join(HandlerParams), Name.Builtin),
689 (r'\b(%s)\b' % '|'.join(StudioProperties), Name.Attribute),
690 (r'\b(%s)s?\b' % '|'.join(StudioClasses), Name.Builtin),
691 (r'\b(%s)\b' % '|'.join(StudioCommands), Name.Builtin),
692 (r'\b(%s)\b' % '|'.join(References), Name.Builtin),
693 (r'"(\\\\|\\"|[^"])*"', String.Double),
694 (r'\b(%s)\b' % Identifiers, Name.Variable),
695 (r'[-+]?(\d+\.\d*|\d*\.\d+)(E[-+][0-9]+)?', Number.Float),
696 (r'[-+]?\d+', Number.Integer),
697 ],
698 'comment': [
699 (r'\(\*', Comment.Multiline, '#push'),
700 (r'\*\)', Comment.Multiline, '#pop'),
701 ('[^*(]+', Comment.Multiline),
702 ('[*(]', Comment.Multiline),
703 ],
704 }
705
706
707 class RexxLexer(RegexLexer):
708 """
709 `Rexx <http://www.rexxinfo.org/>`_ is a scripting language available for
710 a wide range of different platforms with its roots found on mainframe
711 systems. It is popular for I/O- and data based tasks and can act as glue
712 language to bind different applications together.
713
714 .. versionadded:: 2.0
715 """
716 name = 'Rexx'
717 aliases = ['rexx', 'arexx']
718 filenames = ['*.rexx', '*.rex', '*.rx', '*.arexx']
719 mimetypes = ['text/x-rexx']
720 flags = re.IGNORECASE
721
722 tokens = {
723 'root': [
724 (r'\s', Whitespace),
725 (r'/\*', Comment.Multiline, 'comment'),
726 (r'"', String, 'string_double'),
727 (r"'", String, 'string_single'),
728 (r'[0-9]+(\.[0-9]+)?(e[+-]?[0-9])?', Number),
729 (r'([a-z_]\w*)(\s*)(:)(\s*)(procedure)\b',
730 bygroups(Name.Function, Whitespace, Operator, Whitespace,
731 Keyword.Declaration)),
732 (r'([a-z_]\w*)(\s*)(:)',
733 bygroups(Name.Label, Whitespace, Operator)),
734 include('function'),
735 include('keyword'),
736 include('operator'),
737 (r'[a-z_]\w*', Text),
738 ],
739 'function': [
740 (words((
741 'abbrev', 'abs', 'address', 'arg', 'b2x', 'bitand', 'bitor', 'bitxor',
742 'c2d', 'c2x', 'center', 'charin', 'charout', 'chars', 'compare',
743 'condition', 'copies', 'd2c', 'd2x', 'datatype', 'date', 'delstr',
744 'delword', 'digits', 'errortext', 'form', 'format', 'fuzz', 'insert',
745 'lastpos', 'left', 'length', 'linein', 'lineout', 'lines', 'max',
746 'min', 'overlay', 'pos', 'queued', 'random', 'reverse', 'right', 'sign',
747 'sourceline', 'space', 'stream', 'strip', 'substr', 'subword', 'symbol',
748 'time', 'trace', 'translate', 'trunc', 'value', 'verify', 'word',
749 'wordindex', 'wordlength', 'wordpos', 'words', 'x2b', 'x2c', 'x2d',
750 'xrange'), suffix=r'(\s*)(\()'),
751 bygroups(Name.Builtin, Whitespace, Operator)),
752 ],
753 'keyword': [
754 (r'(address|arg|by|call|do|drop|else|end|exit|for|forever|if|'
755 r'interpret|iterate|leave|nop|numeric|off|on|options|parse|'
756 r'pull|push|queue|return|say|select|signal|to|then|trace|until|'
757 r'while)\b', Keyword.Reserved),
758 ],
759 'operator': [
760 (r'(-|//|/|\(|\)|\*\*|\*|\\<<|\\<|\\==|\\=|\\>>|\\>|\\|\|\||\||'
761 r'&&|&|%|\+|<<=|<<|<=|<>|<|==|=|><|>=|>>=|>>|>|¬<<|¬<|¬==|¬=|'
762 r'¬>>|¬>|¬|\.|,)', Operator),
763 ],
764 'string_double': [
765 (r'[^"\n]+', String),
766 (r'""', String),
767 (r'"', String, '#pop'),
768 (r'\n', Text, '#pop'), # Stray linefeed also terminates strings.
769 ],
770 'string_single': [
771 (r'[^\'\n]', String),
772 (r'\'\'', String),
773 (r'\'', String, '#pop'),
774 (r'\n', Text, '#pop'), # Stray linefeed also terminates strings.
775 ],
776 'comment': [
777 (r'[^*]+', Comment.Multiline),
778 (r'\*/', Comment.Multiline, '#pop'),
779 (r'\*', Comment.Multiline),
780 ]
781 }
782
783 _c = lambda s: re.compile(s, re.MULTILINE)
784 _ADDRESS_COMMAND_PATTERN = _c(r'^\s*address\s+command\b')
785 _ADDRESS_PATTERN = _c(r'^\s*address\s+')
786 _DO_WHILE_PATTERN = _c(r'^\s*do\s+while\b')
787 _IF_THEN_DO_PATTERN = _c(r'^\s*if\b.+\bthen\s+do\s*$')
788 _PROCEDURE_PATTERN = _c(r'^\s*([a-z_]\w*)(\s*)(:)(\s*)(procedure)\b')
789 _ELSE_DO_PATTERN = _c(r'\belse\s+do\s*$')
790 _PARSE_ARG_PATTERN = _c(r'^\s*parse\s+(upper\s+)?(arg|value)\b')
791 PATTERNS_AND_WEIGHTS = (
792 (_ADDRESS_COMMAND_PATTERN, 0.2),
793 (_ADDRESS_PATTERN, 0.05),
794 (_DO_WHILE_PATTERN, 0.1),
795 (_ELSE_DO_PATTERN, 0.1),
796 (_IF_THEN_DO_PATTERN, 0.1),
797 (_PROCEDURE_PATTERN, 0.5),
798 (_PARSE_ARG_PATTERN, 0.2),
799 )
800
801 def analyse_text(text):
802 """
803 Check for inital comment and patterns that distinguish Rexx from other
804 C-like languages.
805 """
806 if re.search(r'/\*\**\s*rexx', text, re.IGNORECASE):
807 # Header matches MVS Rexx requirements, this is certainly a Rexx
808 # script.
809 return 1.0
810 elif text.startswith('/*'):
811 # Header matches general Rexx requirements; the source code might
812 # still be any language using C comments such as C++, C# or Java.
813 lowerText = text.lower()
814 result = sum(weight
815 for (pattern, weight) in RexxLexer.PATTERNS_AND_WEIGHTS
816 if pattern.search(lowerText)) + 0.01
817 return min(result, 1.0)
818
819
820 class MOOCodeLexer(RegexLexer):
821 """
822 For `MOOCode <http://www.moo.mud.org/>`_ (the MOO scripting
823 language).
824
825 .. versionadded:: 0.9
826 """
827 name = 'MOOCode'
828 filenames = ['*.moo']
829 aliases = ['moocode', 'moo']
830 mimetypes = ['text/x-moocode']
831
832 tokens = {
833 'root': [
834 # Numbers
835 (r'(0|[1-9][0-9_]*)', Number.Integer),
836 # Strings
837 (r'"(\\\\|\\"|[^"])*"', String),
838 # exceptions
839 (r'(E_PERM|E_DIV)', Name.Exception),
840 # db-refs
841 (r'((#[-0-9]+)|(\$\w+))', Name.Entity),
842 # Keywords
843 (r'\b(if|else|elseif|endif|for|endfor|fork|endfork|while'
844 r'|endwhile|break|continue|return|try'
845 r'|except|endtry|finally|in)\b', Keyword),
846 # builtins
847 (r'(random|length)', Name.Builtin),
848 # special variables
849 (r'(player|caller|this|args)', Name.Variable.Instance),
850 # skip whitespace
851 (r'\s+', Text),
852 (r'\n', Text),
853 # other operators
854 (r'([!;=,{}&|:.\[\]@()<>?]+)', Operator),
855 # function call
856 (r'(\w+)(\()', bygroups(Name.Function, Operator)),
857 # variables
858 (r'(\w+)', Text),
859 ]
860 }
861
862
863 class HybrisLexer(RegexLexer):
864 """
865 For `Hybris <http://www.hybris-lang.org>`_ source code.
866
867 .. versionadded:: 1.4
868 """
869
870 name = 'Hybris'
871 aliases = ['hybris', 'hy']
872 filenames = ['*.hy', '*.hyb']
873 mimetypes = ['text/x-hybris', 'application/x-hybris']
874
875 flags = re.MULTILINE | re.DOTALL
876
877 tokens = {
878 'root': [
879 # method names
880 (r'^(\s*(?:function|method|operator\s+)+?)'
881 r'([a-zA-Z_]\w*)'
882 r'(\s*)(\()', bygroups(Keyword, Name.Function, Text, Operator)),
883 (r'[^\S\n]+', Text),
884 (r'//.*?\n', Comment.Single),
885 (r'/\*.*?\*/', Comment.Multiline),
886 (r'@[a-zA-Z_][\w.]*', Name.Decorator),
887 (r'(break|case|catch|next|default|do|else|finally|for|foreach|of|'
888 r'unless|if|new|return|switch|me|throw|try|while)\b', Keyword),
889 (r'(extends|private|protected|public|static|throws|function|method|'
890 r'operator)\b', Keyword.Declaration),
891 (r'(true|false|null|__FILE__|__LINE__|__VERSION__|__LIB_PATH__|'
892 r'__INC_PATH__)\b', Keyword.Constant),
893 (r'(class|struct)(\s+)',
894 bygroups(Keyword.Declaration, Text), 'class'),
895 (r'(import|include)(\s+)',
896 bygroups(Keyword.Namespace, Text), 'import'),
897 (words((
898 'gc_collect', 'gc_mm_items', 'gc_mm_usage', 'gc_collect_threshold',
899 'urlencode', 'urldecode', 'base64encode', 'base64decode', 'sha1', 'crc32',
900 'sha2', 'md5', 'md5_file', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos',
901 'cosh', 'exp', 'fabs', 'floor', 'fmod', 'log', 'log10', 'pow', 'sin',
902 'sinh', 'sqrt', 'tan', 'tanh', 'isint', 'isfloat', 'ischar', 'isstring',
903 'isarray', 'ismap', 'isalias', 'typeof', 'sizeof', 'toint', 'tostring',
904 'fromxml', 'toxml', 'binary', 'pack', 'load', 'eval', 'var_names',
905 'var_values', 'user_functions', 'dyn_functions', 'methods', 'call',
906 'call_method', 'mknod', 'mkfifo', 'mount', 'umount2', 'umount', 'ticks',
907 'usleep', 'sleep', 'time', 'strtime', 'strdate', 'dllopen', 'dlllink',
908 'dllcall', 'dllcall_argv', 'dllclose', 'env', 'exec', 'fork', 'getpid',
909 'wait', 'popen', 'pclose', 'exit', 'kill', 'pthread_create',
910 'pthread_create_argv', 'pthread_exit', 'pthread_join', 'pthread_kill',
911 'smtp_send', 'http_get', 'http_post', 'http_download', 'socket', 'bind',
912 'listen', 'accept', 'getsockname', 'getpeername', 'settimeout', 'connect',
913 'server', 'recv', 'send', 'close', 'print', 'println', 'printf', 'input',
914 'readline', 'serial_open', 'serial_fcntl', 'serial_get_attr',
915 'serial_get_ispeed', 'serial_get_ospeed', 'serial_set_attr',
916 'serial_set_ispeed', 'serial_set_ospeed', 'serial_write', 'serial_read',
917 'serial_close', 'xml_load', 'xml_parse', 'fopen', 'fseek', 'ftell',
918 'fsize', 'fread', 'fwrite', 'fgets', 'fclose', 'file', 'readdir',
919 'pcre_replace', 'size', 'pop', 'unmap', 'has', 'keys', 'values',
920 'length', 'find', 'substr', 'replace', 'split', 'trim', 'remove',
921 'contains', 'join'), suffix=r'\b'),
922 Name.Builtin),
923 (words((
924 'MethodReference', 'Runner', 'Dll', 'Thread', 'Pipe', 'Process',
925 'Runnable', 'CGI', 'ClientSocket', 'Socket', 'ServerSocket',
926 'File', 'Console', 'Directory', 'Exception'), suffix=r'\b'),
927 Keyword.Type),
928 (r'"(\\\\|\\"|[^"])*"', String),
929 (r"'\\.'|'[^\\]'|'\\u[0-9a-f]{4}'", String.Char),
930 (r'(\.)([a-zA-Z_]\w*)',
931 bygroups(Operator, Name.Attribute)),
932 (r'[a-zA-Z_]\w*:', Name.Label),
933 (r'[a-zA-Z_$]\w*', Name),
934 (r'[~^*!%&\[\](){}<>|+=:;,./?\-@]+', Operator),
935 (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
936 (r'0x[0-9a-f]+', Number.Hex),
937 (r'[0-9]+L?', Number.Integer),
938 (r'\n', Text),
939 ],
940 'class': [
941 (r'[a-zA-Z_]\w*', Name.Class, '#pop')
942 ],
943 'import': [
944 (r'[\w.]+\*?', Name.Namespace, '#pop')
945 ],
946 }
947
948
949 class EasytrieveLexer(RegexLexer):
950 """
951 Easytrieve Plus is a programming language for extracting, filtering and
952 converting sequential data. Furthermore it can layout data for reports.
953 It is mainly used on mainframe platforms and can access several of the
954 mainframe's native file formats. It is somewhat comparable to awk.
955
956 .. versionadded:: 2.1
957 """
958 name = 'Easytrieve'
959 aliases = ['easytrieve']
960 filenames = ['*.ezt', '*.mac']
961 mimetypes = ['text/x-easytrieve']
962 flags = 0
963
964 # Note: We cannot use r'\b' at the start and end of keywords because
965 # Easytrieve Plus delimiter characters are:
966 #
967 # * space ( )
968 # * apostrophe (')
969 # * period (.)
970 # * comma (,)
971 # * paranthesis ( and )
972 # * colon (:)
973 #
974 # Additionally words end once a '*' appears, indicatins a comment.
975 _DELIMITERS = r' \'.,():\n'
976 _DELIMITERS_OR_COMENT = _DELIMITERS + '*'
977 _DELIMITER_PATTERN = '[' + _DELIMITERS + ']'
978 _DELIMITER_PATTERN_CAPTURE = '(' + _DELIMITER_PATTERN + ')'
979 _NON_DELIMITER_OR_COMMENT_PATTERN = '[^' + _DELIMITERS_OR_COMENT + ']'
980 _OPERATORS_PATTERN = u'[.+\\-/=\\[\\](){}<>;,&%¬]'
981 _KEYWORDS = [
982 'AFTER-BREAK', 'AFTER-LINE', 'AFTER-SCREEN', 'AIM', 'AND', 'ATTR',
983 'BEFORE', 'BEFORE-BREAK', 'BEFORE-LINE', 'BEFORE-SCREEN', 'BUSHU',
984 'BY', 'CALL', 'CASE', 'CHECKPOINT', 'CHKP', 'CHKP-STATUS', 'CLEAR',
985 'CLOSE', 'COL', 'COLOR', 'COMMIT', 'CONTROL', 'COPY', 'CURSOR', 'D',
986 'DECLARE', 'DEFAULT', 'DEFINE', 'DELETE', 'DENWA', 'DISPLAY', 'DLI',
987 'DO', 'DUPLICATE', 'E', 'ELSE', 'ELSE-IF', 'END', 'END-CASE',
988 'END-DO', 'END-IF', 'END-PROC', 'ENDPAGE', 'ENDTABLE', 'ENTER', 'EOF',
989 'EQ', 'ERROR', 'EXIT', 'EXTERNAL', 'EZLIB', 'F1', 'F10', 'F11', 'F12',
990 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F2', 'F20', 'F21',
991 'F22', 'F23', 'F24', 'F25', 'F26', 'F27', 'F28', 'F29', 'F3', 'F30',
992 'F31', 'F32', 'F33', 'F34', 'F35', 'F36', 'F4', 'F5', 'F6', 'F7',
993 'F8', 'F9', 'FETCH', 'FILE-STATUS', 'FILL', 'FINAL', 'FIRST',
994 'FIRST-DUP', 'FOR', 'GE', 'GET', 'GO', 'GOTO', 'GQ', 'GR', 'GT',
995 'HEADING', 'HEX', 'HIGH-VALUES', 'IDD', 'IDMS', 'IF', 'IN', 'INSERT',
996 'JUSTIFY', 'KANJI-DATE', 'KANJI-DATE-LONG', 'KANJI-TIME', 'KEY',
997 'KEY-PRESSED', 'KOKUGO', 'KUN', 'LAST-DUP', 'LE', 'LEVEL', 'LIKE',
998 'LINE', 'LINE-COUNT', 'LINE-NUMBER', 'LINK', 'LIST', 'LOW-VALUES',
999 'LQ', 'LS', 'LT', 'MACRO', 'MASK', 'MATCHED', 'MEND', 'MESSAGE',
1000 'MOVE', 'MSTART', 'NE', 'NEWPAGE', 'NOMASK', 'NOPRINT', 'NOT',
1001 'NOTE', 'NOVERIFY', 'NQ', 'NULL', 'OF', 'OR', 'OTHERWISE', 'PA1',
1002 'PA2', 'PA3', 'PAGE-COUNT', 'PAGE-NUMBER', 'PARM-REGISTER',
1003 'PATH-ID', 'PATTERN', 'PERFORM', 'POINT', 'POS', 'PRIMARY', 'PRINT',
1004 'PROCEDURE', 'PROGRAM', 'PUT', 'READ', 'RECORD', 'RECORD-COUNT',
1005 'RECORD-LENGTH', 'REFRESH', 'RELEASE', 'RENUM', 'REPEAT', 'REPORT',
1006 'REPORT-INPUT', 'RESHOW', 'RESTART', 'RETRIEVE', 'RETURN-CODE',
1007 'ROLLBACK', 'ROW', 'S', 'SCREEN', 'SEARCH', 'SECONDARY', 'SELECT',
1008 'SEQUENCE', 'SIZE', 'SKIP', 'SOKAKU', 'SORT', 'SQL', 'STOP', 'SUM',
1009 'SYSDATE', 'SYSDATE-LONG', 'SYSIN', 'SYSIPT', 'SYSLST', 'SYSPRINT',
1010 'SYSSNAP', 'SYSTIME', 'TALLY', 'TERM-COLUMNS', 'TERM-NAME',
1011 'TERM-ROWS', 'TERMINATION', 'TITLE', 'TO', 'TRANSFER', 'TRC',
1012 'UNIQUE', 'UNTIL', 'UPDATE', 'UPPERCASE', 'USER', 'USERID', 'VALUE',
1013 'VERIFY', 'W', 'WHEN', 'WHILE', 'WORK', 'WRITE', 'X', 'XDM', 'XRST'
1014 ]
1015
1016 tokens = {
1017 'root': [
1018 (r'\*.*\n', Comment.Single),
1019 (r'\n+', Whitespace),
1020 # Macro argument
1021 (r'&' + _NON_DELIMITER_OR_COMMENT_PATTERN + r'+\.', Name.Variable,
1022 'after_macro_argument'),
1023 # Macro call
1024 (r'%' + _NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name.Variable),
1025 (r'(FILE|MACRO|REPORT)(\s+)',
1026 bygroups(Keyword.Declaration, Whitespace), 'after_declaration'),
1027 (r'(JOB|PARM)' + r'(' + _DELIMITER_PATTERN + r')',
1028 bygroups(Keyword.Declaration, Operator)),
1029 (words(_KEYWORDS, suffix=_DELIMITER_PATTERN_CAPTURE),
1030 bygroups(Keyword.Reserved, Operator)),
1031 (_OPERATORS_PATTERN, Operator),
1032 # Procedure declaration
1033 (r'(' + _NON_DELIMITER_OR_COMMENT_PATTERN + r'+)(\s*)(\.?)(\s*)(PROC)(\s*\n)',
1034 bygroups(Name.Function, Whitespace, Operator, Whitespace,
1035 Keyword.Declaration, Whitespace)),
1036 (r'[0-9]+\.[0-9]*', Number.Float),
1037 (r'[0-9]+', Number.Integer),
1038 (r"'(''|[^'])*'", String),
1039 (r'\s+', Whitespace),
1040 # Everything else just belongs to a name
1041 (_NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name),
1042 ],
1043 'after_declaration': [
1044 (_NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name.Function),
1045 default('#pop'),
1046 ],
1047 'after_macro_argument': [
1048 (r'\*.*\n', Comment.Single, '#pop'),
1049 (r'\s+', Whitespace, '#pop'),
1050 (_OPERATORS_PATTERN, Operator, '#pop'),
1051 (r"'(''|[^'])*'", String, '#pop'),
1052 # Everything else just belongs to a name
1053 (_NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name),
1054 ],
1055 }
1056 _COMMENT_LINE_REGEX = re.compile(r'^\s*\*')
1057 _MACRO_HEADER_REGEX = re.compile(r'^\s*MACRO')
1058
1059 def analyse_text(text):
1060 """
1061 Perform a structural analysis for basic Easytrieve constructs.
1062 """
1063 result = 0.0
1064 lines = text.split('\n')
1065 hasEndProc = False
1066 hasHeaderComment = False
1067 hasFile = False
1068 hasJob = False
1069 hasProc = False
1070 hasParm = False
1071 hasReport = False
1072
1073 def isCommentLine(line):
1074 return EasytrieveLexer._COMMENT_LINE_REGEX.match(lines[0]) is not None
1075
1076 def isEmptyLine(line):
1077 return not bool(line.strip())
1078
1079 # Remove possible empty lines and header comments.
1080 while lines and (isEmptyLine(lines[0]) or isCommentLine(lines[0])):
1081 if not isEmptyLine(lines[0]):
1082 hasHeaderComment = True
1083 del lines[0]
1084
1085 if EasytrieveLexer._MACRO_HEADER_REGEX.match(lines[0]):
1086 # Looks like an Easytrieve macro.
1087 result = 0.4
1088 if hasHeaderComment:
1089 result += 0.4
1090 else:
1091 # Scan the source for lines starting with indicators.
1092 for line in lines:
1093 words = line.split()
1094 if (len(words) >= 2):
1095 firstWord = words[0]
1096 if not hasReport:
1097 if not hasJob:
1098 if not hasFile:
1099 if not hasParm:
1100 if firstWord == 'PARM':
1101 hasParm = True
1102 if firstWord == 'FILE':
1103 hasFile = True
1104 if firstWord == 'JOB':
1105 hasJob = True
1106 elif firstWord == 'PROC':
1107 hasProc = True
1108 elif firstWord == 'END-PROC':
1109 hasEndProc = True
1110 elif firstWord == 'REPORT':
1111 hasReport = True
1112
1113 # Weight the findings.
1114 if hasJob and (hasProc == hasEndProc):
1115 if hasHeaderComment:
1116 result += 0.1
1117 if hasParm:
1118 if hasProc:
1119 # Found PARM, JOB and PROC/END-PROC:
1120 # pretty sure this is Easytrieve.
1121 result += 0.8
1122 else:
1123 # Found PARAM and JOB: probably this is Easytrieve
1124 result += 0.5
1125 else:
1126 # Found JOB and possibly other keywords: might be Easytrieve
1127 result += 0.11
1128 if hasParm:
1129 # Note: PARAM is not a proper English word, so this is
1130 # regarded a much better indicator for Easytrieve than
1131 # the other words.
1132 result += 0.2
1133 if hasFile:
1134 result += 0.01
1135 if hasReport:
1136 result += 0.01
1137 assert 0.0 <= result <= 1.0
1138 return result
1139
1140
1141 class JclLexer(RegexLexer):
1142 """
1143 `Job Control Language (JCL)
1144 <http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IEA2B570/CCONTENTS>`_
1145 is a scripting language used on mainframe platforms to instruct the system
1146 on how to run a batch job or start a subsystem. It is somewhat
1147 comparable to MS DOS batch and Unix shell scripts.
1148
1149 .. versionadded:: 2.1
1150 """
1151 name = 'JCL'
1152 aliases = ['jcl']
1153 filenames = ['*.jcl']
1154 mimetypes = ['text/x-jcl']
1155 flags = re.IGNORECASE
1156
1157 tokens = {
1158 'root': [
1159 (r'//\*.*\n', Comment.Single),
1160 (r'//', Keyword.Pseudo, 'statement'),
1161 (r'/\*', Keyword.Pseudo, 'jes2_statement'),
1162 # TODO: JES3 statement
1163 (r'.*\n', Other) # Input text or inline code in any language.
1164 ],
1165 'statement': [
1166 (r'\s*\n', Whitespace, '#pop'),
1167 (r'([a-z]\w*)(\s+)(exec|job)(\s*)',
1168 bygroups(Name.Label, Whitespace, Keyword.Reserved, Whitespace),
1169 'option'),
1170 (r'[a-z]\w*', Name.Variable, 'statement_command'),
1171 (r'\s+', Whitespace, 'statement_command'),
1172 ],
1173 'statement_command': [
1174 (r'\s+(command|cntl|dd|endctl|endif|else|include|jcllib|'
1175 r'output|pend|proc|set|then|xmit)\s+', Keyword.Reserved, 'option'),
1176 include('option')
1177 ],
1178 'jes2_statement': [
1179 (r'\s*\n', Whitespace, '#pop'),
1180 (r'\$', Keyword, 'option'),
1181 (r'\b(jobparam|message|netacct|notify|output|priority|route|'
1182 r'setup|signoff|xeq|xmit)\b', Keyword, 'option'),
1183 ],
1184 'option': [
1185 # (r'\n', Text, 'root'),
1186 (r'\*', Name.Builtin),
1187 (r'[\[\](){}<>;,]', Punctuation),
1188 (r'[-+*/=&%]', Operator),
1189 (r'[a-z_]\w*', Name),
1190 (r'\d+\.\d*', Number.Float),
1191 (r'\.\d+', Number.Float),
1192 (r'\d+', Number.Integer),
1193 (r"'", String, 'option_string'),
1194 (r'[ \t]+', Whitespace, 'option_comment'),
1195 (r'\.', Punctuation),
1196 ],
1197 'option_string': [
1198 (r"(\n)(//)", bygroups(Text, Keyword.Pseudo)),
1199 (r"''", String),
1200 (r"[^']", String),
1201 (r"'", String, '#pop'),
1202 ],
1203 'option_comment': [
1204 # (r'\n', Text, 'root'),
1205 (r'.+', Comment.Single),
1206 ]
1207 }
1208
1209 _JOB_HEADER_PATTERN = re.compile(r'^//[a-z#$@][a-z0-9#$@]{0,7}\s+job(\s+.*)?$',
1210 re.IGNORECASE)
1211
1212 def analyse_text(text):
1213 """
1214 Recognize JCL job by header.
1215 """
1216 result = 0.0
1217 lines = text.split('\n')
1218 if len(lines) > 0:
1219 if JclLexer._JOB_HEADER_PATTERN.match(lines[0]):
1220 result = 1.0
1221 assert 0.0 <= result <= 1.0
1222 return result

eric ide

mercurial