source: utils/developer/fortran.py @ 11781

Last change on this file since 11781 was 11781, checked in by nicolasmartin, 12 months ago

Improve Fortran lexer by creating distinct states for comment, boolean, operator and punctuation
Respectively cmt, bool, opr & punc.

The regexps were from the 'core' state which was reduced to statements, data types and builtins
The punctuation state has evolved to handle & character more wisely:
highlight only if followed by whitespace (continuation line), if not

Tested with tracers.rst which includes routine, namelist and code-block.
Still a small issue with on a specific namelist.

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