1 -- Copyright 2006-2015 Mitchell mitchell.att.foicica.com. See LICENSE.
2 -- Makefile LPeg lexer.
4 local l
= require('lexer')
5 local token
, word_match
= l
.token
, l
.word_match
6 local P
, R
, S
= lpeg
.P
, lpeg
.R
, lpeg
.S
8 local M
= {_NAME
= 'makefile'}
11 local ws
= token(l
.WHITESPACE
, l
.space^
1)
14 local comment
= token(l
.COMMENT
, '#' * l
.nonnewline^
0)
17 local keyword
= token(l
.KEYWORD
, P('!')^
-1 * l
.word_match({
18 -- GNU Make conditionals.
19 'ifeq', 'ifneq', 'ifdef', 'ifndef', 'else', 'endif',
20 -- Other conditionals.
21 'if', 'elseif', 'elseifdef', 'elseifndef',
22 -- Directives and other keywords.
23 'define', 'endef', 'export', 'include', 'override', 'private', 'undefine',
28 local func
= token(l
.FUNCTION
, l
.word_match({
29 -- Functions for String Substitution and Analysis.
30 'subst', 'patsubst', 'strip', 'findstring', 'filter', 'filter-out', 'sort',
31 'word', 'wordlist', 'words', 'firstword', 'lastword',
32 -- Functions for File Names.
33 'dir', 'notdir', 'suffix', 'basename', 'addsuffix', 'addprefix', 'join',
34 'wildcard', 'realpath', 'abspath',
35 -- Functions for Conditionals.
37 -- Miscellaneous Functions.
38 'foreach', 'call', 'value', 'eval', 'origin', 'flavor', 'shell',
39 -- Functions That Control Make.
40 'error', 'warning', 'info'
44 local word_char
, assign
= l
.any
- l
.space
- S(':#=(){}'), S(':+?')^
-1 * '='
45 local expanded_var
= '$' * ('(' * word_char^
1 * ')' + '{' * word_char^
1 * '}')
46 local auto_var
= '$' * S('@%<?^+|*')
47 local special_var
= l
.word_match({
48 'MAKEFILE_LIST', '.DEFAULT_GOAL', 'MAKE_RESTARTS', '.RECIPEPREFIX',
49 '.VARIABLES', '.FEATURES', '.INCLUDE_DIRS',
50 'GPATH', 'MAKECMDGOALS', 'MAKESHELL', 'SHELL', 'VPATH'
51 }, '.') * #(ws^
0 * assign
)
52 local implicit_var
= l
.word_match
{
53 -- Some common variables.
54 'AR', 'AS', 'CC', 'CXX', 'CPP', 'FC', 'M2C', 'PC', 'CO', 'GET', 'LEX', 'YACC',
55 'LINT', 'MAKEINFO', 'TEX', 'TEXI2DVI', 'WEAVE', 'CWEAVE', 'TANGLE', 'CTANGLE',
57 -- Some common flag variables.
58 'ARFLAGS', 'ASFLAGS', 'CFLAGS', 'CXXFLAGS', 'COFLAGS', 'CPPFLAGS', 'FFLAGS',
59 'GFLAGS', 'LDFLAGS', 'LFLAGS', 'YFLAGS', 'PFLAGS', 'RFLAGS', 'LINTFLAGS',
61 'DESTDIR', 'MAKE', 'MAKEFLAGS', 'MAKEOVERRIDES', 'MFLAGS'
63 local computed_var
= token(l
.OPERATOR
, '$' * S('({')) * func
64 local variable
= token(l
.VARIABLE
,
65 expanded_var
+ auto_var
+ special_var
+ implicit_var
) +
69 local special_target
= token(l
.CONSTANT
, l
.word_match({
70 '.PHONY', '.SUFFIXES', '.DEFAULT', '.PRECIOUS', '.INTERMEDIATE', '.SECONDARY',
71 '.SECONDEXPANSION', '.DELETE_ON_ERROR', '.IGNORE', '.LOW_RESOLUTION_TIME',
72 '.SILENT', '.EXPORT_ALL_VARIABLES', '.NOTPARALLEL', '.ONESHELL', '.POSIX'
74 local normal_target
= token('target', (l
.any
- l
.space
- S(':#='))^
1)
75 local target
= l
.starts_line((special_target
+ normal_target
) * ws^
0 *
79 local identifier
= token(l
.IDENTIFIER
, word_char^
1)
82 local operator
= token(l
.OPERATOR
, assign
+ S(':$(){}'))
88 {'variable', variable
},
89 {'operator', operator
},
90 {'identifier', identifier
},
95 target
= l
.STYLE_LABEL
101 local bash
= l
.load('bash')
102 bash
._RULES
['variable'] = token(l
.VARIABLE
, '$$' * word_char^
1) +
103 bash
._RULES
['variable'] + variable
104 local bash_start_rule
= token(l
.WHITESPACE
, P('\t')) + token(l
.OPERATOR
, P(';'))
105 local bash_end_rule
= token(l
.WHITESPACE
, P('\n'))
106 l
.embed_lexer(M
, bash
, bash_start_rule
, bash_end_rule
)