php.lua.version-9.6-backup 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. -- Copyright 2006-2017 Mitchell mitchell.att.foicica.com. See LICENSE.
  2. -- PHP LPeg lexer.
  3. local l = require('lexer')
  4. local token, word_match = l.token, l.word_match
  5. local P, R, S, V = lpeg.P, lpeg.R, lpeg.S, lpeg.V
  6. local M = {_NAME = 'php'}
  7. -- Whitespace.
  8. local ws = token(l.WHITESPACE, l.space^1)
  9. -- Comments.
  10. local line_comment = (P('//') + '#') * l.nonnewline^0
  11. local block_comment = '/*' * (l.any - '*/')^0 * P('*/')^-1
  12. local comment = token(l.COMMENT, block_comment + line_comment)
  13. -- Strings.
  14. local sq_str = l.delimited_range("'")
  15. local dq_str = l.delimited_range('"')
  16. local bt_str = l.delimited_range('`')
  17. local heredoc = '<<<' * P(function(input, index)
  18. local _, e, delimiter = input:find('([%a_][%w_]*)[\n\r\f]+', index)
  19. if delimiter then
  20. local _, e = input:find('[\n\r\f]+'..delimiter, e)
  21. return e and e + 1
  22. end
  23. end)
  24. local string = token(l.STRING, sq_str + dq_str + bt_str + heredoc)
  25. -- TODO: interpolated code.
  26. -- Numbers.
  27. local number = token(l.NUMBER, l.float + l.integer)
  28. -- Keywords.
  29. local keyword = token(l.KEYWORD, word_match{
  30. 'abstract', 'and', 'array', 'as', 'bool', 'boolean', 'break',
  31. 'callable', 'case', 'catch', 'cfunction', 'class', 'const',
  32. 'continue', 'declare', 'default', 'die', 'directory', 'do',
  33. 'double', 'echo', 'else', 'elseif', 'empty', 'enddeclare',
  34. 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval',
  35. 'exit', 'extends', 'false', 'final', 'finally', 'float', 'for',
  36. 'foreach', 'function', 'global', 'goto', 'if', 'implements',
  37. 'include', 'include_once', 'instanceof', 'insteadof', 'int',
  38. 'integer', 'interface', 'isset', 'list', 'namespace', 'new',
  39. 'null', 'object', 'old_function', 'or', 'parent', 'print',
  40. 'private', 'protected', 'public', 'real', 'require',
  41. 'require_once', 'resource', 'return', 'static', 'stdclass',
  42. 'string', 'switch', 'switch', 'throw', 'trait', 'true', 'try',
  43. 'unset', 'use', 'var', 'while', 'xor', 'yield', '__class__',
  44. '__file__', '__function__', '__line__', '__sleep', '__wakeup'
  45. })
  46. -- Variables.
  47. local word = (l.alpha + '_' + R('\127\255')) * (l.alnum + '_' + R('\127\255'))^0
  48. --local variable = token(l.VARIABLE, '$' * word)
  49. local variable = token(l.VARIABLE, ('$' * word) + ('$$' * word))
  50. -- Identifiers.
  51. local identifier = token(l.IDENTIFIER, word)
  52. -- Operators.
  53. --local operator = token(l.OPERATOR, S('!@%^*&()-+=|/.,;:<>[]{}') + '?' * -P('>'))
  54. local operator = token(l.OPERATOR, S('%^*-+=/<>') + '?' * -P('>'))
  55. M._rules = {
  56. {'whitespace', ws},
  57. {'keyword', keyword},
  58. {'identifier', identifier},
  59. {'string', string},
  60. {'variable', variable},
  61. {'comment', comment},
  62. {'number', number},
  63. {'operator', operator},
  64. }
  65. -- Embedded in HTML.
  66. local html = l.load('html')
  67. -- Embedded PHP.
  68. local php_start_rule = token('php_tag', '<?' * ('php' * l.space)^-1)
  69. local php_end_rule = token('php_tag', '?>')
  70. local func_highlight_rule = token('func_tags', word_match{'function', 'func'})
  71. l.embed_lexer(html, M, php_start_rule, func_highlight_rule, php_end_rule)
  72. M._tokenstyles = {
  73. php_tag = l.STYLE_EMBEDDED,
  74. func_tags = l.STYLE_EMBEDDED
  75. }
  76. local _foldsymbols = html._foldsymbols
  77. _foldsymbols._patterns[#_foldsymbols._patterns + 1] = '<%?'
  78. _foldsymbols._patterns[#_foldsymbols._patterns + 1] = '%?>'
  79. _foldsymbols._patterns[#_foldsymbols._patterns + 1] = '/%*'
  80. _foldsymbols._patterns[#_foldsymbols._patterns + 1] = '%*/'
  81. _foldsymbols._patterns[#_foldsymbols._patterns + 1] = '//'
  82. _foldsymbols._patterns[#_foldsymbols._patterns + 1] = '#'
  83. _foldsymbols._patterns[#_foldsymbols._patterns + 1] = '[{}()]'
  84. _foldsymbols.php_tag = {['<?'] = 1, ['?>'] = -1}
  85. _foldsymbols[l.COMMENT]['/*'], _foldsymbols[l.COMMENT]['*/'] = 1, -1
  86. _foldsymbols[l.COMMENT]['//'] = l.fold_line_comments('//')
  87. _foldsymbols[l.COMMENT]['#'] = l.fold_line_comments('#')
  88. _foldsymbols[l.OPERATOR] = {['{'] = 1, ['}'] = -1, ['('] = 1, [')'] = -1}
  89. M._foldsymbols = _foldsymbols
  90. return M