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