-- Copyright 2006-2019 Mitchell mitchell.att.foicica.com. See License.txt. -- Fortran LPeg lexer. local lexer = require('lexer') local token, word_match = lexer.token, lexer.word_match local P, R, S = lpeg.P, lpeg.R, lpeg.S local lex = lexer.new('fortran') -- Whitespace. lex:add_rule('whitespace', token(lexer.WHITESPACE, lexer.space^1)) -- Comments. local c_comment = lexer.starts_line(S('Cc')) * lexer.nonnewline^0 local d_comment = lexer.starts_line(S('Dd')) * lexer.nonnewline^0 local ex_comment = lexer.starts_line('!') * lexer.nonnewline^0 local ast_comment = lexer.starts_line('*') * lexer.nonnewline^0 local line_comment = '!' * lexer.nonnewline^0 lex:add_rule('comment', token(lexer.COMMENT, c_comment + d_comment + ex_comment + ast_comment + line_comment)) -- Keywords. lex:add_rule('keyword', token(lexer.KEYWORD, word_match([[ include program module subroutine function contains use call return -- Statements. case select default continue cycle do while else if elseif then elsewhere end endif enddo forall where exit goto pause stop -- Operators. .not. .and. .or. .xor. .eqv. .neqv. .eq. .ne. .gt. .ge. .lt. .le. -- Logical. .false. .true. ]], true))) -- Functions. lex:add_rule('function', token(lexer.FUNCTION, word_match([[ -- I/O. backspace close endfile inquire open print read rewind write format -- Type conversion utility and math. aimag aint amax0 amin0 anint ceiling cmplx conjg dble dcmplx dfloat dim dprod float floor ifix imag int logical modulo nint real sign sngl transfer zext abs acos aimag aint alog alog10 amax0 amax1 amin0 amin1 amod anint asin atan atan2 cabs ccos char clog cmplx conjg cos cosh csin csqrt dabs dacos dasin datan datan2 dble dcos dcosh ddim dexp dim dint dlog dlog10 dmax1 dmin1 dmod dnint dprod dreal dsign dsin dsinh dsqrt dtan dtanh exp float iabs ichar idim idint idnint ifix index int isign len lge lgt lle llt log log10 max max0 max1 min min0 min1 mod nint real sign sin sinh sngl sqrt tan tanh ]], true))) -- Types. lex:add_rule('type', token(lexer.TYPE, word_match([[ implicit explicit none data parameter allocate allocatable allocated deallocate integer real double precision complex logical character dimension kind ]], true))) -- Numbers. lex:add_rule('number', token(lexer.NUMBER, (lexer.float + lexer.integer) * -lexer.alpha)) -- Identifiers. lex:add_rule('identifier', token(lexer.IDENTIFIER, lexer.alnum^1)) -- Strings. local sq_str = lexer.delimited_range("'", true, true) local dq_str = lexer.delimited_range('"', true, true) lex:add_rule('string', token(lexer.STRING, sq_str + dq_str)) -- Operators. lex:add_rule('operator', token(lexer.OPERATOR, S('<>=&+-/*,()'))) return lex