aboutsummaryrefslogtreecommitdiffhomepage
path: root/lexlua/makefile.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lexlua/makefile.lua')
-rw-r--r--lexlua/makefile.lua90
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