source: utils/developer/fortran.py @ 11801

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

Add some syntax patterns to highlight

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