branch: externals/phps-mode commit d74686e07ce937a423b7b0b7924642a9f4424e94 Author: Christian Johansson <christ...@cvj.se> Commit: Christian Johansson <christ...@cvj.se>
Started on optimizing lexer --- phps-mode-ast-bookkeeping.el | 151 +-- phps-mode-lex-analyzer.el | 20 +- phps-mode-lexer.el | 2852 ++++++++++++++++++++++-------------------- 3 files changed, 1587 insertions(+), 1436 deletions(-) diff --git a/phps-mode-ast-bookkeeping.el b/phps-mode-ast-bookkeeping.el index 27af096e27..d8bda44a4a 100644 --- a/phps-mode-ast-bookkeeping.el +++ b/phps-mode-ast-bookkeeping.el @@ -762,89 +762,90 @@ (downcase-subject-name (downcase (plist-get subject 'name))) (property-name (plist-get item 'property-name))) - (cond + (when downcase-subject-name + (cond - ((string= downcase-subject-name "$this") - (puthash - (list - (plist-get subject 'start) - (plist-get subject 'end)) - 1 - bookkeeping) - ;; When current scope is arrow function - ;; we should go up in scope until we get out of - ;; arrow functions scope - (let ((sub-scope scope) - (head-scope) - (is-arrow-function-scope t)) - (while (and - sub-scope - is-arrow-function-scope) - (setq - head-scope - (car sub-scope)) - (setq - sub-scope - (cdr sub-scope)) - (unless (equal - (plist-get head-scope 'type) - 'arrow-function) - (setq is-arrow-function-scope nil))) - (let* ((predefined) - (variable-ids - (phps-mode-ast-bookkeeping--generate-variable-scope-string - sub-scope - (concat "$" property-name) - t)) - (symbol-id - (phps-mode-ast-bookkeeping--generate-symbol-scope-string - sub-scope - property-name)) - (bookkeeping-object - (list - (plist-get item 'property-start) - (plist-get item 'property-end)))) - (when (gethash symbol-id bookkeeping) + ((string= downcase-subject-name "$this") + (puthash + (list + (plist-get subject 'start) + (plist-get subject 'end)) + 1 + bookkeeping) + ;; When current scope is arrow function + ;; we should go up in scope until we get out of + ;; arrow functions scope + (let ((sub-scope scope) + (head-scope) + (is-arrow-function-scope t)) + (while (and + sub-scope + is-arrow-function-scope) (setq - predefined - t)) - (dolist (variable-id variable-ids) - (when (gethash variable-id bookkeeping) + head-scope + (car sub-scope)) + (setq + sub-scope + (cdr sub-scope)) + (unless (equal + (plist-get head-scope 'type) + 'arrow-function) + (setq is-arrow-function-scope nil))) + (let* ((predefined) + (variable-ids + (phps-mode-ast-bookkeeping--generate-variable-scope-string + sub-scope + (concat "$" property-name) + t)) + (symbol-id + (phps-mode-ast-bookkeeping--generate-symbol-scope-string + sub-scope + property-name)) + (bookkeeping-object + (list + (plist-get item 'property-start) + (plist-get item 'property-end)))) + (when (gethash symbol-id bookkeeping) (setq predefined - t))) - (if predefined + t)) + (dolist (variable-id variable-ids) + (when (gethash variable-id bookkeeping) + (setq + predefined + t))) + (if predefined + (puthash + bookkeeping-object + 1 + bookkeeping) (puthash bookkeeping-object - 1 - bookkeeping) - (puthash - bookkeeping-object - 0 - bookkeeping))))) + 0 + bookkeeping))))) - (t - (let ((variable-ids - (phps-mode-ast-bookkeeping--generate-variable-scope-string - scope - (plist-get subject 'name) - t)) - (predefined 0)) - (dolist (variable-id variable-ids) - (when (gethash - variable-id - bookkeeping) - (setq - predefined - 1))) - (puthash - (list - (plist-get subject 'start) - (plist-get subject 'end)) - predefined - bookkeeping))) + (t + (let ((variable-ids + (phps-mode-ast-bookkeeping--generate-variable-scope-string + scope + (plist-get subject 'name) + t)) + (predefined 0)) + (dolist (variable-id variable-ids) + (when (gethash + variable-id + bookkeeping) + (setq + predefined + 1))) + (puthash + (list + (plist-get subject 'start) + (plist-get subject 'end)) + predefined + bookkeeping))) - ))) + )))) ((equal type 'static-member) (let* ((parent-class (plist-get item 'class)) diff --git a/phps-mode-lex-analyzer.el b/phps-mode-lex-analyzer.el index 9ac9194e5f..26f814fae3 100644 --- a/phps-mode-lex-analyzer.el +++ b/phps-mode-lex-analyzer.el @@ -132,11 +132,12 @@ (setq bookkeeping-index (list start end)) - (setq - bookkeeping-value - (gethash - bookkeeping-index - phps-mode-lex-analyzer--bookkeeping))) + (when phps-mode-lex-analyzer--bookkeeping + (setq + bookkeeping-value + (gethash + bookkeeping-index + phps-mode-lex-analyzer--bookkeeping)))) (cond @@ -256,7 +257,6 @@ (phps-mode-lex-analyzer--set-region-syntax-color start end (list 'font-lock-face token-syntax-color)) (phps-mode-lex-analyzer--clear-region-syntax-color start end))))) - ;; Signal parser error (if any) (when phps-mode-lex-analyzer--parse-error @@ -278,7 +278,9 @@ 'phps-parser-error (list (nth 1 phps-mode-lex-analyzer--parse-error) - (nth 4 phps-mode-lex-analyzer--parse-error))))))) + (nth 4 phps-mode-lex-analyzer--parse-error)))) + + ))) (lambda(result) (when (get-buffer buffer-name) @@ -317,7 +319,9 @@ ) - ))))) + ) + +)))) nil async diff --git a/phps-mode-lexer.el b/phps-mode-lexer.el index d38b918096..ce4bbbfb35 100644 --- a/phps-mode-lexer.el +++ b/phps-mode-lexer.el @@ -108,6 +108,11 @@ ;; VARIABLES +(defvar + phps-mode-lexer--lambdas-by-state + (make-hash-table :test 'equal) + "Hash-map of lambdas by state.") + (defvar-local phps-mode-lexer--generated-tokens nil "List of current generated tokens.") @@ -327,12 +332,42 @@ (setq end (match-end 0))) (setq semantic-lex-end-point end)) -(defmacro phps-mode-lexer--match-macro (conditions &rest body) - "Check if CONDITIONS hold, if so execute BODY." - `(phps-mode-lexer--re2c-rule - ,conditions - (lambda() - ,@body))) +(defmacro phps-mode-lexer--match-macro (states conditions &rest body) + "Place in STATES a check for CONDITIONS to execute BODY." + (unless (listp states) + (setq states (list states))) + (dolist (state states) + (let ((old-lambdas + (gethash + state + phps-mode-lexer--lambdas-by-state))) + (when old-lambdas + (setq + old-lambdas + (reverse old-lambdas))) + (push + `(lambda() + (when ,conditions + (let ((match-end (match-end 0)) + (match-beginning (match-beginning 0))) + (let ((matching-length (- match-end match-beginning))) + (when (> matching-length 0) + (when (or (not phps-mode-lexer--match-length) + (> matching-length phps-mode-lexer--match-length)) + (setq + phps-mode-lexer--match-length matching-length) + (setq + phps-mode-lexer--match-body (lambda() ,@body)) + (setq + phps-mode-lexer--match-data (match-data)))))))) + old-lambdas) + (setq + old-lambdas + (reverse old-lambdas)) + (puthash + state + old-lambdas + phps-mode-lexer--lambdas-by-state)))) (defun phps-mode-lexer--return-token (&optional token start end) "Return TOKEN with START and END." @@ -433,18 +468,1439 @@ ;; LEXER FUNCTIONS BELOW -(defun phps-mode-lexer--re2c-rule (condition body) - "Process rule with CONDITION and BODY." - (when condition - (let ((match-end (match-end 0)) - (match-beginning (match-beginning 0))) - (let ((matching-length (- match-end match-beginning))) - (when (> matching-length 0) - (when (or (not phps-mode-lexer--match-length) - (> matching-length phps-mode-lexer--match-length)) - (setq phps-mode-lexer--match-length matching-length) - (setq phps-mode-lexer--match-body body) - (setq phps-mode-lexer--match-data (match-data)))))))) +;; Setup lexer rules +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "exit") + (phps-mode-lexer--return-token-with-indent 'T_EXIT)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "die") + (phps-mode-lexer--return-token-with-indent 'T_EXIT)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "fn") + (phps-mode-lexer--return-token-with-indent 'T_FN)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "function") + (phps-mode-lexer--return-token-with-indent 'T_FUNCTION)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "const") + (phps-mode-lexer--return-token-with-indent 'T_CONST)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "return") + (phps-mode-lexer--return-token-with-indent 'T_RETURN)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "#\\[") + (phps-mode-lexer--enter-nesting "[") + (phps-mode-lexer--return-token 'T_ATTRIBUTE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at + (concat + "yield" + phps-mode-lexer--whitespace + "from" + "[^a-zA-Z0-9_\x80-\xff]")) + (phps-mode-lexer--return-token-with-indent 'T_YIELD_FROM)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "yield") + (phps-mode-lexer--return-token-with-indent 'T_YIELD)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "try") + (phps-mode-lexer--return-token-with-indent 'T_TRY)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "catch") + (phps-mode-lexer--return-token-with-indent 'T_CATCH)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "finally") + (phps-mode-lexer--return-token-with-indent 'T_FINALLY)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "throw") + (phps-mode-lexer--return-token-with-indent 'T_THROW)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "if") + (phps-mode-lexer--return-token-with-indent 'T_IF)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "elseif") + (phps-mode-lexer--return-token-with-indent 'T_ELSEIF)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "endif") + (phps-mode-lexer--return-token-with-indent 'T_ENDIF)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "else") + (phps-mode-lexer--return-token-with-indent 'T_ELSE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "while") + (phps-mode-lexer--return-token-with-indent 'T_WHILE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "endwhile") + (phps-mode-lexer--return-token-with-indent 'T_ENDWHILE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "do") + (phps-mode-lexer--return-token-with-indent 'T_DO)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "for") + (phps-mode-lexer--return-token-with-indent 'T_FOR)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "endfor") + (phps-mode-lexer--return-token-with-indent 'T_ENDFOR)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "foreach") + (phps-mode-lexer--return-token-with-indent 'T_FOREACH)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "endforeach") + (phps-mode-lexer--return-token-with-indent 'T_ENDFOREACH)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "declare") + (phps-mode-lexer--return-token-with-indent 'T_DECLARE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "enddeclare") + (phps-mode-lexer--return-token-with-indent 'T_ENDDECLARE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "instanceof") + (phps-mode-lexer--return-token-with-indent 'T_INSTANCEOF)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "as") + (phps-mode-lexer--return-token-with-indent 'T_AS)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "switch") + (phps-mode-lexer--return-token-with-indent 'T_SWITCH)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "match") + (phps-mode-lexer--return-token-with-indent 'T_MATCH)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "endswitch") + (phps-mode-lexer--return-token-with-indent 'T_ENDSWITCH)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "case") + (phps-mode-lexer--return-token-with-indent 'T_CASE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "default") + (phps-mode-lexer--return-token-with-indent 'T_DEFAULT)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "break") + (phps-mode-lexer--return-token-with-indent 'T_BREAK)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "continue") + (phps-mode-lexer--return-token-with-indent 'T_CONTINUE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "goto") + (phps-mode-lexer--return-token-with-indent 'T_GOTO)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "echo") + (phps-mode-lexer--return-token-with-indent 'T_ECHO)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "print") + (phps-mode-lexer--return-token-with-indent 'T_PRINT)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "class") + (phps-mode-lexer--return-token-with-indent 'T_CLASS)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "interface") + (phps-mode-lexer--return-token-with-indent 'T_INTERFACE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "trait") + (phps-mode-lexer--return-token-with-indent 'T_TRAIT)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "extends") + (phps-mode-lexer--return-token-with-indent 'T_EXTENDS)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "implements") + (phps-mode-lexer--return-token-with-indent 'T_IMPLEMENTS)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "->") + (phps-mode-lexer--yy-push-state 'ST_LOOKING_FOR_PROPERTY) + (phps-mode-lexer--return-token-with-indent 'T_OBJECT_OPERATOR)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "?->") + (phps-mode-lexer--yy-push-state 'ST_LOOKING_FOR_PROPERTY) + (phps-mode-lexer--return-token-with-indent 'T_NULLSAFE_OBJECT_OPERATOR)) + +(phps-mode-lexer--match-macro + (ST_IN_SCRIPTING ST_LOOKING_FOR_PROPERTY) + (looking-at phps-mode-lexer--whitespace) + (phps-mode-lexer--return-whitespace)) + +(phps-mode-lexer--match-macro + ST_LOOKING_FOR_PROPERTY + (looking-at "->") + (phps-mode-lexer--return-token 'T_OBJECT_OPERATOR)) + +(phps-mode-lexer--match-macro + ST_LOOKING_FOR_PROPERTY + (looking-at "?->") + (phps-mode-lexer--return-token 'T_NULLSAFE_OBJECT_OPERATOR)) + +(phps-mode-lexer--match-macro + ST_LOOKING_FOR_PROPERTY + (looking-at phps-mode-lexer--label) + (phps-mode-lexer--yy-pop-state) + (phps-mode-lexer--return-token-with-str 'T_STRING 0)) + +(phps-mode-lexer--match-macro + ST_LOOKING_FOR_PROPERTY + (looking-at phps-mode-lexer--any-char) + (phps-mode-lexer--yyless 0) + (phps-mode-lexer--yy-pop-state) + (phps-mode-lexer--restart)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "::") + (phps-mode-lexer--return-token 'T_PAAMAYIM_NEKUDOTAYIM)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "\\.\\.\\.") + (phps-mode-lexer--return-token 'T_ELLIPSIS)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "\\?\\?") + (phps-mode-lexer--return-token 'T_COALESCE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "new") + (phps-mode-lexer--return-token-with-indent 'T_NEW)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "clone") + (phps-mode-lexer--return-token-with-indent 'T_CLONE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "var") + (phps-mode-lexer--return-token-with-indent 'T_VAR)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at + (concat + "(" + phps-mode-lexer--tabs-and-spaces + "\\(int\\|integer\\)" + phps-mode-lexer--tabs-and-spaces + ")")) + (phps-mode-lexer--return-token 'T_INT_CAST)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at + (concat + "(" + phps-mode-lexer--tabs-and-spaces + "\\(double\\|float\\)" + phps-mode-lexer--tabs-and-spaces + ")")) + (phps-mode-lexer--return-token 'T_DOUBLE_CAST)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at + (concat + "(" + phps-mode-lexer--tabs-and-spaces + "\\(real\\)" + phps-mode-lexer--tabs-and-spaces + ")")) + (when (phps-mode-lexer--parser-mode) + (signal + 'phps-lexer-error + (list + (format + "The (real) cast has been removed, use (float) instead at %d" + (match-beginning 0)) + (match-beginning 0) + (match-end 0)))) + (phps-mode-lexer--return-token 'T_DOUBLE_CAST)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at + (concat + "(" + phps-mode-lexer--tabs-and-spaces + "\\(string\\|binary\\)" + phps-mode-lexer--tabs-and-spaces + ")")) + (phps-mode-lexer--return-token 'T_STRING_CAST)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at + (concat + "(" + phps-mode-lexer--tabs-and-spaces + "array" + phps-mode-lexer--tabs-and-spaces + ")")) + (phps-mode-lexer--return-token 'T_ARRAY_CAST)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at + (concat + "(" + phps-mode-lexer--tabs-and-spaces + "object" + phps-mode-lexer--tabs-and-spaces + ")")) + (phps-mode-lexer--return-token 'T_OBJECT_CAST)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at + (concat + "(" + phps-mode-lexer--tabs-and-spaces + "\\(bool\\|boolean\\)" + phps-mode-lexer--tabs-and-spaces + ")")) + (phps-mode-lexer--return-token 'T_BOOL_CAST)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at + (concat + "(" + phps-mode-lexer--tabs-and-spaces + "unset" + phps-mode-lexer--tabs-and-spaces ")")) + (phps-mode-lexer--return-token 'T_UNSET_CAST)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "eval") + (phps-mode-lexer--return-token-with-indent 'T_EVAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "include") + (phps-mode-lexer--return-token-with-indent 'T_INCLUDE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "include_once") + (phps-mode-lexer--return-token-with-indent 'T_INCLUDE_ONCE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "require") + (phps-mode-lexer--return-token-with-indent 'T_REQUIRE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "require_once") + (phps-mode-lexer--return-token-with-indent 'T_REQUIRE_ONCE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "namespace") + (phps-mode-lexer--return-token-with-indent 'T_NAMESPACE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "use") + (phps-mode-lexer--return-token-with-indent 'T_USE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "insteadof") + (phps-mode-lexer--return-token-with-indent 'T_INSTEADOF)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "global") + (phps-mode-lexer--return-token-with-indent 'T_GLOBAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "isset") + (phps-mode-lexer--return-token-with-indent 'T_ISSET)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "empty") + (phps-mode-lexer--return-token-with-indent 'T_EMPTY)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "__halt_compiler") + (phps-mode-lexer--return-token-with-indent 'T_HALT_COMPILER)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "static") + (phps-mode-lexer--return-token-with-indent 'T_STATIC)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "abstract") + (phps-mode-lexer--return-token-with-indent 'T_ABSTRACT)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "final") + (phps-mode-lexer--return-token-with-indent 'T_FINAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "private") + (phps-mode-lexer--return-token-with-indent 'T_PRIVATE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "protected") + (phps-mode-lexer--return-token-with-indent 'T_PROTECTED)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "public") + (phps-mode-lexer--return-token-with-indent 'T_PUBLIC)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "unset") + (phps-mode-lexer--return-token-with-indent 'T_UNSET)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "=>") + (phps-mode-lexer--return-token 'T_DOUBLE_ARROW)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "list") + (phps-mode-lexer--return-token-with-indent 'T_LIST)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "array") + (phps-mode-lexer--return-token-with-indent 'T_ARRAY)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "callable") + (phps-mode-lexer--return-token-with-indent 'T_CALLABLE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "\\+\\+") + (phps-mode-lexer--return-token 'T_INC)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "--") + (phps-mode-lexer--return-token 'T_DEC)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "===") + (phps-mode-lexer--return-token 'T_IS_IDENTICAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "!==") + (phps-mode-lexer--return-token 'T_IS_NOT_IDENTICAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "==") + (phps-mode-lexer--return-token 'T_IS_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "\\(!=\\|<>\\)") + (phps-mode-lexer--return-token 'T_IS_NOT_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "<=>") + (phps-mode-lexer--return-token 'T_SPACESHIP)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "<=") + (phps-mode-lexer--return-token 'T_IS_SMALLER_OR_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at ">=") + (phps-mode-lexer--return-token 'T_IS_GREATER_OR_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "\\+=") + (phps-mode-lexer--return-token 'T_PLUS_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "-=") + (phps-mode-lexer--return-token 'T_MINUS_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "\\*=") + (phps-mode-lexer--return-token 'T_MUL_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "\\*\\\\\\*=") + (phps-mode-lexer--return-token 'T_POW_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "\\*\\\\\\*") + (phps-mode-lexer--return-token 'T_POW)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "/=") + (phps-mode-lexer--return-token 'T_DIV_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "\\.=") + (phps-mode-lexer--return-token 'T_CONCAT_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "%=") + (phps-mode-lexer--return-token 'T_MOD_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "<<=") + (phps-mode-lexer--return-token 'T_SL_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at ">>=") + (phps-mode-lexer--return-token 'T_SR_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "&=") + (phps-mode-lexer--return-token 'T_AND_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "|=") + (phps-mode-lexer--return-token 'T_OR_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "\\^=") + (phps-mode-lexer--return-token 'T_XOR_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "\\?\\?=") + (phps-mode-lexer--return-token 'T_COALESCE_EQUAL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "||") + (phps-mode-lexer--return-token 'T_BOOLEAN_OR)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "&&") + (phps-mode-lexer--return-token 'T_BOOLEAN_AND)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "OR") + (phps-mode-lexer--return-token 'T_LOGICAL_OR)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "AND") + (phps-mode-lexer--return-token 'T_LOGICAL_AND)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "XOR") + (phps-mode-lexer--return-token 'T_LOGICAL_XOR)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "<<") + (phps-mode-lexer--return-token 'T_SL)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at ">>") + (phps-mode-lexer--return-token 'T_SR)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at + (concat "\\(" "]" "\\|" ")" "\\)")) + (phps-mode-lexer--return-exit-nesting-token)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at + (concat "\\(" "\\[" "\\|" "(" "\\)")) + (phps-mode-lexer--enter-nesting) + (phps-mode-lexer--return-token)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at phps-mode-lexer--tokens) + (phps-mode-lexer--return-token)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "{") + (phps-mode-lexer--yy-push-state 'ST_IN_SCRIPTING) + (phps-mode-lexer--enter-nesting "{") + (phps-mode-lexer--return-token)) + +(phps-mode-lexer--match-macro + (ST_DOUBLE_QUOTES ST_BACKQUOTE ST_HEREDOC) + (looking-at "\\${") + (phps-mode-lexer--yy-push-state 'ST_LOOKING_FOR_VARNAME) + (phps-mode-lexer--enter-nesting "{") + (phps-mode-lexer--return-token 'T_DOLLAR_OPEN_CURLY_BRACES)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "}") + (phps-mode-lexer--reset-doc-comment) + (when phps-mode-lexer--state-stack + (phps-mode-lexer--yy-pop-state)) + (phps-mode-lexer--return-exit-nesting-token)) + +(phps-mode-lexer--match-macro + ST_LOOKING_FOR_VARNAME + (looking-at (concat phps-mode-lexer--label "[\\[}]")) + (let* ((start (match-beginning 0)) + (end (1- (match-end 0))) + (_data (buffer-substring-no-properties start end))) + (phps-mode-lexer--yyless 1) + (phps-mode-lexer--yy-pop-state) + (phps-mode-lexer--yy-push-state 'ST_IN_SCRIPTING) + (phps-mode-lexer--return-token 'T_STRING_VARNAME start end))) + +(phps-mode-lexer--match-macro + ST_LOOKING_FOR_VARNAME + (looking-at phps-mode-lexer--any-char) + (phps-mode-lexer--yyless 0) + (phps-mode-lexer--yy-pop-state) + (phps-mode-lexer--yy-push-state 'ST_IN_SCRIPTING) + (phps-mode-lexer--restart)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at phps-mode-lexer--bnum) + (let* ((start (match-beginning 0)) + (end (match-end 0)) + (data (buffer-substring-no-properties (+ start 2) end)) + (long-number (string-to-number data 2))) + ;; (message "Binary number %s from %s" long-number data) + (if (> long-number phps-mode-lexer--long-limit) + (phps-mode-lexer--return-token 'T_DNUMBER) + (phps-mode-lexer--return-token 'T_LNUMBER)))) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at phps-mode-lexer--lnum) + (let* ((start (match-beginning 0)) + (end (match-end 0)) + (data (string-to-number (buffer-substring-no-properties start end)))) + ;; (message "Long number: %d" data) + (if (> data phps-mode-lexer--long-limit) + (phps-mode-lexer--return-token 'T_DNUMBER) + (phps-mode-lexer--return-token 'T_LNUMBER)))) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at phps-mode-lexer--hnum) + (let* ((start (match-beginning 0)) + (end (match-end 0)) + (data (buffer-substring-no-properties (+ start 2) end)) + (long-number (string-to-number data 16))) + ;; (message "Hexadecimal number %s from %s" long-number data) + (if (> long-number phps-mode-lexer--long-limit) + (phps-mode-lexer--return-token 'T_DNUMBER) + (phps-mode-lexer--return-token 'T_LNUMBER)))) + +(phps-mode-lexer--match-macro + ST_VAR_OFFSET + (looking-at "\\([0]\\|[1-9][0-9]*\\)") + (phps-mode-lexer--return-token 'T_NUM_STRING)) + +(phps-mode-lexer--match-macro + ST_VAR_OFFSET + (looking-at + (concat "\\(" + phps-mode-lexer--lnum "\\|" + phps-mode-lexer--hnum "\\|" + phps-mode-lexer--bnum "\\)")) + (phps-mode-lexer--return-token 'T_NUM_STRING)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (or (looking-at phps-mode-lexer--dnum) + (looking-at phps-mode-lexer--exponent-dnum)) + (phps-mode-lexer--return-token 'T_DNUMBER)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "__CLASS__") + (phps-mode-lexer--return-token-with-indent 'T_CLASS_C)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "__TRAIT__") + (phps-mode-lexer--return-token-with-indent 'T_TRAIT_C)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "__FUNCTION__") + (phps-mode-lexer--return-token-with-indent 'T_FUNC_C)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "__METHOD__") + (phps-mode-lexer--return-token-with-indent 'T_METHOD_C)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "__LINE__") + (phps-mode-lexer--return-token-with-indent 'T_LINE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "__FILE__") + (phps-mode-lexer--return-token-with-indent 'T_FILE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "__DIR__") + (phps-mode-lexer--return-token-with-indent 'T_DIR)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "__NAMESPACE__") + (phps-mode-lexer--return-token-with-indent 'T_NS_C)) + +(phps-mode-lexer--match-macro + 'SHEBANG + (looking-at (concat "#!.*" phps-mode-lexer--newline)) + (let ((lineno + (1+ + (phps-mode-lexer--CG 'zend_lineno)))) + (phps-mode-lexer--CG 'zend-lineno lineno)) + (phps-mode-lexer--begin 'ST_INITIAL) + (phps-mode-lexer--restart)) + +(phps-mode-lexer--match-macro + 'SHEBANG + (looking-at phps-mode-lexer--any-char) + (phps-mode-lexer--yyless 0) + (phps-mode-lexer--begin 'ST_INITIAL) + (phps-mode-lexer--restart)) + +(phps-mode-lexer--match-macro + ST_INITIAL + (looking-at "<\\?=") + (phps-mode-lexer--begin 'ST_IN_SCRIPTING) + (when (phps-mode-lexer--parser-mode) + (phps-mode-lexer--return-token-with-indent 'T_ECHO)) + (phps-mode-lexer--return-token 'T_OPEN_TAG_WITH_ECHO)) + +(phps-mode-lexer--match-macro + ST_INITIAL + (looking-at + (concat + "<\\?php\\([ \t]\\|" + phps-mode-lexer--newline + "\\)")) + (phps-mode-lexer--handle-newline) + (phps-mode-lexer--begin 'ST_IN_SCRIPTING) + (phps-mode-lexer--return-or-skip-token 'T_OPEN_TAG)) + +(phps-mode-lexer--match-macro + ST_INITIAL + (looking-at "<\\?php") + (let ((start (match-beginning 0)) + (end (match-end 0))) + + ;; Allow <?php followed by end of file. + (cond + + ((equal end (point-max)) + (phps-mode-lexer--begin 'ST_IN_SCRIPTING) + (phps-mode-lexer--return-or-skip-token 'T_OPEN_TAG)) + + ((phps-mode-lexer--CG 'short-tags) + (phps-mode-lexer--yyless 2) + (setq end (- end 2)) + (phps-mode-lexer--begin 'ST_IN_SCRIPTING) + (phps-mode-lexer--return-or-skip-token + 'T_OPEN_TAG + start + end)) + + (t + (phps-mode-lexer--inline-char-handler))))) + +(phps-mode-lexer--match-macro + ST_INITIAL + (looking-at "<\\?") + (if (phps-mode-lexer--CG 'short-tags) + (progn + (phps-mode-lexer--begin 'ST_IN_SCRIPTING) + (phps-mode-lexer--return-or-skip-token 'T_OPEN_TAG)) + (phps-mode-lexer--inline-char-handler))) + +(phps-mode-lexer--match-macro + ST_INITIAL + (looking-at phps-mode-lexer--any-char) + (if (= (point) (point-max)) + (phps-mode-lexer--return-end-token) + (phps-mode-lexer--inline-char-handler))) + +;; Make sure a label character follows "->" or "?->", otherwise there is no property +;; and "->"/"?->" will be taken literally +(phps-mode-lexer--match-macro + (ST_DOUBLE_QUOTES ST_HEREDOC ST_BACKQUOTE) + (looking-at + (concat + "\\$" + phps-mode-lexer--label + "->" + "[a-zA-Z_\x80-\xff]")) + (phps-mode-lexer--yyless 3) + (phps-mode-lexer--yy-push-state 'ST_LOOKING_FOR_PROPERTY) + (phps-mode-lexer--return-token-with-str + 'T_VARIABLE + 1 + (match-beginning 0) + (- (match-end 0) 3))) + +(phps-mode-lexer--match-macro + (ST_DOUBLE_QUOTES ST_HEREDOC ST_BACKQUOTE) + (looking-at + (concat + "\\$" + phps-mode-lexer--label + "\\?->" + "[a-zA-Z_\x80-\xff]")) + (phps-mode-lexer--yyless 4) + (phps-mode-lexer--yy-push-state 'ST_LOOKING_FOR_PROPERTY) + (phps-mode-lexer--return-token-with-str + 'T_VARIABLE + 1 + (match-beginning 0) + (- (match-end 0) 4))) + +;; A [ always designates a variable offset, regardless of what follows +(phps-mode-lexer--match-macro + (ST_DOUBLE_QUOTES ST_HEREDOC ST_BACKQUOTE) + (looking-at + (concat + "\\$" + phps-mode-lexer--label + "\\[")) + (phps-mode-lexer--yyless 1) + (phps-mode-lexer--yy-push-state 'ST_VAR_OFFSET) + (phps-mode-lexer--return-token-with-str + 'T_VARIABLE + 1 + (match-beginning 0) + (- (match-end 0) 1))) + +(phps-mode-lexer--match-macro + '( + ST_IN_SCRIPTING + ST_DOUBLE_QUOTES + ST_HEREDOC + ST_BACKQUOTE + ST_VAR_OFFSET) + (looking-at + (concat + "\\$" + phps-mode-lexer--label)) + (phps-mode-lexer--return-token-with-str 'T_VARIABLE 1)) + +(phps-mode-lexer--match-macro + ST_VAR_OFFSET + (looking-at "\\]") + (phps-mode-lexer--yy-pop-state) + (phps-mode-lexer--return-token-with-str "]" 1)) + +(phps-mode-lexer--match-macro + ST_VAR_OFFSET + (looking-at + (concat "\\(" phps-mode-lexer--tokens + "\\|[{}\"`]\\)")) + (let* ((start (match-beginning 0)) + (end (match-end 0)) + (data (buffer-substring-no-properties start end))) + ;; Only '[' or '-' can be valid, but returning other tokens will allow a more explicit parse error + (phps-mode-lexer--return-token data))) + +(phps-mode-lexer--match-macro + ST_VAR_OFFSET + (looking-at (concat "[ \n\r\t'#]")) + ;; Invalid rule to return a more explicit parse error with proper line number + (phps-mode-lexer--yyless 0) + (phps-mode-lexer--yy-pop-state) + (phps-mode-lexer--return-token-with-val 'T_ENCAPSED_AND_WHITESPACE)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at + (concat + "namespace" + "\\(" + "\\\\" + phps-mode-lexer--label + "\\)+")) + (phps-mode-lexer--return-token-with-str + 'T_NAME_RELATIVE + (1- (length "namespace\\")))) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at (concat + phps-mode-lexer--label + "\\(" + "\\\\" + phps-mode-lexer--label + "\\)+")) + (phps-mode-lexer--return-token-with-str + 'T_NAME_QUALIFIED + 0)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at (concat + "\\\\" + phps-mode-lexer--label + "\\(" + "\\\\" + phps-mode-lexer--label + "\\)*")) + (phps-mode-lexer--return-token-with-str + 'T_NAME_FULLY_QUALIFIED + 1)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "\\\\") + (phps-mode-lexer--return-token 'T_NS_SEPARATOR)) + +(phps-mode-lexer--match-macro + (ST_IN_SCRIPTING ST_VAR_OFFSET) + (looking-at phps-mode-lexer--label) + (phps-mode-lexer--return-token-with-str 'T_STRING 0)) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "\\(#\\|//\\)") + (let* ((start (match-beginning 0)) + (end (match-end 0)) + (_data (buffer-substring-no-properties start end)) + (line (buffer-substring-no-properties end (line-end-position)))) + (if (string-match "\\?>" line) + (phps-mode-lexer--return-or-skip-token + 'T_COMMENT + start + (+ end (match-beginning 0))) + (phps-mode-lexer--return-or-skip-token + 'T_COMMENT + start + (line-end-position))))) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at + (concat + "\\(/\\*\\|/\\*\\*" + phps-mode-lexer--whitespace + "\\)")) + (let* ((start (match-beginning 0)) + (end (match-end 0)) + (_data (buffer-substring-no-properties start end)) + (doc-com (looking-at-p (concat "/\\*\\*" phps-mode-lexer--whitespace)))) + (let ((string-start (search-forward "*/" nil t))) + (if string-start + (if doc-com + (progn + (phps-mode-lexer--reset-doc-comment) + (phps-mode-lexer--return-token + 'T_DOC_COMMENT + start) + (phps-mode-lexer--CG 'doc_comment t)) + (phps-mode-lexer--return-token + 'T_COMMENT start)) + (progn + (signal + 'phps-lexer-error + (list + (format + "Unterminated comment starting at %d" + start) + start))))))) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at + (concat + "\\?>" + phps-mode-lexer--newline + "?")) + (let ((start (match-beginning 0)) + (end (match-end 0))) + (when (= (- end start) 3) + (setq end (1- end))) + (phps-mode-lexer--begin 'ST_INITIAL) + (when (phps-mode-lexer--parser-mode) + (phps-mode-lexer--return-token + ";" + start + end)) + (phps-mode-lexer--return-token + 'T_CLOSE_TAG + start + end))) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "'") + (let* ((start (match-beginning 0)) + (end (match-end 0)) + (_data (buffer-substring-no-properties start end)) + (un-escaped-end (phps-mode-lexer--get-next-unescaped "'"))) + (if un-escaped-end + (phps-mode-lexer--return-token + 'T_CONSTANT_ENCAPSED_STRING + start + un-escaped-end) + ;; Unclosed single quotes + (phps-mode-lexer--return-token-with-val + 'T_ENCAPSED_AND_WHITESPACE + start + (point-max)) + (phps-mode-lexer--move-forward + (point-max))))) + +;; Double quoted string +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "\"") + (let* ((start (match-beginning 0)) + (end (match-end 0)) + (_data (buffer-substring-no-properties start end)) + (open-quote t)) + + ;; Move forward from the double-quote one character + (forward-char) + + (while open-quote + (let ((string-start + (search-forward-regexp + (concat + "\\(\"" + "\\|\\$" phps-mode-lexer--label + "\\|\\${" phps-mode-lexer--label + "\\|{\\$" phps-mode-lexer--label "\\)") + nil t))) + + ;; Do we find a ending double quote or starting variable? + (if string-start + (let ((string-start (match-beginning 0)) + (is-escaped nil) + (is-escaped-1 nil) + (is-escaped-2 nil)) + + ;; Check whether one character back is escape character + (goto-char (1- string-start)) + (setq is-escaped-1 (looking-at-p "\\\\")) + + ;; Check whether two characters back is escape character + (goto-char (- string-start 2)) + (setq is-escaped-2 (looking-at-p "\\\\")) + + (setq is-escaped + (and + is-escaped-1 + (not is-escaped-2))) + + ;; Do we find variable inside quote? + (goto-char string-start) + + ;; Process character if it's not escaped + (if is-escaped + (forward-char 1) + (setq open-quote nil) + (if (looking-at "\"") + (let ((_double-quoted-string + (buffer-substring-no-properties start (+ string-start 1)))) + ;; (message "Double quoted string: %s" _double-quoted-string) + (phps-mode-lexer--return-token-with-val + 'T_CONSTANT_ENCAPSED_STRING + start + (+ string-start 1))) + ;; (message "Found variable after '%s' at %s-%s" (buffer-substring-no-properties start string-start) start string-start) + (phps-mode-lexer--begin 'ST_DOUBLE_QUOTES) + (phps-mode-lexer--return-token "\"" start (1+ start))))) + (progn + (setq open-quote nil) + (signal + 'phps-lexer-error + (list + (format "Found no ending of quote at %s" start) + start)))))))) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at + (concat + "<<<" + phps-mode-lexer--tabs-and-spaces + "\\(" + phps-mode-lexer--label + "\\|'" + phps-mode-lexer--label + "'\\|\"" + phps-mode-lexer--label + "\"\\)" + phps-mode-lexer--newline)) + (let* ((start (match-beginning 0)) + (end (match-end 0)) + (data + (buffer-substring-no-properties + (match-beginning 1) + (match-end 1)))) + + ;; Determine if it's HEREDOC or NOWDOC and extract label here + (if (string= (substring data 0 1) "'") + (progn + (setq + phps-mode-lexer--heredoc-label + (substring data 1 (- (length data) 1))) + (phps-mode-lexer--begin 'ST_NOWDOC)) + (progn + (if (string= (substring data 0 1) "\"") + (setq + phps-mode-lexer--heredoc-label + (substring data 1 (- (length data) 1))) + (setq + phps-mode-lexer--heredoc-label + data)) + (phps-mode-lexer--begin 'ST_HEREDOC))) + + ;; Check for ending label on the next line + (when (string= + (buffer-substring-no-properties + end + (+ end + (length + phps-mode-lexer--heredoc-label))) + phps-mode-lexer--heredoc-label) + (phps-mode-lexer--begin 'ST_END_HEREDOC)) + + (push + `(,phps-mode-lexer--heredoc-label ,start ,end) + phps-mode-lexer--heredoc-label-stack) + ;; (message "Found heredoc or nowdoc at %s with label %s" data phps-mode-lexer--heredoc-label) + + (phps-mode-lexer--CG + 'doc_comment + t) + (phps-mode-lexer--return-token + 'T_START_HEREDOC + start + end))) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "[`]") + ;; (message "Begun backquote at %s-%s" (match-beginning 0) (match-end 0)) + (phps-mode-lexer--begin 'ST_BACKQUOTE) + (phps-mode-lexer--return-token "`")) + +(phps-mode-lexer--match-macro + ST_END_HEREDOC + (looking-at + (concat phps-mode-lexer--any-char)) + (let* ((start (match-beginning 0)) + (end (+ start + (length + phps-mode-lexer--heredoc-label) + 1)) + (_data (buffer-substring-no-properties start end))) + ;; (message "Found ending heredoc at %s, %s of %s" _data (thing-at-point 'line) phps-mode-lexer--heredoc-label) + (pop phps-mode-lexer--heredoc-label-stack) + (phps-mode-lexer--begin 'ST_IN_SCRIPTING) + (phps-mode-lexer--return-token 'T_END_HEREDOC start end))) + +(phps-mode-lexer--match-macro + (ST_DOUBLE_QUOTES ST_BACKQUOTE ST_HEREDOC) + (looking-at "{\\$") + (phps-mode-lexer--yy-push-state 'ST_IN_SCRIPTING) + (phps-mode-lexer--yyless 1) + (phps-mode-lexer--enter-nesting "{") + (phps-mode-lexer--return-token + 'T_CURLY_OPEN + (match-beginning 0) + (- (match-end 0) 1))) + +(phps-mode-lexer--match-macro + ST_DOUBLE_QUOTES + (looking-at "[\"]") + (phps-mode-lexer--begin 'ST_IN_SCRIPTING) + (phps-mode-lexer--return-token "\"")) + +(phps-mode-lexer--match-macro + ST_BACKQUOTE + (looking-at "[`]") + (phps-mode-lexer--begin 'ST_IN_SCRIPTING) + (phps-mode-lexer--return-token "`")) + +(phps-mode-lexer--match-macro + ST_DOUBLE_QUOTES + (looking-at phps-mode-lexer--any-char) + (let ((start (point)) + (start-error (car (cdr (nth 2 phps-mode-lexer--generated-tokens))))) + (let ((string-start (search-forward-regexp "[^\\\\]\"" nil t))) + (if string-start + (let* ((end (- (match-end 0) 1)) + (double-quoted-string (buffer-substring-no-properties start end))) + ;; Do we find variable inside quote? + (if (or (string-match (concat "\\${" phps-mode-lexer--label) double-quoted-string) + (string-match (concat "{\\$" phps-mode-lexer--label) double-quoted-string) + (string-match (concat "\\$" phps-mode-lexer--label) double-quoted-string)) + (progn + (let ((variable-start (+ start (match-beginning 0)))) + + ;; (message "Found starting expression inside double-quoted string at: %s %s" start variable-start) + (phps-mode-lexer--return-token-with-val + 'T_ENCAPSED_AND_WHITESPACE + start + variable-start))) + (progn + (phps-mode-lexer--return-token-with-val + 'T_ENCAPSED_AND_WHITESPACE + start + end) + ;; (message "Found end of quote at %s-%s, moving ahead after '%s'" start end (buffer-substring-no-properties start end)) + ))) + (progn + (signal + 'phps-lexer-error + (list + (format "Found no ending of double quoted region starting at %d" start-error) + start-error))))))) + +(phps-mode-lexer--match-macro + ST_BACKQUOTE + (looking-at phps-mode-lexer--any-char) + (let ((start (car (cdr (car phps-mode-lexer--generated-tokens))))) + (let ((string-start (search-forward-regexp "\\([^\\\\]`\\|\\$\\|{\\)" nil t))) + (if string-start + (let ((start (- (match-end 0) 1))) + ;; (message "Skipping backquote forward over %s" (buffer-substring-no-properties old-start start)) + (phps-mode-lexer--return-token-with-val + 'T_ENCAPSED_AND_WHITESPACE + old-start + start)) + (progn + (signal + 'phps-lexer-error + (list + (format "Found no ending of back-quoted string starting at %d" start) + start))))))) + +(phps-mode-lexer--match-macro + ST_HEREDOC + (looking-at phps-mode-lexer--any-char) + ;; Check for $, ${ and {$ forward + (let ((old-start (car (cdr (car phps-mode-lexer--heredoc-label-stack)))) + (old-end (point))) + (let ((string-start + (search-forward-regexp + (concat + "\\(\n" + phps-mode-lexer--heredoc-label + ";?\n\\|\\$" + phps-mode-lexer--label + "\\|{\\$" + phps-mode-lexer--label + "\\|\\${" + phps-mode-lexer--label + "\\)" + ) + nil + t))) + (if string-start + (let* ((start (match-beginning 0)) + (end (match-end 0)) + (data (buffer-substring-no-properties start end))) + + (cond + + ((string-match + (concat + "\n" + phps-mode-lexer--heredoc-label + ";?\n" + ) + data) + ;; (message "Found heredoc end at %s-%s" start end) + (phps-mode-lexer--return-token-with-val + 'T_ENCAPSED_AND_WHITESPACE + old-end + start) + (phps-mode-lexer--begin + 'ST_END_HEREDOC)) + + (t + ;; (message "Found variable at '%s'.. Skipping forward to %s" data start) + (phps-mode-lexer--return-token-with-val + 'T_ENCAPSED_AND_WHITESPACE + old-end + start)) + + )) + (progn + (signal + 'phps-lexer-error + (list + (format "Found no ending of heredoc starting at %d" old-start) + old-start))))))) + +(phps-mode-lexer--match-macro + ST_NOWDOC + (looking-at phps-mode-lexer--any-char) + (let ((start (car (cdr (car phps-mode-lexer--generated-tokens))))) + (let ((string-start (search-forward-regexp + (concat + "\n" + phps-mode-lexer--heredoc-label + ";?\\\n" + ) nil t))) + (if string-start + (let* ((start (match-beginning 0)) + (end (match-end 0)) + (_data (buffer-substring-no-properties start end))) + ;; (message "Found something ending at %s" _data) + ;; (message "Found nowdoc end at %s-%s" start end) + (phps-mode-lexer--return-token-with-val + 'T_ENCAPSED_AND_WHITESPACE + old-start + start) + (phps-mode-lexer--begin + 'ST_END_HEREDOC)) + (progn + (signal + 'phps-lexer-error + (list + (format "Found no ending of nowdoc starting at %d" start) + start))))))) + +(phps-mode-lexer--match-macro + (ST_IN_SCRIPTING ST_VAR_OFFSET) + (looking-at phps-mode-lexer--any-char) + (signal + 'phps-lexer-error + (list + (format "Unexpected character at %d" (match-beginning 0)) + (match-beginning 0)))) (defun phps-mode-lexer--re2c-execute () "Execute matching body (if any)." @@ -493,1343 +1949,33 @@ phps-mode-lexer--state lookahead))) (phps-mode-lexer--reset-match-data) - - (let ((SHEBANG (equal phps-mode-lexer--state 'SHEBANG)) - (ST_IN_SCRIPTING (equal phps-mode-lexer--state 'ST_IN_SCRIPTING)) - (ST_INITIAL (equal phps-mode-lexer--state 'ST_INITIAL)) - (ST_LOOKING_FOR_PROPERTY (equal phps-mode-lexer--state 'ST_LOOKING_FOR_PROPERTY)) - (ST_DOUBLE_QUOTES (equal phps-mode-lexer--state 'ST_DOUBLE_QUOTES)) - (ST_BACKQUOTE (equal phps-mode-lexer--state 'ST_BACKQUOTE)) - (ST_HEREDOC (equal phps-mode-lexer--state 'ST_HEREDOC)) - (ST_NOWDOC (equal phps-mode-lexer--state 'ST_NOWDOC)) - (ST_LOOKING_FOR_VARNAME (equal phps-mode-lexer--state 'ST_LOOKING_FOR_VARNAME)) - (ST_END_HEREDOC (equal phps-mode-lexer--state 'ST_END_HEREDOC)) - (ST_VAR_OFFSET (equal phps-mode-lexer--state 'ST_VAR_OFFSET))) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "exit")) - (phps-mode-lexer--return-token-with-indent 'T_EXIT)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "die")) - (phps-mode-lexer--return-token-with-indent 'T_EXIT)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "fn")) - (phps-mode-lexer--return-token-with-indent 'T_FN)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "function")) - (phps-mode-lexer--return-token-with-indent 'T_FUNCTION)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "const")) - (phps-mode-lexer--return-token-with-indent 'T_CONST)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "return")) - (phps-mode-lexer--return-token-with-indent 'T_RETURN)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "#\\[")) - (phps-mode-lexer--enter-nesting "[") - (phps-mode-lexer--return-token 'T_ATTRIBUTE)) - - (phps-mode-lexer--match-macro - (and - ST_IN_SCRIPTING - (looking-at - (concat - "yield" - phps-mode-lexer--whitespace - "from" - "[^a-zA-Z0-9_\x80-\xff]"))) - (phps-mode-lexer--return-token-with-indent 'T_YIELD_FROM)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "yield")) - (phps-mode-lexer--return-token-with-indent 'T_YIELD)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "try")) - (phps-mode-lexer--return-token-with-indent 'T_TRY)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "catch")) - (phps-mode-lexer--return-token-with-indent 'T_CATCH)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "finally")) - (phps-mode-lexer--return-token-with-indent 'T_FINALLY)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "throw")) - (phps-mode-lexer--return-token-with-indent 'T_THROW)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "if")) - (phps-mode-lexer--return-token-with-indent 'T_IF)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "elseif")) - (phps-mode-lexer--return-token-with-indent 'T_ELSEIF)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "endif")) - (phps-mode-lexer--return-token-with-indent 'T_ENDIF)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "else")) - (phps-mode-lexer--return-token-with-indent 'T_ELSE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "while")) - (phps-mode-lexer--return-token-with-indent 'T_WHILE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "endwhile")) - (phps-mode-lexer--return-token-with-indent 'T_ENDWHILE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "do")) - (phps-mode-lexer--return-token-with-indent 'T_DO)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "for")) - (phps-mode-lexer--return-token-with-indent 'T_FOR)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "endfor")) - (phps-mode-lexer--return-token-with-indent 'T_ENDFOR)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "foreach")) - (phps-mode-lexer--return-token-with-indent 'T_FOREACH)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "endforeach")) - (phps-mode-lexer--return-token-with-indent 'T_ENDFOREACH)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "declare")) - (phps-mode-lexer--return-token-with-indent 'T_DECLARE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "enddeclare")) - (phps-mode-lexer--return-token-with-indent 'T_ENDDECLARE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "instanceof")) - (phps-mode-lexer--return-token-with-indent 'T_INSTANCEOF)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "as")) - (phps-mode-lexer--return-token-with-indent 'T_AS)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "switch")) - (phps-mode-lexer--return-token-with-indent 'T_SWITCH)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "match")) - (phps-mode-lexer--return-token-with-indent 'T_MATCH)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "endswitch")) - (phps-mode-lexer--return-token-with-indent 'T_ENDSWITCH)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "case")) - (phps-mode-lexer--return-token-with-indent 'T_CASE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "default")) - (phps-mode-lexer--return-token-with-indent 'T_DEFAULT)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "break")) - (phps-mode-lexer--return-token-with-indent 'T_BREAK)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "continue")) - (phps-mode-lexer--return-token-with-indent 'T_CONTINUE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "goto")) - (phps-mode-lexer--return-token-with-indent 'T_GOTO)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "echo")) - (phps-mode-lexer--return-token-with-indent 'T_ECHO)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "print")) - (phps-mode-lexer--return-token-with-indent 'T_PRINT)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "class")) - (phps-mode-lexer--return-token-with-indent 'T_CLASS)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "interface")) - (phps-mode-lexer--return-token-with-indent 'T_INTERFACE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "trait")) - (phps-mode-lexer--return-token-with-indent 'T_TRAIT)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "extends")) - (phps-mode-lexer--return-token-with-indent 'T_EXTENDS)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "implements")) - (phps-mode-lexer--return-token-with-indent 'T_IMPLEMENTS)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "->")) - (phps-mode-lexer--yy-push-state 'ST_LOOKING_FOR_PROPERTY) - (phps-mode-lexer--return-token-with-indent 'T_OBJECT_OPERATOR)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "?->")) - (phps-mode-lexer--yy-push-state 'ST_LOOKING_FOR_PROPERTY) - (phps-mode-lexer--return-token-with-indent 'T_NULLSAFE_OBJECT_OPERATOR)) - - (phps-mode-lexer--match-macro - (and (or ST_IN_SCRIPTING ST_LOOKING_FOR_PROPERTY) - (looking-at phps-mode-lexer--whitespace)) - (phps-mode-lexer--return-whitespace)) - - (phps-mode-lexer--match-macro - (and ST_LOOKING_FOR_PROPERTY (looking-at "->")) - (phps-mode-lexer--return-token 'T_OBJECT_OPERATOR)) - - (phps-mode-lexer--match-macro - (and ST_LOOKING_FOR_PROPERTY (looking-at "?->")) - (phps-mode-lexer--return-token 'T_NULLSAFE_OBJECT_OPERATOR)) - - (phps-mode-lexer--match-macro - (and ST_LOOKING_FOR_PROPERTY (looking-at phps-mode-lexer--label)) - (phps-mode-lexer--yy-pop-state) - (phps-mode-lexer--return-token-with-str 'T_STRING 0)) - - (phps-mode-lexer--match-macro - (and ST_LOOKING_FOR_PROPERTY (looking-at phps-mode-lexer--any-char)) - (phps-mode-lexer--yyless 0) - (phps-mode-lexer--yy-pop-state) - (phps-mode-lexer--restart)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "::")) - (phps-mode-lexer--return-token 'T_PAAMAYIM_NEKUDOTAYIM)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "\\.\\.\\.")) - (phps-mode-lexer--return-token 'T_ELLIPSIS)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "\\?\\?")) - (phps-mode-lexer--return-token 'T_COALESCE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "new")) - (phps-mode-lexer--return-token-with-indent 'T_NEW)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "clone")) - (phps-mode-lexer--return-token-with-indent 'T_CLONE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "var")) - (phps-mode-lexer--return-token-with-indent 'T_VAR)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING - (looking-at - (concat - "(" - phps-mode-lexer--tabs-and-spaces - "\\(int\\|integer\\)" - phps-mode-lexer--tabs-and-spaces - ")"))) - (phps-mode-lexer--return-token 'T_INT_CAST)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING - (looking-at - (concat - "(" - phps-mode-lexer--tabs-and-spaces - "\\(double\\|float\\)" - phps-mode-lexer--tabs-and-spaces - ")"))) - (phps-mode-lexer--return-token 'T_DOUBLE_CAST)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING - (looking-at - (concat - "(" - phps-mode-lexer--tabs-and-spaces - "\\(real\\)" - phps-mode-lexer--tabs-and-spaces - ")"))) - (when (phps-mode-lexer--parser-mode) - (signal - 'phps-lexer-error - (list - (format - "The (real) cast has been removed, use (float) instead at %d" - (match-beginning 0)) - (match-beginning 0) - (match-end 0)))) - (phps-mode-lexer--return-token 'T_DOUBLE_CAST)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING - (looking-at - (concat - "(" - phps-mode-lexer--tabs-and-spaces - "\\(string\\|binary\\)" - phps-mode-lexer--tabs-and-spaces - ")"))) - (phps-mode-lexer--return-token 'T_STRING_CAST)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING - (looking-at - (concat - "(" - phps-mode-lexer--tabs-and-spaces - "array" - phps-mode-lexer--tabs-and-spaces - ")"))) - (phps-mode-lexer--return-token 'T_ARRAY_CAST)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING - (looking-at - (concat - "(" - phps-mode-lexer--tabs-and-spaces - "object" - phps-mode-lexer--tabs-and-spaces - ")"))) - (phps-mode-lexer--return-token 'T_OBJECT_CAST)) - - (phps-mode-lexer--match-macro - (and - ST_IN_SCRIPTING - (looking-at - (concat - "(" - phps-mode-lexer--tabs-and-spaces - "\\(bool\\|boolean\\)" - phps-mode-lexer--tabs-and-spaces - ")"))) - (phps-mode-lexer--return-token 'T_BOOL_CAST)) - - (phps-mode-lexer--match-macro - (and - ST_IN_SCRIPTING - (looking-at - (concat - "(" - phps-mode-lexer--tabs-and-spaces - "unset" - phps-mode-lexer--tabs-and-spaces ")"))) - (phps-mode-lexer--return-token 'T_UNSET_CAST)) - - (when (fboundp 'thread-yield) - (thread-yield)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "eval")) - (phps-mode-lexer--return-token-with-indent 'T_EVAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "include")) - (phps-mode-lexer--return-token-with-indent 'T_INCLUDE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "include_once")) - (phps-mode-lexer--return-token-with-indent 'T_INCLUDE_ONCE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "require")) - (phps-mode-lexer--return-token-with-indent 'T_REQUIRE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "require_once")) - (phps-mode-lexer--return-token-with-indent 'T_REQUIRE_ONCE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "namespace")) - (phps-mode-lexer--return-token-with-indent 'T_NAMESPACE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "use")) - (phps-mode-lexer--return-token-with-indent 'T_USE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "insteadof")) - (phps-mode-lexer--return-token-with-indent 'T_INSTEADOF)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "global")) - (phps-mode-lexer--return-token-with-indent 'T_GLOBAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "isset")) - (phps-mode-lexer--return-token-with-indent 'T_ISSET)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "empty")) - (phps-mode-lexer--return-token-with-indent 'T_EMPTY)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "__halt_compiler")) - (phps-mode-lexer--return-token-with-indent 'T_HALT_COMPILER)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "static")) - (phps-mode-lexer--return-token-with-indent 'T_STATIC)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "abstract")) - (phps-mode-lexer--return-token-with-indent 'T_ABSTRACT)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "final")) - (phps-mode-lexer--return-token-with-indent 'T_FINAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "private")) - (phps-mode-lexer--return-token-with-indent 'T_PRIVATE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "protected")) - (phps-mode-lexer--return-token-with-indent 'T_PROTECTED)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "public")) - (phps-mode-lexer--return-token-with-indent 'T_PUBLIC)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "unset")) - (phps-mode-lexer--return-token-with-indent 'T_UNSET)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "=>")) - (phps-mode-lexer--return-token 'T_DOUBLE_ARROW)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "list")) - (phps-mode-lexer--return-token-with-indent 'T_LIST)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "array")) - (phps-mode-lexer--return-token-with-indent 'T_ARRAY)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "callable")) - (phps-mode-lexer--return-token-with-indent 'T_CALLABLE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "\\+\\+")) - (phps-mode-lexer--return-token 'T_INC)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "--")) - (phps-mode-lexer--return-token 'T_DEC)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "===")) - (phps-mode-lexer--return-token 'T_IS_IDENTICAL)) - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "!==")) - (phps-mode-lexer--return-token 'T_IS_NOT_IDENTICAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "==")) - (phps-mode-lexer--return-token 'T_IS_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "\\(!=\\|<>\\)")) - (phps-mode-lexer--return-token 'T_IS_NOT_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "<=>")) - (phps-mode-lexer--return-token 'T_SPACESHIP)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "<=")) - (phps-mode-lexer--return-token 'T_IS_SMALLER_OR_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at ">=")) - (phps-mode-lexer--return-token 'T_IS_GREATER_OR_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "\\+=")) - (phps-mode-lexer--return-token 'T_PLUS_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "-=")) - (phps-mode-lexer--return-token 'T_MINUS_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "\\*=")) - (phps-mode-lexer--return-token 'T_MUL_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "\\*\\\\\\*=")) - (phps-mode-lexer--return-token 'T_POW_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "\\*\\\\\\*")) - (phps-mode-lexer--return-token 'T_POW)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "/=")) - (phps-mode-lexer--return-token 'T_DIV_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "\\.=")) - (phps-mode-lexer--return-token 'T_CONCAT_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "%=")) - (phps-mode-lexer--return-token 'T_MOD_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "<<=")) - (phps-mode-lexer--return-token 'T_SL_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at ">>=")) - (phps-mode-lexer--return-token 'T_SR_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "&=")) - (phps-mode-lexer--return-token 'T_AND_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "|=")) - (phps-mode-lexer--return-token 'T_OR_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "\\^=")) - (phps-mode-lexer--return-token 'T_XOR_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "\\?\\?=")) - (phps-mode-lexer--return-token 'T_COALESCE_EQUAL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "||")) - (phps-mode-lexer--return-token 'T_BOOLEAN_OR)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "&&")) - (phps-mode-lexer--return-token 'T_BOOLEAN_AND)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "OR")) - (phps-mode-lexer--return-token 'T_LOGICAL_OR)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "AND")) - (phps-mode-lexer--return-token 'T_LOGICAL_AND)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "XOR")) - (phps-mode-lexer--return-token 'T_LOGICAL_XOR)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "<<")) - (phps-mode-lexer--return-token 'T_SL)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at ">>")) - (phps-mode-lexer--return-token 'T_SR)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING - (looking-at - (concat "\\(" "]" "\\|" ")" "\\)"))) - (phps-mode-lexer--return-exit-nesting-token)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING - (looking-at - (concat "\\(" "\\[" "\\|" "(" "\\)"))) - (phps-mode-lexer--enter-nesting) - (phps-mode-lexer--return-token)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at phps-mode-lexer--tokens)) - (phps-mode-lexer--return-token)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "{")) - (phps-mode-lexer--yy-push-state 'ST_IN_SCRIPTING) - (phps-mode-lexer--enter-nesting "{") - (phps-mode-lexer--return-token)) - - (phps-mode-lexer--match-macro - (and (or ST_DOUBLE_QUOTES ST_BACKQUOTE ST_HEREDOC) (looking-at "\\${")) - (phps-mode-lexer--yy-push-state 'ST_LOOKING_FOR_VARNAME) - (phps-mode-lexer--enter-nesting "{") - (phps-mode-lexer--return-token 'T_DOLLAR_OPEN_CURLY_BRACES)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "}")) - (phps-mode-lexer--reset-doc-comment) - (when phps-mode-lexer--state-stack - (phps-mode-lexer--yy-pop-state)) - (phps-mode-lexer--return-exit-nesting-token)) - - (phps-mode-lexer--match-macro - (and - ST_LOOKING_FOR_VARNAME - (looking-at (concat phps-mode-lexer--label "[\\[}]"))) - (let* ((start (match-beginning 0)) - (end (1- (match-end 0))) - (_data (buffer-substring-no-properties start end))) - (phps-mode-lexer--yyless 1) - (phps-mode-lexer--yy-pop-state) - (phps-mode-lexer--yy-push-state 'ST_IN_SCRIPTING) - (phps-mode-lexer--return-token 'T_STRING_VARNAME start end))) - - (phps-mode-lexer--match-macro - (and - ST_LOOKING_FOR_VARNAME - (looking-at phps-mode-lexer--any-char)) - (phps-mode-lexer--yyless 0) - (phps-mode-lexer--yy-pop-state) - (phps-mode-lexer--yy-push-state 'ST_IN_SCRIPTING) - (phps-mode-lexer--restart)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING - (looking-at phps-mode-lexer--bnum)) - (let* ((start (match-beginning 0)) - (end (match-end 0)) - (data (buffer-substring-no-properties (+ start 2) end)) - (long-number (string-to-number data 2))) - ;; (message "Binary number %s from %s" long-number data) - (if (> long-number phps-mode-lexer--long-limit) - (phps-mode-lexer--return-token 'T_DNUMBER) - (phps-mode-lexer--return-token 'T_LNUMBER)))) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING - (looking-at phps-mode-lexer--lnum)) - (let* ((start (match-beginning 0)) - (end (match-end 0)) - (data (string-to-number (buffer-substring-no-properties start end)))) - ;; (message "Long number: %d" data) - (if (> data phps-mode-lexer--long-limit) - (phps-mode-lexer--return-token 'T_DNUMBER) - (phps-mode-lexer--return-token 'T_LNUMBER)))) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at phps-mode-lexer--hnum)) - (let* ((start (match-beginning 0)) - (end (match-end 0)) - (data (buffer-substring-no-properties (+ start 2) end)) - (long-number (string-to-number data 16))) - ;; (message "Hexadecimal number %s from %s" long-number data) - (if (> long-number phps-mode-lexer--long-limit) - (phps-mode-lexer--return-token 'T_DNUMBER) - (phps-mode-lexer--return-token 'T_LNUMBER)))) - - (when (fboundp 'thread-yield) - (thread-yield)) - - (phps-mode-lexer--match-macro - (and ST_VAR_OFFSET (looking-at "\\([0]\\|[1-9][0-9]*\\)")) - (phps-mode-lexer--return-token 'T_NUM_STRING)) - - (phps-mode-lexer--match-macro - (and ST_VAR_OFFSET - (looking-at - (concat "\\(" - phps-mode-lexer--lnum "\\|" - phps-mode-lexer--hnum "\\|" - phps-mode-lexer--bnum "\\)"))) - (phps-mode-lexer--return-token 'T_NUM_STRING)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING - (or (looking-at phps-mode-lexer--dnum) - (looking-at phps-mode-lexer--exponent-dnum))) - (phps-mode-lexer--return-token 'T_DNUMBER)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "__CLASS__")) - (phps-mode-lexer--return-token-with-indent 'T_CLASS_C)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "__TRAIT__")) - (phps-mode-lexer--return-token-with-indent 'T_TRAIT_C)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "__FUNCTION__")) - (phps-mode-lexer--return-token-with-indent 'T_FUNC_C)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "__METHOD__")) - (phps-mode-lexer--return-token-with-indent 'T_METHOD_C)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "__LINE__")) - (phps-mode-lexer--return-token-with-indent 'T_LINE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "__FILE__")) - (phps-mode-lexer--return-token-with-indent 'T_FILE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "__DIR__")) - (phps-mode-lexer--return-token-with-indent 'T_DIR)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "__NAMESPACE__")) - (phps-mode-lexer--return-token-with-indent 'T_NS_C)) - - (phps-mode-lexer--match-macro - (and SHEBANG (looking-at (concat "#!.*" phps-mode-lexer--newline))) - (let ((lineno - (1+ - (phps-mode-lexer--CG 'zend_lineno)))) - (phps-mode-lexer--CG 'zend-lineno lineno)) - (phps-mode-lexer--begin 'ST_INITIAL) - (phps-mode-lexer--restart)) - - (phps-mode-lexer--match-macro - (and SHEBANG (looking-at phps-mode-lexer--any-char)) - (phps-mode-lexer--yyless 0) - (phps-mode-lexer--begin 'ST_INITIAL) - (phps-mode-lexer--restart)) - - (phps-mode-lexer--match-macro - (and ST_INITIAL (looking-at "<\\?=")) - (phps-mode-lexer--begin 'ST_IN_SCRIPTING) - (when (phps-mode-lexer--parser-mode) - (phps-mode-lexer--return-token-with-indent 'T_ECHO)) - (phps-mode-lexer--return-token 'T_OPEN_TAG_WITH_ECHO)) - - (phps-mode-lexer--match-macro - (and - ST_INITIAL - (looking-at - (concat - "<\\?php\\([ \t]\\|" - phps-mode-lexer--newline - "\\)"))) - (phps-mode-lexer--handle-newline) - (phps-mode-lexer--begin 'ST_IN_SCRIPTING) - (phps-mode-lexer--return-or-skip-token 'T_OPEN_TAG)) - - (phps-mode-lexer--match-macro - (and ST_INITIAL (looking-at "<\\?php")) - (let ((start (match-beginning 0)) - (end (match-end 0))) - - ;; Allow <?php followed by end of file. - (cond - - ((equal end (point-max)) - (phps-mode-lexer--begin 'ST_IN_SCRIPTING) - (phps-mode-lexer--return-or-skip-token 'T_OPEN_TAG)) - - ((phps-mode-lexer--CG 'short-tags) - (phps-mode-lexer--yyless 2) - (setq end (- end 2)) - (phps-mode-lexer--begin 'ST_IN_SCRIPTING) - (phps-mode-lexer--return-or-skip-token - 'T_OPEN_TAG - start - end)) - - (t - (phps-mode-lexer--inline-char-handler))))) - - (phps-mode-lexer--match-macro - (and ST_INITIAL (looking-at "<\\?")) - (if (phps-mode-lexer--CG 'short-tags) - (progn - (phps-mode-lexer--begin 'ST_IN_SCRIPTING) - (phps-mode-lexer--return-or-skip-token 'T_OPEN_TAG)) - (phps-mode-lexer--inline-char-handler))) - - (phps-mode-lexer--match-macro - (and ST_INITIAL (looking-at phps-mode-lexer--any-char)) - (if (= (point) (point-max)) - (phps-mode-lexer--return-end-token) - (phps-mode-lexer--inline-char-handler))) - - ;; Make sure a label character follows "->" or "?->", otherwise there is no property - ;; and "->"/"?->" will be taken literally - (phps-mode-lexer--match-macro - (and (or ST_DOUBLE_QUOTES ST_HEREDOC ST_BACKQUOTE) - (looking-at - (concat - "\\$" - phps-mode-lexer--label - "->" - "[a-zA-Z_\x80-\xff]"))) - (phps-mode-lexer--yyless 3) - (phps-mode-lexer--yy-push-state 'ST_LOOKING_FOR_PROPERTY) - (phps-mode-lexer--return-token-with-str - 'T_VARIABLE - 1 - (match-beginning 0) - (- (match-end 0) 3))) - - (phps-mode-lexer--match-macro - (and (or ST_DOUBLE_QUOTES ST_HEREDOC ST_BACKQUOTE) - (looking-at - (concat - "\\$" - phps-mode-lexer--label - "\\?->" - "[a-zA-Z_\x80-\xff]"))) - (phps-mode-lexer--yyless 4) - (phps-mode-lexer--yy-push-state 'ST_LOOKING_FOR_PROPERTY) - (phps-mode-lexer--return-token-with-str - 'T_VARIABLE - 1 - (match-beginning 0) - (- (match-end 0) 4))) - - ;; A [ always designates a variable offset, regardless of what follows - (phps-mode-lexer--match-macro - (and (or ST_DOUBLE_QUOTES ST_HEREDOC ST_BACKQUOTE) - (looking-at - (concat - "\\$" - phps-mode-lexer--label - "\\["))) - (phps-mode-lexer--yyless 1) - (phps-mode-lexer--yy-push-state 'ST_VAR_OFFSET) - (phps-mode-lexer--return-token-with-str - 'T_VARIABLE - 1 - (match-beginning 0) - (- (match-end 0) 1))) - - (phps-mode-lexer--match-macro - (and (or - ST_IN_SCRIPTING - ST_DOUBLE_QUOTES - ST_HEREDOC - ST_BACKQUOTE - ST_VAR_OFFSET) - (looking-at - (concat - "\\$" - phps-mode-lexer--label))) - (phps-mode-lexer--return-token-with-str 'T_VARIABLE 1)) - - (phps-mode-lexer--match-macro - (and ST_VAR_OFFSET (looking-at "\\]")) - (phps-mode-lexer--yy-pop-state) - (phps-mode-lexer--return-token-with-str "]" 1)) - - (phps-mode-lexer--match-macro - (and ST_VAR_OFFSET - (looking-at - (concat "\\(" phps-mode-lexer--tokens - "\\|[{}\"`]\\)"))) - (let* ((start (match-beginning 0)) - (end (match-end 0)) - (data (buffer-substring-no-properties start end))) - ;; Only '[' or '-' can be valid, but returning other tokens will allow a more explicit parse error - (phps-mode-lexer--return-token data))) - - (phps-mode-lexer--match-macro - (and ST_VAR_OFFSET (looking-at (concat "[ \n\r\t'#]"))) - ;; Invalid rule to return a more explicit parse error with proper line number - (phps-mode-lexer--yyless 0) - (phps-mode-lexer--yy-pop-state) - (phps-mode-lexer--return-token-with-val 'T_ENCAPSED_AND_WHITESPACE)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING - (looking-at - (concat - "namespace" - "\\(" - "\\\\" - phps-mode-lexer--label - "\\)+"))) - (phps-mode-lexer--return-token-with-str - 'T_NAME_RELATIVE - (1- (length "namespace\\")))) - - (phps-mode-lexer--match-macro - (and - ST_IN_SCRIPTING - (looking-at (concat - phps-mode-lexer--label - "\\(" - "\\\\" - phps-mode-lexer--label - "\\)+"))) - (phps-mode-lexer--return-token-with-str - 'T_NAME_QUALIFIED - 0)) - - (phps-mode-lexer--match-macro - (and - ST_IN_SCRIPTING - (looking-at (concat - "\\\\" - phps-mode-lexer--label - "\\(" - "\\\\" - phps-mode-lexer--label - "\\)*"))) - (phps-mode-lexer--return-token-with-str - 'T_NAME_FULLY_QUALIFIED - 1)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "\\\\")) - (phps-mode-lexer--return-token 'T_NS_SEPARATOR)) - - (phps-mode-lexer--match-macro - (and - (or ST_IN_SCRIPTING ST_VAR_OFFSET) - (looking-at phps-mode-lexer--label)) - (phps-mode-lexer--return-token-with-str 'T_STRING 0)) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "\\(#\\|//\\)")) - (let* ((start (match-beginning 0)) - (end (match-end 0)) - (_data (buffer-substring-no-properties start end)) - (line (buffer-substring-no-properties end (line-end-position)))) - (if (string-match "\\?>" line) - (phps-mode-lexer--return-or-skip-token - 'T_COMMENT - start - (+ end (match-beginning 0))) - (phps-mode-lexer--return-or-skip-token - 'T_COMMENT - start - (line-end-position))))) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING - (looking-at - (concat - "\\(/\\*\\|/\\*\\*" - phps-mode-lexer--whitespace - "\\)"))) - (let* ((start (match-beginning 0)) - (end (match-end 0)) - (_data (buffer-substring-no-properties start end)) - (doc-com (looking-at-p (concat "/\\*\\*" phps-mode-lexer--whitespace)))) - (let ((string-start (search-forward "*/" nil t))) - (if string-start - (if doc-com - (progn - (phps-mode-lexer--reset-doc-comment) - (phps-mode-lexer--return-token - 'T_DOC_COMMENT - start) - (phps-mode-lexer--CG 'doc_comment t)) - (phps-mode-lexer--return-token - 'T_COMMENT start)) - (progn - (signal - 'phps-lexer-error - (list - (format - "Unterminated comment starting at %d" - start) - start))))))) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING - (looking-at - (concat - "\\?>" - phps-mode-lexer--newline - "?"))) - (let ((start (match-beginning 0)) - (end (match-end 0))) - (when (= (- end start) 3) - (setq end (1- end))) - (phps-mode-lexer--begin 'ST_INITIAL) - (when (phps-mode-lexer--parser-mode) - (phps-mode-lexer--return-token - ";" - start - end)) - (phps-mode-lexer--return-token - 'T_CLOSE_TAG - start - end))) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "'")) - (let* ((start (match-beginning 0)) - (end (match-end 0)) - (_data (buffer-substring-no-properties start end)) - (un-escaped-end (phps-mode-lexer--get-next-unescaped "'"))) - (if un-escaped-end - (phps-mode-lexer--return-token - 'T_CONSTANT_ENCAPSED_STRING - start - un-escaped-end) - ;; Unclosed single quotes - (phps-mode-lexer--return-token-with-val - 'T_ENCAPSED_AND_WHITESPACE - start - (point-max)) - (phps-mode-lexer--move-forward - (point-max))))) - - ;; Double quoted string - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "\"")) - (let* ((start (match-beginning 0)) - (end (match-end 0)) - (_data (buffer-substring-no-properties start end)) - (open-quote t)) - - ;; Move forward from the double-quote one character - (forward-char) - - (while open-quote - (let ((string-start - (search-forward-regexp - (concat - "\\(\"" - "\\|\\$" phps-mode-lexer--label - "\\|\\${" phps-mode-lexer--label - "\\|{\\$" phps-mode-lexer--label "\\)") - nil t))) - - ;; Do we find a ending double quote or starting variable? - (if string-start - (let ((string-start (match-beginning 0)) - (is-escaped nil) - (is-escaped-1 nil) - (is-escaped-2 nil)) - - ;; Check whether one character back is escape character - (goto-char (1- string-start)) - (setq is-escaped-1 (looking-at-p "\\\\")) - - ;; Check whether two characters back is escape character - (goto-char (- string-start 2)) - (setq is-escaped-2 (looking-at-p "\\\\")) - - (setq is-escaped - (and - is-escaped-1 - (not is-escaped-2))) - - ;; Do we find variable inside quote? - (goto-char string-start) - - ;; Process character if it's not escaped - (if is-escaped - (forward-char 1) - (setq open-quote nil) - (if (looking-at "\"") - (let ((_double-quoted-string - (buffer-substring-no-properties start (+ string-start 1)))) - ;; (message "Double quoted string: %s" _double-quoted-string) - (phps-mode-lexer--return-token-with-val - 'T_CONSTANT_ENCAPSED_STRING - start - (+ string-start 1))) - ;; (message "Found variable after '%s' at %s-%s" (buffer-substring-no-properties start string-start) start string-start) - (phps-mode-lexer--begin 'ST_DOUBLE_QUOTES) - (phps-mode-lexer--return-token "\"" start (1+ start))))) - (progn - (setq open-quote nil) - (signal - 'phps-lexer-error - (list - (format "Found no ending of quote at %s" start) - start)))))))) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING - (looking-at - (concat - "<<<" - phps-mode-lexer--tabs-and-spaces - "\\(" - phps-mode-lexer--label - "\\|'" - phps-mode-lexer--label - "'\\|\"" - phps-mode-lexer--label - "\"\\)" - phps-mode-lexer--newline))) - (let* ((start (match-beginning 0)) - (end (match-end 0)) - (data - (buffer-substring-no-properties - (match-beginning 1) - (match-end 1)))) - - ;; Determine if it's HEREDOC or NOWDOC and extract label here - (if (string= (substring data 0 1) "'") - (progn - (setq - phps-mode-lexer--heredoc-label - (substring data 1 (- (length data) 1))) - (phps-mode-lexer--begin 'ST_NOWDOC)) - (progn - (if (string= (substring data 0 1) "\"") - (setq - phps-mode-lexer--heredoc-label - (substring data 1 (- (length data) 1))) - (setq - phps-mode-lexer--heredoc-label - data)) - (phps-mode-lexer--begin 'ST_HEREDOC))) - - ;; Check for ending label on the next line - (when (string= - (buffer-substring-no-properties - end - (+ end - (length - phps-mode-lexer--heredoc-label))) - phps-mode-lexer--heredoc-label) - (phps-mode-lexer--begin 'ST_END_HEREDOC)) - - (push - `(,phps-mode-lexer--heredoc-label ,start ,end) - phps-mode-lexer--heredoc-label-stack) - ;; (message "Found heredoc or nowdoc at %s with label %s" data phps-mode-lexer--heredoc-label) - - (phps-mode-lexer--CG - 'doc_comment - t) - (phps-mode-lexer--return-token - 'T_START_HEREDOC - start - end))) - - (phps-mode-lexer--match-macro - (and ST_IN_SCRIPTING (looking-at "[`]")) - ;; (message "Begun backquote at %s-%s" (match-beginning 0) (match-end 0)) - (phps-mode-lexer--begin 'ST_BACKQUOTE) - (phps-mode-lexer--return-token "`")) - - (phps-mode-lexer--match-macro - (and ST_END_HEREDOC - (looking-at - (concat phps-mode-lexer--any-char))) - (let* ((start (match-beginning 0)) - (end (+ start - (length - phps-mode-lexer--heredoc-label) - 1)) - (_data (buffer-substring-no-properties start end))) - ;; (message "Found ending heredoc at %s, %s of %s" _data (thing-at-point 'line) phps-mode-lexer--heredoc-label) - (pop phps-mode-lexer--heredoc-label-stack) - (phps-mode-lexer--begin 'ST_IN_SCRIPTING) - (phps-mode-lexer--return-token 'T_END_HEREDOC start end))) - - (phps-mode-lexer--match-macro - (and (or ST_DOUBLE_QUOTES ST_BACKQUOTE ST_HEREDOC) (looking-at "{\\$")) - (phps-mode-lexer--yy-push-state 'ST_IN_SCRIPTING) - (phps-mode-lexer--yyless 1) - (phps-mode-lexer--enter-nesting "{") - (phps-mode-lexer--return-token - 'T_CURLY_OPEN - (match-beginning 0) - (- (match-end 0) 1))) - - (phps-mode-lexer--match-macro - (and ST_DOUBLE_QUOTES (looking-at "[\"]")) - (phps-mode-lexer--begin 'ST_IN_SCRIPTING) - (phps-mode-lexer--return-token "\"")) - - (phps-mode-lexer--match-macro - (and ST_BACKQUOTE (looking-at "[`]")) - (phps-mode-lexer--begin 'ST_IN_SCRIPTING) - (phps-mode-lexer--return-token "`")) - - (phps-mode-lexer--match-macro - (and ST_DOUBLE_QUOTES - (looking-at phps-mode-lexer--any-char)) - (let ((start (point)) - (start-error (car (cdr (nth 2 phps-mode-lexer--generated-tokens))))) - (let ((string-start (search-forward-regexp "[^\\\\]\"" nil t))) - (if string-start - (let* ((end (- (match-end 0) 1)) - (double-quoted-string (buffer-substring-no-properties start end))) - ;; Do we find variable inside quote? - (if (or (string-match (concat "\\${" phps-mode-lexer--label) double-quoted-string) - (string-match (concat "{\\$" phps-mode-lexer--label) double-quoted-string) - (string-match (concat "\\$" phps-mode-lexer--label) double-quoted-string)) - (progn - (let ((variable-start (+ start (match-beginning 0)))) - - ;; (message "Found starting expression inside double-quoted string at: %s %s" start variable-start) - (phps-mode-lexer--return-token-with-val - 'T_ENCAPSED_AND_WHITESPACE - start - variable-start))) - (progn - (phps-mode-lexer--return-token-with-val - 'T_ENCAPSED_AND_WHITESPACE - start - end) - ;; (message "Found end of quote at %s-%s, moving ahead after '%s'" start end (buffer-substring-no-properties start end)) - ))) - (progn - (signal - 'phps-lexer-error - (list - (format "Found no ending of double quoted region starting at %d" start-error) - start-error))))))) - - (phps-mode-lexer--match-macro - (and ST_BACKQUOTE (looking-at phps-mode-lexer--any-char)) - (let ((start (car (cdr (car phps-mode-lexer--generated-tokens))))) - (let ((string-start (search-forward-regexp "\\([^\\\\]`\\|\\$\\|{\\)" nil t))) - (if string-start - (let ((start (- (match-end 0) 1))) - ;; (message "Skipping backquote forward over %s" (buffer-substring-no-properties old-start start)) - (phps-mode-lexer--return-token-with-val - 'T_ENCAPSED_AND_WHITESPACE - old-start - start)) - (progn - (signal - 'phps-lexer-error - (list - (format "Found no ending of back-quoted string starting at %d" start) - start))))))) - - (phps-mode-lexer--match-macro - (and ST_HEREDOC (looking-at phps-mode-lexer--any-char)) - ;; Check for $, ${ and {$ forward - (let ((old-start (car (cdr (car phps-mode-lexer--heredoc-label-stack)))) - (old-end (point))) - (let ((string-start - (search-forward-regexp - (concat - "\\(\n" - phps-mode-lexer--heredoc-label - ";?\n\\|\\$" - phps-mode-lexer--label - "\\|{\\$" - phps-mode-lexer--label - "\\|\\${" - phps-mode-lexer--label - "\\)" - ) - nil - t))) - (if string-start - (let* ((start (match-beginning 0)) - (end (match-end 0)) - (data (buffer-substring-no-properties start end))) - - (cond - - ((string-match - (concat - "\n" - phps-mode-lexer--heredoc-label - ";?\n" - ) - data) - ;; (message "Found heredoc end at %s-%s" start end) - (phps-mode-lexer--return-token-with-val - 'T_ENCAPSED_AND_WHITESPACE - old-end - start) - (phps-mode-lexer--begin - 'ST_END_HEREDOC)) - - (t - ;; (message "Found variable at '%s'.. Skipping forward to %s" data start) - (phps-mode-lexer--return-token-with-val - 'T_ENCAPSED_AND_WHITESPACE - old-end - start)) - - )) - (progn - (signal - 'phps-lexer-error - (list - (format "Found no ending of heredoc starting at %d" old-start) - old-start))))))) - - (phps-mode-lexer--match-macro - (and ST_NOWDOC (looking-at phps-mode-lexer--any-char)) - (let ((start (car (cdr (car phps-mode-lexer--generated-tokens))))) - (let ((string-start (search-forward-regexp - (concat - "\n" - phps-mode-lexer--heredoc-label - ";?\\\n" - ) nil t))) - (if string-start - (let* ((start (match-beginning 0)) - (end (match-end 0)) - (_data (buffer-substring-no-properties start end))) - ;; (message "Found something ending at %s" _data) - ;; (message "Found nowdoc end at %s-%s" start end) - (phps-mode-lexer--return-token-with-val - 'T_ENCAPSED_AND_WHITESPACE - old-start - start) - (phps-mode-lexer--begin - 'ST_END_HEREDOC)) - (progn - (signal - 'phps-lexer-error - (list - (format "Found no ending of nowdoc starting at %d" start) - start))))))) - - (phps-mode-lexer--match-macro - (and (or ST_IN_SCRIPTING ST_VAR_OFFSET) - (looking-at phps-mode-lexer--any-char)) - (signal - 'phps-lexer-error - (list - (format "Unexpected character at %d" (match-beginning 0)) - (match-beginning 0)))) - - (if phps-mode-lexer--match-length - (progn + ;; Run rules based on state + (when-let ((lambdas + (gethash + phps-mode-lexer--state + phps-mode-lexer--lambdas-by-state))) + (dolist (lambd lambdas) + (funcall lambd))) + + (when (fboundp 'thread-yield) + (thread-yield)) + + ;; Did we find a match? + (if phps-mode-lexer--match-length + (progn + (phps-mode-debug-message + (message + "Found match %s" + phps-mode-lexer--match-body)) + (phps-mode-lexer--re2c-execute) + + (when phps-mode-lexer--restart-flag (phps-mode-debug-message - (message - "Found match %s" - phps-mode-lexer--match-body)) - (phps-mode-lexer--re2c-execute) - - (when phps-mode-lexer--restart-flag - (phps-mode-debug-message - (message "Restarting lexer")) - (phps-mode-lexer--re2c))) - (phps-mode-debug-message - (message "Found nothing at %d" (point)))))) - (when (fboundp 'thread-yield) - (thread-yield))) + (message "Restarting lexer")) + (phps-mode-lexer--re2c))) + (phps-mode-debug-message + (message "Found nothing at %d" (point)))))) (provide 'phps-mode-lexer)