1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
# -*- coding: utf-8 -*- #
# frozen_string_literal: true
module Rouge
module Lexers
class Make < RegexLexer
title "Make"
desc "Makefile syntax"
tag 'make'
aliases 'makefile', 'mf', 'gnumake', 'bsdmake'
filenames '*.make', '*.mak', '*.mk', 'Makefile', 'makefile', 'Makefile.*', 'GNUmakefile', '*,fe1'
mimetypes 'text/x-makefile'
def self.functions
@functions ||= %w(
abspath addprefix addsuffix and basename call dir error eval file
filter filter-out findstring firstword flavor foreach if join lastword
notdir or origin patsubst realpath shell sort strip subst suffix value
warning wildcard word wordlist words
)
end
def initialize(opts={})
super
@shell = Shell.new(opts)
end
start { @shell.reset! }
state :root do
rule %r/\s+/, Text
rule %r/#.*?\n/, Comment
rule %r/([-s]?include)((?:[\t ]+[^\t\n #]+)+)/ do
groups Keyword, Literal::String::Other
end
rule %r/((?:ifn?def|ifn?eq|unexport)\b)([\t ]+)([^#\n]+)/ do
groups Keyword, Text, Name::Variable
end
rule %r/(else\b)([\t ]+)((?:ifn?def|ifn?eq)\b)([\t ]+)([^#\n]+)/ do
groups Keyword, Text, Keyword, Text, Name::Variable
end
rule %r/(?:else|endif|endef|endfor)[\t ]*(?=[#\n])/, Keyword
rule %r/(export)([\t ]+)(?=[\w\${}()\t -]+\n)/ do
groups Keyword, Text
push :export
end
rule %r/export[\t ]+/, Keyword
# assignment
rule %r/(override\b)*([\t ]*)([\w${}().-]+)([\t ]*)([!?:+]?=)/m do |m|
groups Name::Builtin, Text, Name::Variable, Text, Operator
push :shell_line
end
rule %r/"(\\\\|\\.|[^"\\])*"/, Str::Double
rule %r/'(\\\\|\\.|[^'\\])*'/, Str::Single
rule %r/([^\n:]+)(:+)([ \t]*)/ do
groups Name::Label, Operator, Text
push :block_header
end
rule %r/(override\b)*([\t ])*(define)([\t ]+)([^#\n]+)/ do
groups Name::Builtin, Text, Keyword, Text, Name::Variable
end
rule %r/(\$[({])([\t ]*)(#{Make.functions.join('|')})([\t ]+)/m do
groups Name::Function, Text, Name::Builtin, Text
push :shell_expr
end
end
state :export do
rule %r/[\w\${}()-]/, Name::Variable
rule %r/\n/, Text, :pop!
rule %r/[\t ]+/, Text
end
state :block_header do
rule %r/[^,\\\n#]+/, Name::Function
rule %r/,/, Punctuation
rule %r/#.*?/, Comment
rule %r/\\\n/, Text
rule %r/\\./, Text
rule %r/\n/ do
token Text
goto :block_body
end
end
state :block_body do
rule %r/(ifn?def|ifn?eq)([\t ]+)([^#\n]+)(#.*)?(\n)/ do
groups Keyword, Text, Name::Variable, Comment, Text
end
rule %r/(else|endif)([\t ]*)(#.*)?(\n)/ do
groups Keyword, Text, Comment, Text
end
rule %r/(\t[\t ]*)([@-]?)/ do
groups Text, Punctuation
push :shell_line
end
rule(//) { @shell.reset!; pop! }
end
state :shell do
# macro interpolation
rule %r/[\$]{1,2}[({]/, Punctuation, :macro_expr
# function invocation
rule %r/(\$[({])([\t ]*)(#{Make.functions.join('|')})([\t ]+)/m do
groups Punctuation, Text, Name::Builtin, Text
push :shell_expr
end
rule(/\\./m) { delegate @shell }
stop = /[\$]{1,2}\(|[\$]{1,2}\{|\(|\)|\}|\\|$/
rule(/.+?(?=#{stop})/m) { delegate @shell }
rule(stop) { delegate @shell }
end
state :macro_expr do
rule %r/[)}]/, Punctuation, :pop!
rule %r/\n/, Text, :pop!
mixin :shell
end
state :shell_expr do
rule(/[({]/) { delegate @shell; push }
rule %r/[)}]/, Punctuation, :pop!
mixin :shell
end
state :shell_line do
rule %r/\n/, Text, :pop!
mixin :shell
end
end
end
end
|