1"""
2 pygments.lexers.snobol
3 ~~~~~~~~~~~~~~~~~~~~~~
4
5 Lexers for the SNOBOL language.
6
7 :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9"""
10
11from pygments.lexer import RegexLexer, bygroups
12from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
13 Number, Punctuation
14
15__all__ = ['SnobolLexer']
16
17
18class SnobolLexer(RegexLexer):
19 """
20 Lexer for the SNOBOL4 programming language.
21
22 Recognizes the common ASCII equivalents of the original SNOBOL4 operators.
23 Does not require spaces around binary operators.
24 """
25
26 name = "Snobol"
27 aliases = ["snobol"]
28 filenames = ['*.snobol']
29 mimetypes = ['text/x-snobol']
30 url = 'https://www.regressive.org/snobol4'
31 version_added = '1.5'
32
33 tokens = {
34 # root state, start of line
35 # comments, continuation lines, and directives start in column 1
36 # as do labels
37 'root': [
38 (r'\*.*\n', Comment),
39 (r'[+.] ', Punctuation, 'statement'),
40 (r'-.*\n', Comment),
41 (r'END\s*\n', Name.Label, 'heredoc'),
42 (r'[A-Za-z$][\w$]*', Name.Label, 'statement'),
43 (r'\s+', Text, 'statement'),
44 ],
45 # statement state, line after continuation or label
46 'statement': [
47 (r'\s*\n', Text, '#pop'),
48 (r'\s+', Text),
49 (r'(?<=[^\w.])(LT|LE|EQ|NE|GE|GT|INTEGER|IDENT|DIFFER|LGT|SIZE|'
50 r'REPLACE|TRIM|DUPL|REMDR|DATE|TIME|EVAL|APPLY|OPSYN|LOAD|UNLOAD|'
51 r'LEN|SPAN|BREAK|ANY|NOTANY|TAB|RTAB|REM|POS|RPOS|FAIL|FENCE|'
52 r'ABORT|ARB|ARBNO|BAL|SUCCEED|INPUT|OUTPUT|TERMINAL)(?=[^\w.])',
53 Name.Builtin),
54 (r'[A-Za-z][\w.]*', Name),
55 # ASCII equivalents of original operators
56 # | for the EBCDIC equivalent, ! likewise
57 # \ for EBCDIC negation
58 (r'\*\*|[?$.!%*/#+\-@|&\\=]', Operator),
59 (r'"[^"]*"', String),
60 (r"'[^']*'", String),
61 # Accept SPITBOL syntax for real numbers
62 # as well as Macro SNOBOL4
63 (r'[0-9]+(?=[^.EeDd])', Number.Integer),
64 (r'[0-9]+(\.[0-9]*)?([EDed][-+]?[0-9]+)?', Number.Float),
65 # Goto
66 (r':', Punctuation, 'goto'),
67 (r'[()<>,;]', Punctuation),
68 ],
69 # Goto block
70 'goto': [
71 (r'\s*\n', Text, "#pop:2"),
72 (r'\s+', Text),
73 (r'F|S', Keyword),
74 (r'(\()([A-Za-z][\w.]*)(\))',
75 bygroups(Punctuation, Name.Label, Punctuation))
76 ],
77 # everything after the END statement is basically one
78 # big heredoc.
79 'heredoc': [
80 (r'.*\n', String.Heredoc)
81 ]
82 }