source: utils/developer/fortran.py @ 11779

Last change on this file since 11779 was 11779, checked in by nicolasmartin, 18 months ago

Create 'namelist' state to handle highlighting of this particular statement
Probably not optimized but it works.

The line have to start with the expecting syntax for declaring a namelist &[a-z][\w$]*
The token type that seems appropriate is the namespace (Name.Namespace).
The declaration of variables, arrays and data structures are taken into account in the same regexp
with bygroups
The slash terminator to end the namelist will also be colorized to make some kind of an envelope
surrounding the variables and arrays.

File size: 10.3 KB
Line 
1# -*- coding: utf-8 -*-
2"""
3    pygments.lexers.fortran
4    ~~~~~~~~~~~~~~~~~~~~~~~
5
6    Lexers for Fortran languages.
7
8    :copyright: Copyright 2006-2019 by the Pygments team, see AUTHORS.
9    :license: BSD, see LICENSE for details.
10"""
11
12import re
13
14from pygments.lexer import RegexLexer, bygroups, include, words, using, default
15from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
16    Number, Punctuation, Generic
17
18__all__ = ['FortranLexer', 'FortranFixedLexer']
19
20
21class FortranLexer(RegexLexer):
22    """
23    Lexer for FORTRAN 90 code.
24
25    .. versionadded:: 0.10
26    """
27    name = 'Fortran'
28    aliases = ['fortran']
29    filenames = ['*.f03', '*.f90', '*.F03', '*.F90']
30    mimetypes = ['text/x-fortran']
31    flags = re.IGNORECASE | re.MULTILINE
32
33    # Data Types: INTEGER, REAL, COMPLEX, LOGICAL, CHARACTER and DOUBLE PRECISION
34    # Operators: **, *, +, -, /, <, >, <=, >=, ==, /=
35    # Logical (?): NOT, AND, OR, EQV, NEQV
36
37    # Builtins:
38    # http://gcc.gnu.org/onlinedocs/gcc-3.4.6/g77/Table-of-Intrinsic-Functions.html
39
40    tokens = {
41        'root': [
42            (r'^#.*\n', Comment.Preproc),
43            (r'^&[a-z]\w*', Name.Namespace, 'namelist'),
44            (r'!.*\n', Comment),
45            include('strings'),
46            include('core'),
47            (r'[a-z][\w$]*', Name),
48            include('nums'),
49            (r'[\s]+', Text),
50        ],
51        'core': [
52            # Statements
53            (words((
54                'ABSTRACT', 'ACCEPT', 'ALL', 'ALLSTOP', 'ALLOCATABLE', 'ALLOCATE',
55                'ARRAY', 'ASSIGN', 'ASSOCIATE', 'ASYNCHRONOUS', 'BACKSPACE', 'BIND',
56                'BLOCK', 'BLOCKDATA', 'BYTE', 'CALL', 'CASE', 'CLASS', 'CLOSE',
57                'CODIMENSION', 'COMMON', 'CONCURRRENT', 'CONTIGUOUS', 'CONTAINS',
58                'CONTINUE', 'CRITICAL', 'CYCLE', 'DATA', 'DEALLOCATE', 'DECODE',
59                'DEFERRED', 'DIMENSION', 'DO', 'ELEMENTAL', 'ELSE', 'ENCODE', 'END', 'ENDIF',
60                'ENTRY', 'ENUM', 'ENUMERATOR', 'EQUIVALENCE', 'EXIT', 'EXTENDS',
61                'EXTERNAL', 'EXTRINSIC', 'FILE', 'FINAL', 'FORALL', 'FORMAT',
62                'FUNCTION', 'GENERIC', 'GOTO', 'IF', 'IMAGES', 'IMPLICIT',
63                'IMPORT', 'IMPURE', 'INCLUDE', 'INQUIRE', 'INTENT', 'INTERFACE',
64                'INTRINSIC', 'IS', 'LOCK', 'MEMORY', 'MODULE', 'NAMELIST', 'NULLIFY',
65                'NONE', 'NON_INTRINSIC', 'NON_OVERRIDABLE', 'NOPASS', 'OPEN', 'OPTIONAL',
66                'OPTIONS', 'PARAMETER', 'PASS', 'PAUSE', 'POINTER', 'PRINT', 'PRIVATE',
67                'PROGRAM', 'PROCEDURE', 'PROTECTED', 'PUBLIC', 'PURE', 'READ',
68                'RECURSIVE', 'RESULT', 'RETURN', 'REWIND', 'SAVE', 'SELECT', 'SEQUENCE',
69                'STOP', 'SUBMODULE', 'SUBROUTINE', 'SYNC', 'SYNCALL', 'SYNCIMAGES',
70                'SYNCMEMORY', 'TARGET', 'THEN', 'TYPE', 'UNLOCK', 'USE', 'VALUE',
71                'VOLATILE', 'WHERE', 'WRITE', 'WHILE'), prefix=r'\b', suffix=r'\s*\b'),
72             Keyword),
73
74            # Data Types
75            (words((
76                'CHARACTER', 'COMPLEX', 'DOUBLE PRECISION', 'DOUBLE COMPLEX', 'INTEGER',
77                'LOGICAL', 'REAL', 'C_INT', 'C_SHORT', 'C_LONG', 'C_LONG_LONG',
78                'C_SIGNED_CHAR', 'C_SIZE_T', 'C_INT8_T', 'C_INT16_T', 'C_INT32_T',
79                'C_INT64_T', 'C_INT_LEAST8_T', 'C_INT_LEAST16_T', 'C_INT_LEAST32_T',
80                'C_INT_LEAST64_T', 'C_INT_FAST8_T', 'C_INT_FAST16_T', 'C_INT_FAST32_T',
81                'C_INT_FAST64_T', 'C_INTMAX_T', 'C_INTPTR_T', 'C_FLOAT', 'C_DOUBLE',
82                'C_LONG_DOUBLE', 'C_FLOAT_COMPLEX', 'C_DOUBLE_COMPLEX',
83                'C_LONG_DOUBLE_COMPLEX', 'C_BOOL', 'C_CHAR', 'C_PTR', 'C_FUNPTR'),
84                   prefix=r'\b', suffix=r'\s*\b'),
85             Keyword.Type),
86
87            # Operators
88            (r'(\*\*|\*|\+|-|\/|<|>|<=|>=|==|\/=|=)', Operator),
89
90            #
91            (r'(::)', Keyword.Declaration),
92
93            # Intrinsics
94            (words((
95                'Abort', 'Abs', 'Access', 'AChar', 'ACos', 'ACosH', 'AdjustL',
96                'AdjustR', 'AImag', 'AInt', 'Alarm', 'All', 'Allocated', 'ALog',
97                'AMax', 'AMin', 'AMod', 'ANInt', 'Any', 'ASin', 'ASinH',
98                'Associated', 'ATan', 'ATanH', 'Atomic_Define', 'Atomic_Ref',
99                'BesJ', 'BesJN', 'Bessel_J0', 'Bessel_J1', 'Bessel_JN', 'Bessel_Y0',
100                'Bessel_Y1', 'Bessel_YN', 'BesY', 'BesYN', 'BGE', 'BGT', 'BLE',
101                'BLT', 'Bit_Size', 'BTest', 'CAbs', 'CCos', 'Ceiling', 'CExp',
102                'Char', 'ChDir', 'ChMod', 'CLog', 'Cmplx', 'Command_Argument_Count',
103                'Complex', 'Conjg', 'Cos', 'CosH', 'Count', 'CPU_Time', 'CShift',
104                'CSin', 'CSqRt', 'CTime', 'C_Loc', 'C_Associated',
105                'C_Null_Ptr', 'C_Null_Funptr', 'C_F_Pointer', 'C_F_ProcPointer',
106                'C_Null_Char', 'C_Alert', 'C_Backspace', 'C_Form_Feed', 'C_FunLoc',
107                'C_Sizeof', 'C_New_Line', 'C_Carriage_Return',
108                'C_Horizontal_Tab', 'C_Vertical_Tab', 'DAbs', 'DACos', 'DASin',
109                'DATan', 'Date_and_Time', 'DbesJ', 'DbesJN', 'DbesY',
110                'DbesYN', 'Dble', 'DCos', 'DCosH', 'DDiM', 'DErF',
111                'DErFC', 'DExp', 'Digits', 'DiM', 'DInt', 'DLog', 'DMax',
112                'DMin', 'DMod', 'DNInt', 'Dot_Product', 'DProd', 'DSign', 'DSinH',
113                'DShiftL', 'DShiftR', 'DSin', 'DSqRt', 'DTanH', 'DTan', 'DTime',
114                'EOShift', 'Epsilon', 'ErF', 'ErFC', 'ErFC_Scaled', 'ETime',
115                'Execute_Command_Line', 'Exit', 'Exp', 'Exponent', 'Extends_Type_Of',
116                'FDate', 'FGet', 'FGetC', 'FindLoc', 'Float', 'Floor', 'Flush',
117                'FNum', 'FPutC', 'FPut', 'Fraction', 'FSeek', 'FStat', 'FTell',
118                'Gamma', 'GError', 'GetArg', 'Get_Command', 'Get_Command_Argument',
119                'Get_Environment_Variable', 'GetCWD', 'GetEnv', 'GetGId', 'GetLog',
120                'GetPId', 'GetUId', 'GMTime', 'HostNm', 'Huge', 'Hypot', 'IAbs',
121                'IAChar', 'IAll', 'IAnd', 'IAny', 'IArgC', 'IBClr', 'IBits',
122                'IBSet', 'IChar', 'IDate', 'IDiM', 'IDInt', 'IDNInt', 'IEOr',
123                'IErrNo', 'IFix', 'Imag', 'ImagPart', 'Image_Index', 'Index',
124                'Int', 'IOr', 'IParity', 'IRand', 'IsaTty', 'IShft', 'IShftC',
125                'ISign', 'Iso_C_Binding', 'Is_Contiguous', 'Is_Iostat_End',
126                'Is_Iostat_Eor', 'ITime', 'Kill', 'Kind', 'LBound', 'LCoBound',
127                'Len', 'Len_Trim', 'LGe', 'LGt', 'Link', 'LLe', 'LLt', 'LnBlnk',
128                'Loc', 'Log', 'Log_Gamma', 'Logical', 'Long', 'LShift', 'LStat',
129                'LTime', 'MaskL', 'MaskR', 'MatMul', 'Max', 'MaxExponent',
130                'MaxLoc', 'MaxVal', 'MClock', 'Merge', 'Merge_Bits', 'Move_Alloc',
131                'Min', 'MinExponent', 'MinLoc', 'MinVal', 'Mod', 'Modulo', 'MvBits',
132                'Nearest', 'New_Line', 'NInt', 'Norm2', 'Null', 'Num_Images',
133                'Pack', 'Parity', 'PError', 'Precision', 'Present', 'Product',
134                'Radix', 'Rand', 'Random_Number', 'Random_Seed', 'Range', 'Real',
135                'RealPart', 'Rename', 'Repeat', 'Reshape', 'RRSpacing', 'RShift',
136                'Same_Type_As', 'Scale', 'Scan', 'Second', 'Selected_Char_Kind',
137                'Selected_Int_Kind', 'Selected_Real_Kind', 'Set_Exponent', 'Shape',
138                'ShiftA', 'ShiftL', 'ShiftR', 'Short', 'Sign', 'Signal', 'SinH',
139                'Sin', 'Sleep', 'Sngl', 'Spacing', 'Spread', 'SqRt', 'SRand',
140                'Stat', 'Storage_Size', 'Sum', 'SymLnk', 'System', 'System_Clock',
141                'Tan', 'TanH', 'Time', 'This_Image', 'Tiny', 'TrailZ', 'Transfer',
142                'Transpose', 'Trim', 'TtyNam', 'UBound', 'UCoBound', 'UMask',
143                'Unlink', 'Unpack', 'Verify', 'XOr', 'ZAbs', 'ZCos', 'ZExp',
144                'ZLog', 'ZSin', 'ZSqRt'), prefix=r'\b', suffix=r'\s*\b'),
145             Name.Builtin),
146
147            # Booleans
148            (r'\.(true|false)\.', Name.Builtin),
149
150            # Comparing Operators
151            (r'\.(eq|ne|lt|le|gt|ge|not|and|or|eqv|neqv)\.', Operator.Word),
152
153            # Punctuation
154            (r'[()\[\],:&%;.]', Punctuation),
155        ],
156        'namelist': [
157            (r'!.*\n', Comment),
158            (r'([a-z]\w*)(\()?(\s*)?(\d*)?(\s*)?(\))?(%[a-z]\w*)?(\s*)(=)', bygroups(
159               Name.Variable, Punctuation, Text, Number.Integer, Text, Punctuation, 
160               Name.Variable, Text, Operator)),
161            (r'(\*\*|\*|\+|-|\/|<|>|<=|>=|==|\/=|=)', Operator),
162            (r'\.(true|false)\.', Name.Builtin),
163            include('strings'),
164            include('nums'),
165            (r'[()\[\],:&%;.]', Punctuation),
166            (r'[\s]+', Text),
167            (r'^\/$', Name.Namespace),
168        ],
169        'strings': [
170            (r'(?s)"(\\\\|\\[0-7]+|\\.|[^"\\])*"', String.Double),
171            (r"(?s)'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single),
172        ],
173        'nums': [
174            (r'\d+(?![.e])(_[a-z]\w+)?', Number.Integer),
175            (r'[+-]?\d*\.\d+([ed][-+]?\d+)?(_[a-z]\w+)?', Number.Float),
176            (r'[+-]?\d+\.\d*([ed][-+]?\d+)?(_[a-z]\w+)?', Number.Float),
177            (r'[+-]?\d+(\.\d*)?[ed][-+]?\d+(_[a-z]\w+)?', Number.Float),
178        ],
179    }
180
181
182class FortranFixedLexer(RegexLexer):
183    """
184    Lexer for fixed format Fortran.
185
186    .. versionadded:: 2.1
187    """
188    name = 'FortranFixed'
189    aliases = ['fortranfixed']
190    filenames = ['*.f', '*.F']
191
192    flags = re.IGNORECASE
193
194    def _lex_fortran(self, match, ctx=None):
195        """Lex a line just as free form fortran without line break."""
196        lexer = FortranLexer()
197        text = match.group(0) + "\n"
198        for index, token, value in lexer.get_tokens_unprocessed(text):
199            value = value.replace('\n', '')
200            if value != '':
201                yield index, token, value
202
203    tokens = {
204        'root': [
205            (r'[C*].*\n', Comment),
206            (r'#.*\n', Comment.Preproc),
207            (r' {0,4}!.*\n', Comment),
208            (r'(.{5})', Name.Label, 'cont-char'),
209            (r'.*\n', using(FortranLexer)),
210        ],
211        'cont-char': [
212            (' ', Text, 'code'),
213            ('0', Comment, 'code'),
214            ('.', Generic.Strong, 'code'),
215        ],
216        'code': [
217            (r'(.{66})(.*)(\n)',
218             bygroups(_lex_fortran, Comment, Text), 'root'),
219            (r'(.*)(\n)', bygroups(_lex_fortran, Text), 'root'),
220            default('root'),
221        ]
222    }
Note: See TracBrowser for help on using the repository browser.