1 -- Copyright 2006-2017 Mitchell mitchell.att.foicica.com. See LICENSE.
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
= 'bash'}
11 local ws
= token(l
.WHITESPACE
, l
.space^
1)
14 local comment
= token(l
.COMMENT
, '#' * l
.nonnewline^
0)
17 local sq_str
= l
.delimited_range("'", false, true)
18 local dq_str
= l
.delimited_range('"')
19 local ex_str
= l
.delimited_range('`')
20 local heredoc
= '<<' * P(function(input
, index
)
21 local s
, e
, _
, delimiter
=
22 input
:find('%-?(["\']?)([%a_][%w_]*)%1[\n\r\f;]+', index
)
23 if s
== index
and delimiter
then
24 local _
, e
= input
:find('[\n\r\f]+'..delimiter
, e
)
25 return e
and e
+ 1 or #input
+ 1
28 local string = token(l
.STRING
, sq_str
+ dq_str
+ ex_str
+ heredoc
)
31 local number = token(l
.NUMBER
, l
.float
+ l
.integer
)
34 local keyword
= token(l
.KEYWORD
, word_match({
35 'if', 'then', 'elif', 'else', 'fi', 'case', 'in', 'esac', 'while', 'for',
36 'do', 'done', 'continue', 'local', 'return', 'select',
38 '-a', '-b', '-c', '-d', '-e', '-f', '-g', '-h', '-k', '-p', '-r', '-s', '-t',
39 '-u', '-w', '-x', '-O', '-G', '-L', '-S', '-N', '-nt', '-ot', '-ef', '-o',
40 '-z', '-n', '-eq', '-ne', '-lt', '-le', '-gt', '-ge'
44 local identifier
= token(l
.IDENTIFIER
, l
.word
)
47 local variable
= token(l
.VARIABLE
,
48 '$' * (S('!#?*@$') + l
.digit^
1 + l
.word
+
49 l
.delimited_range('{}', true, true, true)))
52 local operator
= token(l
.OPERATOR
, S('=!<>+-/*^&|~.,:;?()[]{}'))
57 {'identifier', identifier
},
61 {'variable', variable
},
62 {'operator', operator
},
66 _patterns
= {'[a-z]+', '[{}]', '#'},
68 ['if'] = 1, fi
= -1, case
= 1, esac
= -1, ['do'] = 1, done
= -1
70 [l
.OPERATOR
] = {['{'] = 1, ['}'] = -1},
71 [l
.COMMENT
] = {['#'] = l
.fold_line_comments('#')}