branch: externals/phps-mode commit 3a59ef2141f2ffb80d5af549771546db47880a63 Author: Christian Johansson <christ...@cvj.se> Commit: Christian Johansson <christ...@cvj.se>
Added tests for new lexer tokens --- phps-mode-lexer.el | 2952 +++++++++++++++++++++--------------------- phps-mode-syntax-color.el | 2 +- test/phps-mode-test-lexer.el | 24 + 3 files changed, 1491 insertions(+), 1487 deletions(-) diff --git a/phps-mode-lexer.el b/phps-mode-lexer.el index 4a5dbbc286..66bd2f8c7d 100644 --- a/phps-mode-lexer.el +++ b/phps-mode-lexer.el @@ -116,18 +116,8 @@ ;; VARIABLES -(defconst - phps-mode-lexer--lambdas-by-state - #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data (ST_IN_SCRIPTING ((lambda nil (when (looking-at "exit") (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 nil (phps- [...] -]*" "\\(\\$\\|\\.\\.\\.\\)")) (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 nil (phps-mode-lexer--yyless 1) (phps-mode-lexer--return-token 'T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG (match-beginni [...] -" phps-mode-lexer--heredoc-label ";? -\\|\\$" 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 " -" phps-mode-lexer--heredoc-label ";? -") data) (phps-mode-lexer--return-token-with-val 'T_ENCAPSED_AND_WHITESPACE old-end start) (phps-mode-lexer--begin 'ST_END_HEREDOC)) (t (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)))))))) (setq phps-mode-lexer--match-data (match-data))))))))) ST_LOOKING_FOR_VARNAME ((lambda nil (when (looking-at (concat phps-mode-lexer--label "[\\[}]")) [...] - '#]")) (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 nil (phps-mode-lexer--yyless 0) (phps-mode-lexer--yy-pop-state) (phps-mode-lexer--return-token-with-val 'T_ENCAPSED_AND_WHITESPACE))) (setq [...] -" phps-mode-lexer--heredoc-label ";?\\ -") nil t))) (if string-start (let* ((start (match-beginning 0)) (end (match-end 0)) (_data (buffer-substring-no-properties start end))) (phps-mode-lexer--return-token-with-val 'T_ENCAPSED_AND_WHITESPACE phps-mode-lexer--generated-new-tokens-index 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)))))))) (setq phps-mode-lexer--match-data (match-data))))))))))) - "Hash-map of lambdas by state.") +(defvar phps-mode-lexer--lambdas-by-state (make-hash-table :test 'equal) + "Hash-table of lex-analyzer rules organized by state.") (defvar-local phps-mode-lexer--generated-tokens nil "List of current generated tokens.") @@ -494,1512 +484,1502 @@ ;; Setup lexer rules - -(defun phps-mode-lxer--generate-lexer-rules () - "Generate lexer match rules." - - (eval-when-compile - (setq - phps-mode-lexer--lambdas-by-state - (make-hash-table :test 'equal))) - - (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 (concat "enum" phps-mode-lexer--whitespace "[a-zA-Z_\x80-\xff]")) - (phps-mode-lexer--yyless 4) - (phps-mode-lexer--return-token-with-indent 'T_ENUM)) - - (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 "readonly") - (phps-mode-lexer--return-token-with-indent 'T_READONLY)) - - ;; Don't treat "readonly(" as a keyword, to allow using it as a function name. - (phps-mode-lexer--match-macro - ST_IN_SCRIPTING - (looking-at (concat "readonly" "[ \n\r\t]*(")) - (phps-mode-lexer--yyless (length "readonly")) - (phps-mode-lexer--return-token-with-indent 'T_READONLY)) - - (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)) - - (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_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 "&" "[ \t\r\n]*" "\\(\\$\\|\\.\\.\\.\\)")) +(eval-when-compile + (setq phps-mode-lexer--lambdas-by-state (make-hash-table :test 'equal))) + +(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 (concat "enum" phps-mode-lexer--whitespace "[a-zA-Z_\x80-\xff]")) + (phps-mode-lexer--yyless 4) + (phps-mode-lexer--return-token-with-indent 'T_ENUM)) + +(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 "readonly") + (phps-mode-lexer--return-token-with-indent 'T_READONLY)) + +;; Don't treat "readonly(" as a keyword, to allow using it as a function name. +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at (concat "readonly" "[ \n\r\t]*(")) + (phps-mode-lexer--yyless (length "readonly")) + (phps-mode-lexer--return-token-with-indent 'T_READONLY)) + +(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)) + +(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_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 "&" "[ \t\r\n]*" "\\(\\$\\|\\.\\.\\.\\)")) + (phps-mode-lexer--yyless 1) + (phps-mode-lexer--return-token + 'T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG + (match-beginning 0) + (- (match-end 0) 1))) + +(phps-mode-lexer--match-macro + ST_IN_SCRIPTING + (looking-at "&") + (phps-mode-lexer--return-token 'T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG)) + +(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--return-token - 'T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG - (match-beginning 0) - (- (match-end 0) 1))) - - (phps-mode-lexer--match-macro - ST_IN_SCRIPTING - (looking-at "&") - (phps-mode-lexer--return-token 'T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG)) - - (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 - (replace-regexp-in-string - "_" - "" - (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--onum) - (let* ((start (match-beginning 0)) - (end (match-end 0)) - (data (string-to-number - (replace-regexp-in-string - "_" - "" - (buffer-substring-no-properties start end)) - 8))) - (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--lnum) - (let* ((start (match-beginning 0)) - (end (match-end 0)) - (data (string-to-number - (replace-regexp-in-string - "_" - "" - (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 - (replace-regexp-in-string - "_" - "" - (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--onum "\\)")) - (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--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 + (replace-regexp-in-string + "_" + "" + (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--onum) + (let* ((start (match-beginning 0)) + (end (match-end 0)) + (data (string-to-number + (replace-regexp-in-string + "_" + "" + (buffer-substring-no-properties start end)) + 8))) + (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--lnum) + (let* ((start (match-beginning 0)) + (end (match-end 0)) + (data (string-to-number + (replace-regexp-in-string + "_" + "" + (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 + (replace-regexp-in-string + "_" + "" + (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--onum "\\)")) + (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))) + + (cond + + ;; Allow <?php followed by end of file. + ((equal end (point-max)) + (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))) + ;; Degenerate case: <?phpX is interpreted as <? phpX with short tags + ((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)) - (cond + (t + (phps-mode-lexer--inline-char-handler))))) - ;; Allow <?php followed by end of file. - ((equal end (point-max)) +(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)) - - ;; Degenerate case: <?phpX is interpreted as <? phpX with short tags - ((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))) - - ;; TODO Was here - - (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--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 - (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 + (+ end (match-beginning 0))) + (phps-mode-lexer--return-or-skip-token + 'T_COMMENT 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)) + (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 - (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) + (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 - 'T_START_HEREDOC + ";" start - end))) + 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))) - (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))) + ;; 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)) - (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))) + ;; Check whether one character back is escape character + (goto-char (1- string-start)) + (setq is-escaped-1 (looking-at-p "\\\\")) - (phps-mode-lexer--match-macro - ST_DOUBLE_QUOTES - (looking-at "[\"]") - (phps-mode-lexer--begin 'ST_IN_SCRIPTING) - (phps-mode-lexer--return-token "\"")) + ;; Check whether two characters back is escape character + (goto-char (- string-start 2)) + (setq is-escaped-2 (looking-at-p "\\\\")) - (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)))) + (setq is-escaped + (and + is-escaped-1 + (not is-escaped-2))) - ;; (message "Found starting expression inside double-quoted string at: %s %s" start variable-start) + ;; 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_ENCAPSED_AND_WHITESPACE + 'T_CONSTANT_ENCAPSED_STRING 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 phps-mode-lexer--generated-new-tokens-index start)) - (phps-mode-lexer--return-token-with-val - 'T_ENCAPSED_AND_WHITESPACE - phps-mode-lexer--generated-new-tokens-index - 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 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) + (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 - 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) + 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 phps-mode-lexer--generated-new-tokens-index start)) + (phps-mode-lexer--return-token-with-val + 'T_ENCAPSED_AND_WHITESPACE + phps-mode-lexer--generated-new-tokens-index + 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 - phps-mode-lexer--generated-new-tokens-index + old-end 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)))) + (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 + phps-mode-lexer--generated-new-tokens-index + 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)." @@ -2051,9 +2031,9 @@ ;; Run rules based on state (when-let ((lambdas - (gethash - phps-mode-lexer--state - phps-mode-lexer--lambdas-by-state))) + (gethash + phps-mode-lexer--state + phps-mode-lexer--lambdas-by-state))) (dolist (lambd lambdas) (funcall lambd))) diff --git a/phps-mode-syntax-color.el b/phps-mode-syntax-color.el index 5f622b2c08..2615bc8d0b 100644 --- a/phps-mode-syntax-color.el +++ b/phps-mode-syntax-color.el @@ -11,7 +11,7 @@ (defvar phps-mode-syntax-color--token-font-face - #s(hash-table size 149 test equal rehash-size 1.5 rehash-threshold 0.8125 data (T_ERROR font-lock-warning-face T_OPEN_TAG font-lock-constant-face T_OPEN_TAG_WITH_ECHO font-lock-constant-face T_CLOSE_TAG font-lock-constant-face T_START_HEREDOC font-lock-constant-face T_END_HEREDOC font-lock-constant-face T_ELLIPSIS font-lock-constant-face T_COALESCE font-lock-constant-face T_DOUBLE_ARROW font-lock-constant-face T_INC font-lock-constant-face T_DEC font-lock-constant-face T_IS_IDENTICAL f [...] + #s(hash-table size 151 test equal rehash-size 1.5 rehash-threshold 0.8125 data (T_ERROR font-lock-warning-face T_OPEN_TAG font-lock-constant-face T_OPEN_TAG_WITH_ECHO font-lock-constant-face T_CLOSE_TAG font-lock-constant-face T_START_HEREDOC font-lock-constant-face T_END_HEREDOC font-lock-constant-face T_ELLIPSIS font-lock-constant-face T_COALESCE font-lock-constant-face T_DOUBLE_ARROW font-lock-constant-face T_INC font-lock-constant-face T_DEC font-lock-constant-face T_IS_IDENTICAL f [...] "Syntax color table for tokens") (defvar diff --git a/test/phps-mode-test-lexer.el b/test/phps-mode-test-lexer.el index a403f0cbbb..4d6176e034 100644 --- a/test/phps-mode-test-lexer.el +++ b/test/phps-mode-test-lexer.el @@ -284,6 +284,30 @@ phps-mode-lex-analyzer--tokens '((T_OPEN_TAG 1 . 7) (T_STRING 7 . 10) (";" 10 . 11) (T_COMMENT 12 . 31) (T_COMMENT 32 . 51) (T_COMMENT 52 . 70) (T_NAME_QUALIFIED 73 . 80) (";" 80 . 81) (T_COMMENT 82 . 125) (T_COMMENT 126 . 153) (T_COMMENT 154 . 185) (T_NAME_FULLY_QUALIFIED 188 . 192) (";" 192 . 193) (T_COMMENT 194 . 228) (T_COMMENT 229 . 262) (T_COMMENT 263 . 287) (T_NAME_RELATIVE 290 . 303) (";" 303 . 304) (T_COMMENT 305 . 351) (T_COMMENT 352 . 378) (T_COMMENT 379 . 414))))) + (phps-mode-test--with-buffer + "<?php\nenum Suit\n{\n case Hearts;\n case Diamonds;\n case Clubs;\n case Spades;\n}" + "Basic Enumerations" + (should + (equal + phps-mode-lex-analyzer--tokens + '((T_OPEN_TAG 1 . 7) (T_ENUM 7 . 13) (T_STRING 13 . 16) ("{" 17 . 18) (T_CASE 23 . 27) (T_STRING 28 . 34) (";" 34 . 35) (T_CASE 40 . 44) (T_STRING 45 . 53) (";" 53 . 54) (T_CASE 59 . 63) (T_STRING 64 . 69) (";" 69 . 70) (T_CASE 75 . 79) (T_STRING 80 . 86) (";" 86 . 87) ("}" 88 . 89))))) + + (phps-mode-test--with-buffer + "<?php\nclass User {\n public readonly int $uid;\n\n public function __construct(int $uid) {\n $this->uid = $uid;\n }\n}" + "Read-only Properties" + (should + (equal + phps-mode-lex-analyzer--tokens + '((T_OPEN_TAG 1 . 7) (T_CLASS 7 . 12) (T_STRING 13 . 17) ("{" 18 . 19) (T_PUBLIC 24 . 30) (T_READONLY 31 . 39) (T_STRING 40 . 43) (T_VARIABLE 44 . 48) (";" 48 . 49) (T_PUBLIC 55 . 61) (T_FUNCTION 62 . 70) (T_STRING 71 . 82) ("(" 82 . 83) (T_STRING 83 . 86) (T_VARIABLE 87 . 91) (")" 91 . 92) ("{" 93 . 94) (T_VARIABLE 103 . 108) (T_OBJECT_OPERATOR 108 . 110) (T_STRING 110 . 113) ("=" 114 . 115) (T_VARIABLE 116 . 120) (";" 120 . 121) ("}" 126 . 127) ("}" 128 . 129))))) + + (phps-mode-test--with-buffer + "<?php\n$a = 1234; // decimal number\n$a = 0123; // octal number (equivalent to 83 decimal)\n$a = 0o123; // octal number (as of PHP 8.1.0)\n$a = 0x1A; // hexadecimal number (equivalent to 26 decimal)\n$a = 0b11111111; // binary number (equivalent to 255 decimal)\n$a = 1_234_567; // decimal number (as of PHP 7.4.0)\n?>\n" + "Integers with underscores" + (should + (equal + phps-mode-lex-analyzer--tokens + '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 9) ("=" 10 . 11) (T_LNUMBER 12 . 16) (";" 16 . 17) (T_COMMENT 18 . 35) (T_VARIABLE 36 . 38) ("=" 39 . 40) (T_LNUMBER 41 . 45) (";" 45 . 46) (T_COMMENT 47 . 89) (T_VARIABLE 90 . 92) ("=" 93 . 94) (T_LNUMBER 95 . 100) (";" 100 . 101) (T_COMMENT 102 . 135) (T_VARIABLE 136 . 138) ("=" 139 . 140) (T_LNUMBER 141 . 145) (";" 145 . 146) (T_COMMENT 147 . 195) (T_VARIABLE 196 . 198) ("=" 199 . 200) (T_LNUMBER 201 . 211) (";" 211 . 212) (T_COMMENT 213 . 257 [...] + ) (defun phps-mode-test-lexer--complex-tokens ()