-- Copyright 2006-2022 Mitchell. See LICENSE. -- Makefile LPeg lexer. local lexer = require('lexer') local token, word_match = lexer.token, lexer.word_match local P, S = lpeg.P, lpeg.S local lex = lexer.new('makefile', {lex_by_line = true}) -- Whitespace. local ws = token(lexer.WHITESPACE, lexer.space^1) lex:add_rule('whitespace', ws) -- Keywords. lex:add_rule('keyword', token(lexer.KEYWORD, P('!')^-1 * word_match({ -- GNU Make conditionals. 'ifeq', 'ifneq', 'ifdef', 'ifndef', 'else', 'endif', -- Other conditionals. 'if', 'elseif', 'elseifdef', 'elseifndef', -- Directives and other keywords. 'define', 'endef', 'export', 'include', 'override', 'private', 'undefine', 'unexport', 'vpath' }, true))) -- Targets. local special_target = token(lexer.CONSTANT, word_match{ '.PHONY', '.SUFFIXES', '.DEFAULT', '.PRECIOUS', '.INTERMEDIATE', '.SECONDARY', '.SECONDEXPANSION', '.DELETE_ON_ERROR', '.IGNORE', '.LOW_RESOLUTION_TIME', '.SILENT', '.EXPORT_ALL_VARIABLES', '.NOTPARALLEL', '.ONESHELL', '.POSIX' }) local normal_target = token('target', (lexer.any - lexer.space - S(':#='))^1) local target_list = normal_target * (ws * normal_target)^0 lex:add_rule('target', lexer.starts_line((special_target + target_list) * ws^0 * #(':' * -P('=')))) lex:add_style('target', lexer.styles.label) -- Variables. local word_char = lexer.any - lexer.space - S(':#=(){}') local assign = S(':+?')^-1 * '=' local expanded_var = '$' * ('(' * word_char^1 * ')' + '{' * word_char^1 * '}') local auto_var = '$' * S('@%