diff options
Diffstat (limited to 'lexlua/makefile.lua')
-rw-r--r-- | lexlua/makefile.lua | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/lexlua/makefile.lua b/lexlua/makefile.lua new file mode 100644 index 000000000..061424615 --- /dev/null +++ b/lexlua/makefile.lua @@ -0,0 +1,90 @@ +-- Copyright 2006-2018 Mitchell mitchell.att.foicica.com. See License.txt. +-- Makefile 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('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) +lex:add_rule('target', lexer.starts_line((special_target + normal_target) * + ws^0 * #(':' * -P('=')))) +lex:add_style('target', lexer.STYLE_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('@%<?^+|*') +local special_var = word_match[[ + MAKEFILE_LIST .DEFAULT_GOAL MAKE_RESTARTS .RECIPEPREFIX .VARIABLES .FEATURES + .INCLUDE_DIRS GPATH MAKECMDGOALS MAKESHELL SHELL VPATH +]] * #(ws^0 * assign) +local implicit_var = word_match[[ + -- Some common variables. + AR AS CC CXX CPP FC M2C PC CO GET LEX YACC LINT MAKEINFO TEX TEXI2DVI WEAVE + CWEAVE TANGLE CTANGLE RM + -- Some common flag variables. + ARFLAGS ASFLAGS CFLAGS CXXFLAGS COFLAGS CPPFLAGS FFLAGS GFLAGS LDFLAGS LFLAGS + YFLAGS PFLAGS RFLAGS LINTFLAGS + -- Other. + DESTDIR MAKE MAKEFLAGS MAKEOVERRIDES MFLAGS +]] * #(ws^0 * assign) +local computed_var = token(lexer.OPERATOR, '$' * S('({')) * + token(lexer.FUNCTION, word_match[[ + -- Functions for String Substitution and Analysis. + subst patsubst strip findstring filter filter-out sort word wordlist words + firstword lastword + -- Functions for File Names. + dir notdir suffix basename addsuffix addprefix join wildcard realpath abspath + -- Functions for Conditionals. + if or and + -- Miscellaneous Functions. + foreach call value eval origin flavor shell + -- Functions That Control Make. + error warning info +]]) +local variable = token(lexer.VARIABLE, expanded_var + auto_var + special_var + + implicit_var) + computed_var +lex:add_rule('variable', variable) + +-- Operators. +lex:add_rule('operator', token(lexer.OPERATOR, assign + S(':$(){}'))) + +-- Identifiers. +lex:add_rule('identifier', token(lexer.IDENTIFIER, word_char^1)) + +-- Comments. +lex:add_rule('comment', token(lexer.COMMENT, '#' * lexer.nonnewline^0)) + +-- Embedded Bash. +local bash = lexer.load('bash') +bash:modify_rule('variable', token(lexer.VARIABLE, '$$' * word_char^1) + + bash:get_rule('variable') + variable) +local bash_start_rule = token(lexer.WHITESPACE, P('\t')) + + token(lexer.OPERATOR, P(';')) +local bash_end_rule = token(lexer.WHITESPACE, P('\n')) +lex:embed(bash, bash_start_rule, bash_end_rule) + +return lex |