logo

oasis-root

Compiled tree of Oasis Linux based on own branch at <https://hacktivis.me/git/oasis/> git clone https://anongit.hacktivis.me/git/oasis-root.git

makefile.lua (5111B)


  1. -- Copyright 2006-2024 Mitchell. See LICENSE.
  2. -- Makefile LPeg lexer.
  3. local lexer = lexer
  4. local P, S, B = lpeg.P, lpeg.S, lpeg.B
  5. local lex = lexer.new(..., {lex_by_line = true})
  6. -- Function definition.
  7. local word = (lexer.any - lexer.space - S('$:,#=(){}'))^1
  8. local func_name = lex:tag(lexer.FUNCTION, word)
  9. local ws = lex:get_rule('whitespace')
  10. local eq = lex:tag(lexer.OPERATOR, '=')
  11. lex:add_rule('function_def',
  12. lex:tag(lexer.KEYWORD, lexer.word_match('define')) * ws * func_name * ws^-1 * eq)
  13. -- Keywords.
  14. lex:add_rule('keyword', lex:tag(lexer.KEYWORD, P('!')^-1 * lex:word_match(lexer.KEYWORD, true)))
  15. -- Targets.
  16. local special_target = lex:tag(lexer.CONSTANT_BUILTIN, '.' * lex:word_match('special_targets'))
  17. -- local normal_target = lex:tag('target', (lexer.any - lexer.space - S(':+?!=#'))^1)
  18. local target = special_target -- + normal_target * (ws * normal_target)^0
  19. lex:add_rule('target', lexer.starts_line(target * ws^-1 * #(':' * lexer.space)))
  20. -- Variable and function assignments.
  21. local func_assign = func_name * ws^-1 * eq *
  22. #P(function(input, index) return input:find('%$%(%d%)', index) end)
  23. local builtin_var = lex:tag(lexer.VARIABLE_BUILTIN, lex:word_match(lexer.VARIABLE_BUILTIN))
  24. local var_name = lex:tag(lexer.VARIABLE, word)
  25. local var_assign = (builtin_var + var_name) * ws^-1 *
  26. lex:tag(lexer.OPERATOR, S(':+?!')^-1 * '=' + '::=')
  27. lex:add_rule('assign', lexer.starts_line(func_assign + var_assign, true) + B(': ') * var_assign)
  28. -- Operators.
  29. lex:add_rule('operator', lex:tag(lexer.OPERATOR, S(':(){}|')))
  30. -- Strings.
  31. lex:add_rule('string', lexer.range("'", true) + lexer.range('"', true))
  32. -- Identifiers.
  33. lex:add_rule('identifier', lex:tag(lexer.IDENTIFIER, word))
  34. -- Functions.
  35. local builtin_func = lex:tag(lexer.FUNCTION_BUILTIN, lex:word_match(lexer.FUNCTION_BUILTIN))
  36. local call_func = lex:tag(lexer.FUNCTION_BUILTIN, 'call') * ws * func_name
  37. local func = lex:tag(lexer.OPERATOR, '$' * S('({')) * (call_func + builtin_func)
  38. lex:add_rule('function', func)
  39. -- Variables.
  40. local auto_var = lex:tag(lexer.OPERATOR, '$') * lex:tag(lexer.VARIABLE_BUILTIN, S('@%<?^+|*')) +
  41. lex:tag(lexer.OPERATOR, '$(') * lex:tag(lexer.VARIABLE_BUILTIN, S('@%<?^+*') * S('DF'))
  42. local var_ref = lex:tag(lexer.OPERATOR, P('$(') + '${') * (builtin_var + var_name)
  43. local var = auto_var + var_ref
  44. lex:add_rule('variable', var)
  45. -- Comments.
  46. lex:add_rule('comment', lex:tag(lexer.COMMENT, lexer.to_eol('#')))
  47. -- Embedded Bash in target rules.
  48. local bash = lexer.load('bash')
  49. bash:modify_rule('variable',
  50. lex:tag(lexer.VARIABLE, '$$' * word) + func + var + bash:get_rule('variable'))
  51. local bash_start_rule = lex:tag(lexer.WHITESPACE, '\t') + lex:tag(lexer.OPERATOR, ';')
  52. local bash_end_rule = lex:tag(lexer.WHITESPACE, '\n')
  53. lex:embed(bash, bash_start_rule, bash_end_rule)
  54. -- Embedded Bash in $(shell ...) calls.
  55. local shell = lexer.load('bash', 'bash.shell')
  56. bash_start_rule = #P('$(shell') * func
  57. bash_end_rule = -B('\\') * lex:tag(lexer.OPERATOR, ')')
  58. lex:embed(shell, bash_start_rule, bash_end_rule)
  59. -- Word lists.
  60. lex:set_word_list(lexer.KEYWORD, {
  61. 'define', 'endef', -- multi-line
  62. 'else', 'endif', 'ifdef', 'ifeq', 'ifndef', 'ifneq', -- conditionals
  63. 'export', 'include', 'load', 'override', 'undefine', 'unexport', 'vpath', -- directives
  64. 'private', --
  65. 'if', 'elseif', 'elseifdef', 'elseifndef' -- non-Make conditionals
  66. })
  67. lex:set_word_list('special_targets', {
  68. 'DEFAULT', 'DELETE_ON_ERROR', 'EXPORT_ALL_VARIABLES', 'IGNORE', 'INTERMEDIATE',
  69. 'LOW_RESOLUTION_TIME', 'NOTPARALLEL', 'ONESHELL', 'PHONY', 'POSIX', 'PRECIOUS', 'SECONDARY',
  70. 'SECONDEXPANSION', 'SILENT', 'SUFFIXES'
  71. })
  72. lex:set_word_list(lexer.VARIABLE_BUILTIN, {
  73. -- Special.
  74. '.DEFAULT_GOAL', '.FEATURES', '.INCLUDE_DIRS', '.LIBPATTERNS', '.LOADED', '.RECIPEPREFIX',
  75. '.SHELLFLAGS', '.SHELLSTATUS', '.VARIABLES', --
  76. 'COMSPEC', 'MAKESHELL', 'SHELL', -- choosing the shell
  77. 'GPATH', 'VPATH', -- search
  78. -- Make.
  79. 'MAKE', 'MAKECMDGOALS', 'MAKEFILES', 'MAKEFILE_LIST', 'MAKEFLAGS', 'MAKELEVEL', 'MAKEOVERRIDES',
  80. 'MAKE_RESTARTS', 'MAKE_TERMERR', 'MAKE_TERMOUT', 'MFLAGS',
  81. -- Other.
  82. 'CURDIR', 'OUTPUT_OPTION', 'SUFFIXES',
  83. -- Implicit.
  84. 'AR', 'ARFLAGS', 'AS', 'ASFLAGS', 'CC', 'CFLAGS', 'CO', 'COFLAGS', 'CPP', 'CPPFLAGS', 'CTANGLE',
  85. 'CWEAVE', 'CXX', 'CXXFLAGS', 'FC', 'FFLAGS', 'GET', 'GFLAGS', 'LDFLAGS', 'LDLIBS', 'LEX',
  86. 'LFLAGS', 'LINT', 'LINTFLAGS', 'M2C', 'MAKEINFO', 'PC', 'PFLAGS', 'RFLAGS', 'RM', 'TANGLE', 'TEX',
  87. 'TEXI2DVI', 'WEAVE', 'YACC', 'YFLAGS', --
  88. 'bindir', 'DESTDIR', 'exec_prefix', 'libexecdir', 'prefix', 'sbindir' -- directory
  89. })
  90. lex:set_word_list(lexer.FUNCTION_BUILTIN, {
  91. -- Filename.
  92. 'abspath', 'addprefix', 'addsuffix', 'basename', 'dir', 'join', 'notdir', 'realpath', 'suffix',
  93. 'wildcard', --
  94. 'and', 'if', 'or', -- conditional
  95. 'error', 'info', 'warning', -- control
  96. 'filter', 'filter-out', 'findstring', 'firstword', 'lastword', 'patsubst', 'sort', 'strip',
  97. -- Text.
  98. 'subst', 'word', 'wordlist', 'words', --
  99. 'call', 'eval', 'file', 'flavor', 'foreach', 'origin', 'shell', 'value' -- other
  100. })
  101. lexer.property['scintillua.comment'] = '#'
  102. return lex