123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- -- Copyright 2006-2017 Mitchell mitchell.att.foicica.com. See LICENSE.
- -- PHP LPeg lexer.
- local l = require('lexer')
- local token, word_match = l.token, l.word_match
- local P, R, S, V = lpeg.P, lpeg.R, lpeg.S, lpeg.V
- local M = {_NAME = 'php'}
- -- Whitespace.
- local ws = token(l.WHITESPACE, l.space^1)
- -- Comments.
- local line_comment = (P('//') + '#') * l.nonnewline^0
- local block_comment = '/*' * (l.any - '*/')^0 * P('*/')^-1
- local comment = token(l.COMMENT, block_comment + line_comment)
- -- Strings.
- local sq_str = l.delimited_range("'")
- local dq_str = l.delimited_range('"')
- local bt_str = l.delimited_range('`')
- local heredoc = '<<<' * P(function(input, index)
- local _, e, delimiter = input:find('([%a_][%w_]*)[\n\r\f]+', index)
- if delimiter then
- local _, e = input:find('[\n\r\f]+'..delimiter, e)
- return e and e + 1
- end
- end)
- local string = token(l.STRING, sq_str + dq_str + bt_str + heredoc)
- -- TODO: interpolated code.
- -- Numbers.
- local number = token(l.NUMBER, l.float + l.integer)
- -- Keywords.
- local keyword = token(l.KEYWORD, word_match{
- 'abstract', 'and', 'array', 'as', 'bool', 'boolean', 'break',
- 'callable', 'case', 'catch', 'cfunction', 'class', 'const',
- 'continue', 'declare', 'default', 'die', 'directory', 'do',
- 'double', 'echo', 'else', 'elseif', 'empty', 'enddeclare',
- 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval',
- 'exit', 'extends', 'false', 'final', 'finally', 'float', 'for',
- 'foreach', 'function', 'global', 'goto', 'if', 'implements',
- 'include', 'include_once', 'instanceof', 'insteadof', 'int',
- 'integer', 'interface', 'isset', 'list', 'namespace', 'new',
- 'null', 'object', 'old_function', 'or', 'parent', 'print',
- 'private', 'protected', 'public', 'real', 'require',
- 'require_once', 'resource', 'return', 'static', 'stdclass',
- 'string', 'switch', 'switch', 'throw', 'trait', 'true', 'try',
- 'unset', 'use', 'var', 'while', 'xor', 'yield', '__class__',
- '__file__', '__function__', '__line__', '__sleep', '__wakeup'
- })
- -- Variables.
- local word = (l.alpha + '_' + R('\127\255')) * (l.alnum + '_' + R('\127\255'))^0
- --local variable = token(l.VARIABLE, '$' * word)
- local variable = token(l.VARIABLE, ('$' * word) + ('$$' * word))
- -- Identifiers.
- local identifier = token(l.IDENTIFIER, word)
- -- Operators.
- --local operator = token(l.OPERATOR, S('!@%^*&()-+=|/.,;:<>[]{}') + '?' * -P('>'))
- local operator = token(l.OPERATOR, S('%^*-+=/<>') + '?' * -P('>'))
- M._rules = {
- {'whitespace', ws},
- {'keyword', keyword},
- {'identifier', identifier},
- {'string', string},
- {'variable', variable},
- {'comment', comment},
- {'number', number},
- {'operator', operator},
- }
- -- Embedded in HTML.
- local html = l.load('html')
- -- Embedded PHP.
- local php_start_rule = token('php_tag', '<?' * ('php' * l.space)^-1)
- local php_end_rule = token('php_tag', '?>')
- local func_highlight_rule = token('func_tags', word_match{'function', 'func'})
- l.embed_lexer(html, M, php_start_rule, func_highlight_rule, php_end_rule)
- M._tokenstyles = {
- php_tag = l.STYLE_EMBEDDED,
- func_tags = l.STYLE_EMBEDDED
- }
- local _foldsymbols = html._foldsymbols
- _foldsymbols._patterns[#_foldsymbols._patterns + 1] = '<%?'
- _foldsymbols._patterns[#_foldsymbols._patterns + 1] = '%?>'
- _foldsymbols._patterns[#_foldsymbols._patterns + 1] = '/%*'
- _foldsymbols._patterns[#_foldsymbols._patterns + 1] = '%*/'
- _foldsymbols._patterns[#_foldsymbols._patterns + 1] = '//'
- _foldsymbols._patterns[#_foldsymbols._patterns + 1] = '#'
- _foldsymbols._patterns[#_foldsymbols._patterns + 1] = '[{}()]'
- _foldsymbols.php_tag = {['<?'] = 1, ['?>'] = -1}
- _foldsymbols[l.COMMENT]['/*'], _foldsymbols[l.COMMENT]['*/'] = 1, -1
- _foldsymbols[l.COMMENT]['//'] = l.fold_line_comments('//')
- _foldsymbols[l.COMMENT]['#'] = l.fold_line_comments('#')
- _foldsymbols[l.OPERATOR] = {['{'] = 1, ['}'] = -1, ['('] = 1, [')'] = -1}
- M._foldsymbols = _foldsymbols
- return M
|