emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/phps-mode b42ffaf: Added support for PHP 8.0


From: Christian Johansson
Subject: [elpa] externals/phps-mode b42ffaf: Added support for PHP 8.0
Date: Thu, 28 Jan 2021 16:50:33 -0500 (EST)

branch: externals/phps-mode
commit b42ffaff0dad99e596327eed002a03a80e69eac8
Author: Christian Johansson <christian@cvj.se>
Commit: Christian Johansson <christian@cvj.se>

    Added support for PHP 8.0
---
 README.md                           |    2 +-
 admin/phps-mode-automation.el       |    2 +-
 phps-mode-flymake.el                |    2 +-
 phps-mode-lex-analyzer.el           |  184 ++++--
 phps-mode-lexer.el                  | 1216 +++++++++++++++++++++++------------
 phps-mode-macros.el                 |    2 +-
 phps-mode-parser-grammar-macro.el   |    2 +-
 phps-mode-serial.el                 |    2 +-
 phps-mode-syntax-table.el           |    2 +-
 phps-mode-test.el                   |   35 +-
 phps-mode.el                        |    6 +-
 test/phps-mode-test-integration.el  |    4 +-
 test/phps-mode-test-lex-analyzer.el |   20 +-
 test/phps-mode-test-lexer.el        |  533 +++++++++------
 test/phps-mode-test-parser.el       |    2 +-
 test/phps-mode-test-syntax-table.el |    2 +-
 16 files changed, 1319 insertions(+), 697 deletions(-)

diff --git a/README.md b/README.md
index 99cdfdd..b47b5de 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ This mode does not require PHP installed on your computer 
because it has a built
 
 * GPLv3 license
 * Flycheck support with `(phps-mode-flycheck-setup)`
-* Semantic lexer based on official PHP 7.4 re2c lexer
+* Semantic lexer based on official PHP 8.0 re2c lexer
 * Syntax coloring based on lexer tokens, makes it easier to spot invalid code
 * PSR-1, PSR-2 and PSR-12 indentation based on lexer tokens
 * PSR-1, PSR-2 and PSR-12 supported white-space
diff --git a/admin/phps-mode-automation.el b/admin/phps-mode-automation.el
index 6e900a9..d4ff671 100644
--- a/admin/phps-mode-automation.el
+++ b/admin/phps-mode-automation.el
@@ -1,6 +1,6 @@
 ;;; phps-automation --- Generate a Wisent Parser file -*- lexical-binding: t 
-*-
 
-;; Copyright (C) 2018-2020  Free Software Foundation, Inc.
+;; Copyright (C) 2018-2021  Free Software Foundation, Inc.
 
 ;; This file is not part of GNU Emacs.
 
diff --git a/phps-mode-flymake.el b/phps-mode-flymake.el
index b1d1078..ab3c5ec 100644
--- a/phps-mode-flymake.el
+++ b/phps-mode-flymake.el
@@ -1,6 +1,6 @@
 ;;; phps-mode-flymake.el --- Flymake support for PHPs -*- lexical-binding: t 
-*-
 
-;; Copyright (C) 2018-2019  Free Software Foundation, Inc.
+;; Copyright (C) 2018-2021  Free Software Foundation, Inc.
 
 ;; This file is not part of GNU Emacs.
 
diff --git a/phps-mode-lex-analyzer.el b/phps-mode-lex-analyzer.el
index 4846e4f..f834f18 100644
--- a/phps-mode-lex-analyzer.el
+++ b/phps-mode-lex-analyzer.el
@@ -1,6 +1,6 @@
 ;;; phps-mode-lex-analyzer.el -- Lex analyzer for PHPs -*- lexical-binding: t 
-*-
 
-;; Copyright (C) 2018-2020  Free Software Foundation, Inc.
+;; Copyright (C) 2018-2021  Free Software Foundation, Inc.
 
 ;; This file is not part of GNU Emacs.
 
@@ -89,6 +89,9 @@
 (defvar-local phps-mode-lex-analyzer--heredoc-label-stack nil
   "Latest Heredoc label-stack.")
 
+(defvar-local phps-mode-lex-analyzer--nest-location-stack nil
+  "Nest location stack.")
+
 
 ;; FUNCTIONS
 
@@ -106,7 +109,8 @@
   (setq phps-mode-lex-analyzer--state nil)
   (setq phps-mode-lex-analyzer--state-stack nil)
   (setq phps-mode-lex-analyzer--states nil)
-  (setq phps-mode-lex-analyzer--tokens nil))
+  (setq phps-mode-lex-analyzer--tokens nil)
+  (setq phps-mode-lex-analyzer--nest-location-stack nil))
 
 (defun phps-mode-lex-analyzer--set-region-syntax-color (start end properties)
   "Do syntax coloring for region START to END with PROPERTIES."
@@ -138,15 +142,23 @@
 
      ((or
        (equal token-name 'T_VARIABLE)
-       (equal token-name 'T_STRING_VARNAME))
+       (equal token-name 'T_STRING_VARNAME)
+       (equal token-name 'T_NAME_RELATIVE)
+       (equal token-name 'T_NAME_QUALIFIED)
+       (equal token-name 'T_NAME_FULLY_QUALIFIED))
       (list 'font-lock-face 'font-lock-variable-name-face))
 
-     ((equal token-name 'T_COMMENT)
+     ((or
+       (equal token-name 'T_COMMENT)
+       (equal token-name 'END))
       (list 'font-lock-face 'font-lock-comment-face))
 
      ((equal token-name 'T_DOC_COMMENT)
       (list 'font-lock-face 'font-lock-doc-face))
 
+     ((equal token-name 'T_ATTRIBUTE)
+      (list 'font-lock-face 'font-lock-doc-face))
+
      ((equal token-name 'T_INLINE_HTML)
       ;; NOTE T_INLINE_HTML is missing by purpose here to distinguish those 
areas from other entities
       nil)
@@ -164,6 +176,7 @@
        (equal token-name 'T_DOLLAR_OPEN_CURLY_BRACES)
        (equal token-name 'T_CURLY_OPEN)
        (equal token-name 'T_OBJECT_OPERATOR)
+       (equal token-name 'T_NULLSAFE_OBJECT_OPERATOR)
        (equal token-name 'T_PAAMAYIM_NEKUDOTAYIM)
        (equal token-name 'T_NS_SEPARATOR)
        (equal token-name 'T_EXIT)
@@ -294,7 +307,6 @@
       (list 'font-lock-face 'font-lock-constant-face))
 
      ((equal token-name 'T_ERROR)
-      ;; NOTE This token-name is artificial and not PHP native
       (list 'font-lock-face 'font-lock-warning-face))
 
      (t (list 'font-lock-face 'font-lock-constant-face)))))
@@ -389,6 +401,7 @@
              (setq phps-mode-lex-analyzer--state-stack (nth 3 lex-result))
              (setq phps-mode-lex-analyzer--heredoc-label (nth 4 lex-result))
              (setq phps-mode-lex-analyzer--heredoc-label-stack (nth 5 
lex-result))
+             (setq phps-mode-lex-analyzer--nest-location-stack (nth 6 
lex-result))
 
              ;; Save processed result
              (setq phps-mode-lex-analyzer--processed-buffer-p t)
@@ -429,8 +442,15 @@
                           error-start
                           (point-max)
                           (list 'font-lock-face 'font-lock-warning-face))))
-                     (display-warning 'phps-mode error-message :warning "*PHPs 
Lexer Errors*"))
-                 (display-warning error-type error-message :warning)))))))
+                     (display-warning
+                      'phps-mode
+                      error-message
+                      :warning
+                      "*PHPs Lexer Errors*"))
+                 (display-warning
+                  error-type
+                  error-message
+                  :warning)))))))
 
      nil
 
@@ -439,7 +459,7 @@
 
 (defun phps-mode-lex-analyzer--incremental-lex-string
     (buffer-name buffer-contents incremental-start-new-buffer point-max
-                 head-states incremental-state incremental-state-stack 
incremental-heredoc-label incremental-heredoc-label-stack head-tokens &optional 
force-synchronous)
+                 head-states incremental-state incremental-state-stack 
incremental-heredoc-label incremental-heredoc-label-stack 
incremental-nest-location-stack head-tokens &optional force-synchronous)
   "Incremental lex region."
   (let ((async (and (boundp 'phps-mode-async-process)
                     phps-mode-async-process))
@@ -452,16 +472,18 @@
      buffer-name
 
      (lambda()
-       (let* ((lex-result (phps-mode-lex-analyzer--lex-string
-                           buffer-contents
-                           incremental-start-new-buffer
-                           point-max
-                           head-states
-                           incremental-state
-                           incremental-state-stack
-                           incremental-heredoc-label
-                           incremental-heredoc-label-stack
-                           head-tokens))
+       (let* ((lex-result
+               (phps-mode-lex-analyzer--lex-string
+                buffer-contents
+                incremental-start-new-buffer
+                point-max
+                head-states
+                incremental-state
+                incremental-state-stack
+                incremental-heredoc-label
+                incremental-heredoc-label-stack
+                incremental-nest-location-stack
+                head-tokens))
               (processed-result
                (phps-mode-lex-analyzer--process-tokens-in-string
                 (nth 0 lex-result)
@@ -483,6 +505,7 @@
              (setq phps-mode-lex-analyzer--state-stack (nth 3 lex-result))
              (setq phps-mode-lex-analyzer--heredoc-label (nth 4 lex-result))
              (setq phps-mode-lex-analyzer--heredoc-label-stack (nth 5 
lex-result))
+             (setq phps-mode-lex-analyzer--nest-location-stack (nth 6 
lex-result))
 
              ;; Save processed result
              (setq phps-mode-lex-analyzer--processed-buffer-p t)
@@ -528,8 +551,15 @@
                           error-start
                           (point-max)
                           (list 'font-lock-face 'font-lock-warning-face))))
-                     (display-warning 'phps-mode error-message :warning "*PHPs 
Lexer Errors*"))
-                 (display-warning error-type error-message :warning)))))))
+                     (display-warning
+                      'phps-mode
+                      error-message
+                      :warning
+                      "*PHPs Lexer Errors*"))
+                 (display-warning
+                  error-type
+                  error-message
+                  :warning)))))))
 
      nil
      async
@@ -623,6 +653,7 @@
                     (incremental-state-stack nil)
                     (incremental-heredoc-label nil)
                     (incremental-heredoc-label-stack nil)
+                    (incremental-nest-location-stack nil)
                     (incremental-tokens nil)
                     (head-states '())
                     (head-tokens '())
@@ -642,6 +673,7 @@
                 (setq phps-mode-lex-analyzer--state-stack nil)
                 (setq phps-mode-lex-analyzer--heredoc-label nil)
                 (setq phps-mode-lex-analyzer--heredoc-label-stack nil)
+                (setq phps-mode-lex-analyzer--nest-location-stack nil)
 
                 ;; NOTE Starts are inclusive while ends are exclusive buffer 
locations
 
@@ -687,6 +719,7 @@
                                   (setq incremental-state-stack (nth 3 
state-object))
                                   (setq incremental-heredoc-label (nth 4 
state-object))
                                   (setq incremental-heredoc-label-stack (nth 5 
state-object))
+                                  (setq incremental-nest-location-stack (nth 6 
state-object))
                                   (push state-object head-states))
                               (throw 'quit "break")))))
 
@@ -695,7 +728,8 @@
                        (message "Incremental state: %s" incremental-state)
                        (message "State stack: %s" incremental-state-stack)
                        (message "Incremental heredoc-label: %s" 
incremental-heredoc-label)
-                       (message "Incremental heredoc-label-stack: %s" 
incremental-heredoc-label-stack))
+                       (message "Incremental heredoc-label-stack: %s" 
incremental-heredoc-label-stack)
+                       (message "Incremental nest-location-stack: %s" 
incremental-nest-location-stack))
 
                       (if (and
                            head-states
@@ -718,6 +752,7 @@
                              incremental-state-stack
                              incremental-heredoc-label
                              incremental-heredoc-label-stack
+                             incremental-nest-location-stack
                              head-tokens
                              force-synchronous)
 
@@ -1187,22 +1222,32 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
                       ;; Flag super-globals
                       (when (and (equal token 'T_VARIABLE)
                                  (or
+                                  (equal bookkeeping-variable-name "$GLOBALS")
                                   (equal bookkeeping-variable-name "$_COOKIE")
+                                  (equal bookkeeping-variable-name "$_ENV")
+                                  (equal bookkeeping-variable-name "$_FILES")
                                   (equal bookkeeping-variable-name "$_GET")
-                                  (equal bookkeeping-variable-name "$_GLOBALS")
                                   (equal bookkeeping-variable-name "$_POST")
                                   (equal bookkeeping-variable-name "$_REQUEST")
                                   (equal bookkeeping-variable-name "$_SERVER")
                                   (equal bookkeeping-variable-name "$_SESSION")
-                                  (equal bookkeeping-variable-name "$_FILES")))
+                                  ))
                         (setq bookkeeping-is-superglobal t))
 
                       ;; Build name-space
                       (when (and imenu-in-namespace-name
                                  (or imenu-in-class-name 
imenu-in-function-name))
-                        (setq bookkeeping-namespace (concat 
bookkeeping-namespace " namespace " imenu-in-namespace-name)))
+                        (setq bookkeeping-namespace
+                              (concat
+                               bookkeeping-namespace
+                               " namespace "
+                               imenu-in-namespace-name)))
                       (when imenu-in-class-name
-                        (setq bookkeeping-namespace (concat 
bookkeeping-namespace " class " imenu-in-class-name)))
+                        (setq bookkeeping-namespace
+                              (concat
+                               bookkeeping-namespace
+                               " class "
+                               imenu-in-class-name)))
 
                       (when (and
                              (equal token 'T_VARIABLE)
@@ -1227,19 +1272,25 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
                           ;; (message "%s->%s" bookkeeping2-variable-name 
bookkeeping-variable-name)
                           (when (string= bookkeeping2-variable-name "$this")
                             (setq bookkeeping-namespace (concat 
bookkeeping-namespace " id $" bookkeeping-variable-name))
-                            ;; (message "Was here: '%s" bookkeeping-namespace)
                             (setq bookkeeping-named t))))
 
                       (unless bookkeeping-named
                         (when imenu-in-function-name
-                          (setq bookkeeping-namespace (concat 
bookkeeping-namespace " function " imenu-in-function-name))
+                          (setq bookkeeping-namespace
+                                (concat
+                                 bookkeeping-namespace
+                                 " function "
+                                 imenu-in-function-name))
 
                           ;; Add $this special variable in class function scope
                           (when (and imenu-in-class-name
                                      (not imenu-in-interface-class))
                             (let ((bookkeeping-method-this (concat 
bookkeeping-namespace " id $this")))
                               (unless (gethash bookkeeping-method-this 
bookkeeping)
-                                (puthash bookkeeping-method-this 1 
bookkeeping)))))
+                                (puthash
+                                 bookkeeping-method-this
+                                 1
+                                 bookkeeping)))))
 
                         ;; Anonymous function level
                         (when in-anonymous-function-nesting-level
@@ -1271,7 +1322,10 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
                         (when bookkeeping-alternative-namespace
                           (setq bookkeeping-alternative-namespace (concat 
bookkeeping-alternative-namespace " id " bookkeeping-variable-name))))
 
-                      (phps-mode-debug-message (message 
"Bookkeeping-namespace: '%s'" bookkeeping-namespace))
+                      (phps-mode-debug-message
+                       (message
+                        "Bookkeeping-namespace: '%s'"
+                        bookkeeping-namespace))
 
                       ;; Support for ($i = 0), if ($a = ), if (!$ = ), while 
($a = ) and do {} while ($a = ) assignments here
                       (when (and
@@ -1377,13 +1431,18 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
 
                       ;; Do we have a assignment?
                       (when bookkeeping-in-assignment
-                        (let ((declarations (gethash bookkeeping-namespace 
bookkeeping)))
+                        (let ((declarations
+                               (gethash
+                                bookkeeping-namespace
+                                bookkeeping)))
                           ;; Track number of times this variable is defined
                           (unless declarations
                             (setq declarations 0))
                           (setq declarations (1+ declarations))
                           (phps-mode-debug-message
-                           (message "Bookkeeping-assignment: '%s'" 
bookkeeping-namespace))
+                           (message
+                            "Bookkeeping-assignment: '%s'"
+                            bookkeeping-namespace))
                           (puthash bookkeeping-namespace declarations 
bookkeeping)))
 
                       (if bookkeeping-is-superglobal
@@ -1609,10 +1668,11 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
 
                  ((string= token "}")
 
-                  (when (and imenu-open-namespace-level
-                             (= imenu-open-namespace-level imenu-nesting-level)
-                             imenu-in-namespace-name
-                             imenu-namespace-index)
+                  (when (and
+                         imenu-open-namespace-level
+                         (= imenu-open-namespace-level imenu-nesting-level)
+                         imenu-in-namespace-name
+                         imenu-namespace-index)
                     (let ((imenu-add-list (nreverse imenu-namespace-index)))
                       (push `(,imenu-in-namespace-name . ,imenu-add-list) 
imenu-index))
                     (setq imenu-in-namespace-name nil))
@@ -1646,8 +1706,11 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
                     (setq imenu-namespace-index '())
                     (setq imenu-in-namespace-declaration nil))
 
-                   ((and (or (equal token 'T_STRING)
-                             (equal token 'T_NS_SEPARATOR))
+                   ((and (or
+                          (equal token 'T_STRING)
+                          (equal token 'T_NAME_RELATIVE)
+                          (equal token 'T_NAME_FULLY_QUALIFIED)
+                          (equal token 'T_NAME_QUALIFIED))
                          (setq
                           imenu-in-namespace-name
                           (concat
@@ -3005,7 +3068,7 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
   (unless phps-mode-lex-analyzer--state
     (setq phps-mode-lex-analyzer--state 'ST_INITIAL)))
 
-(defun phps-mode-lex-analyzer--lex-string (contents &optional start end states 
state state-stack heredoc-label heredoc-label-stack tokens)
+(defun phps-mode-lex-analyzer--lex-string (contents &optional start end states 
state state-stack heredoc-label heredoc-label-stack nest-location-stack tokens)
   "Run lexer on CONTENTS."
   ;; Create a separate buffer, run lexer inside of it, catch errors and return 
them
   ;; to enable nice presentation
@@ -3018,23 +3081,34 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
         (insert contents)
 
         (if tokens
-            (setq phps-mode-lexer--tokens (nreverse tokens))
-          (setq phps-mode-lexer--tokens nil))
+            (setq
+             phps-mode-lexer--generated-tokens
+             (nreverse tokens))
+          (setq
+           phps-mode-lexer--generated-tokens
+           nil))
         (if state
-            (setq phps-mode-lexer--state state)
-          (setq phps-mode-lexer--state 'ST_INITIAL))
-        (if states
-            (setq phps-mode-lexer--states states)
-          (setq phps-mode-lexer--states nil))
-        (if state-stack
-            (setq phps-mode-lexer--state-stack state-stack)
-          (setq phps-mode-lexer--state-stack nil))
-        (if heredoc-label
-            (setq phps-mode-lexer--heredoc-label heredoc-label)
-          (setq phps-mode-lexer--heredoc-label nil))
-        (if heredoc-label-stack
-            (setq phps-mode-lexer--heredoc-label-stack heredoc-label-stack)
-          (setq phps-mode-lexer--heredoc-label-stack nil))
+            (setq
+             phps-mode-lexer--state state)
+          (setq
+           phps-mode-lexer--state
+           'ST_INITIAL))
+
+        (setq
+         phps-mode-lexer--states
+         states)
+        (setq
+         phps-mode-lexer--state-stack
+         state-stack)
+        (setq
+         phps-mode-lexer--heredoc-label
+         heredoc-label)
+        (setq
+         phps-mode-lexer--heredoc-label-stack
+         heredoc-label-stack)
+        (setq
+         phps-mode-lexer--nest-location-stack
+         nest-location-stack)
 
         ;; Setup lexer settings
         (when (boundp 'phps-mode-syntax-table)
@@ -3062,7 +3136,7 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
         (setq state phps-mode-lexer--state)
         (setq state-stack phps-mode-lexer--state-stack)
         (setq states phps-mode-lexer--states)
-        (setq tokens (nreverse phps-mode-lexer--tokens))
+        (setq tokens (nreverse phps-mode-lexer--generated-tokens))
         (setq heredoc-label phps-mode-lexer--heredoc-label)
         (setq heredoc-label-stack phps-mode-lexer--heredoc-label-stack)
         (kill-buffer))))
diff --git a/phps-mode-lexer.el b/phps-mode-lexer.el
index d2ba03a..47c3449 100644
--- a/phps-mode-lexer.el
+++ b/phps-mode-lexer.el
@@ -1,6 +1,6 @@
 ;;; phps-mode-lexer.el -- Lexer for PHPs -*- lexical-binding: t -*-
 
-;; Copyright (C) 2018-2020  Free Software Foundation, Inc.
+;; Copyright (C) 2018-2021  Free Software Foundation, Inc.
 
 ;; This file is not part of GNU Emacs.
 
@@ -45,67 +45,76 @@
 ;; INITIALIZE SETTINGS
 
 
-(phps-mode-parser-grammar-macro-CG 'PARSER_MODE t)
-(phps-mode-parser-grammar-macro-CG 'SHORT_TAGS t)
+(phps-mode-parser-grammar-macro-CG
+ 'parser-mode t)
+(phps-mode-parser-grammar-macro-CG
+ 'short-tags t)
 
 
 ;; SETTINGS
 
 
 ;; @see https://secure.php.net/manual/en/language.types.integer.php
-(defconst phps-mode-lexer--long-limit 2147483648
+(defconst phps-mode-lexer--long-limit
+  2147483648
   "Limit for 32-bit integer.")
 
-(defconst phps-mode-lexer--BNUM "0b[01]+"
+(defconst phps-mode-lexer--bnum
+  "0b[01]+"
   "Boolean number.")
 
-(defconst phps-mode-lexer--HNUM "0x[0-9a-fA-F]+"
+(defconst phps-mode-lexer--hnum
+  "0x[0-9a-fA-F]+"
   "Hexadecimal number.")
 
-(defconst phps-mode-lexer--LNUM "[0-9]+"
+(defconst phps-mode-lexer--lnum
+  "[0-9]+"
   "Long number.")
 
-(defconst phps-mode-lexer--DNUM "\\([0-9]*\\.[0-9]+\\)\\|\\([0-9]+\\.[0-9]*\\)"
+(defconst phps-mode-lexer--dnum
+  "\\([0-9]*\\.[0-9]+\\)\\|\\([0-9]+\\.[0-9]*\\)"
   "Double number.")
 
-(defconst phps-mode-lexer--EXPONENT_DNUM
+(defconst phps-mode-lexer--exponent-dnum
   (format "\\(\\(%s\\|%s\\)[eE][\\+-]?%s\\)"
-          phps-mode-lexer--LNUM
-          phps-mode-lexer--DNUM
-          phps-mode-lexer--LNUM)
+          phps-mode-lexer--lnum
+          phps-mode-lexer--dnum
+          phps-mode-lexer--lnum)
   "Exponent double number.")
 
-(defconst phps-mode-lexer--LABEL
+(defconst phps-mode-lexer--label
   "[A-Za-z_[:nonascii:]][0-9A-Za-z_[:nonascii:]]*"
   "Labels are used for names.")
 ;; NOTE original is [a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*
 ;; NOTE Rebuilt for comparability with emacs-lisp
 
-(defconst phps-mode-lexer--WHITESPACE "[ \n\r\t]+"
+(defconst phps-mode-lexer--whitespace
+  "[ \n\r\t]+"
   "White-space.")
 
-(defconst phps-mode-lexer--TABS_AND_SPACES "[ \t]*"
+(defconst phps-mode-lexer--tabs-and-spaces
+  "[ \t]*"
   "Tabs and white-spaces.")
 
-(defconst phps-mode-lexer--TOKENS "[][;:,.()|^&+/*=%!~$<>?@-]"
+(defconst phps-mode-lexer--tokens
+  "[][;:,.()|^&+/*=%!~$<>?@-]"
   "Tokens.")
 ;; NOTE Original is [;:,.\[\]()|^&+-/*=%!~$<>?@]
 ;; NOTE The hyphen moved last since it has special meaning and to avoid it 
being interpreted as a range.
 
-(defconst phps-mode-lexer--ANY_CHAR "[^z-a]"
+(defconst phps-mode-lexer--any-char
+  "[^z-a]"
   "Any character.  The Zend equivalent is [^] but is not possible in Emacs 
Lisp.")
 
-(defconst phps-mode-lexer--NEWLINE "[\n\r]"
+(defconst phps-mode-lexer--newline
+  "[\n\r]"
   "Newline characters.  The Zend equivalent is (\"\r\"|\"\n\"|\"\r\n\").")
 
 
 ;; VARIABLES
 
 
-(defvar-local phps-mode-lexer--EXPECTED nil
-  "Flag whether something is expected or not.")
-
-(defvar-local phps-mode-lexer--tokens nil
+(defvar-local phps-mode-lexer--generated-tokens nil
   "List of current generated tokens.")
 
 (defvar-local phps-mode-lexer--state nil
@@ -132,60 +141,135 @@
 (defvar-local phps-mode-lexer--match-data nil
   "Match data.")
 
+(defvar-local phps-mode-lexer--nest-location-stack nil
+  "Nesting stack.")
+
+(defvar-local phps-mode-lexer--restart-flag nil
+  "Flag whether to restart or not.")
 
 ;; HELPER FUNCTIONS
 
 
-(defun phps-mode-lexer--BEGIN (state)
+(defun phps-mode-lexer--parser-mode ()
+  "Return whether we have some expected value or not."
+  nil)
+
+(defun phps-mode-lexer--begin (state)
   "Begin STATE."
+  (phps-mode-debug-message
+   (message "Begin state: %s" state))
   (setq phps-mode-lexer--state state))
 
-;; _yy_push_state
-(defun phps-mode-lexer--yy_push_state (state)
-  "Add NEW-STATE to stack and then begin state."
-  (push phps-mode-lexer--state phps-mode-lexer--state-stack)
-  (phps-mode-lexer--BEGIN state))
-
-(defun phps-mode-lexer--yy_pop_state ()
+(defun phps-mode-lexer--yy-push-state (state)
+  "Add STATE to stack and then begin state."
+  (push
+   phps-mode-lexer--state
+   phps-mode-lexer--state-stack)
+  (phps-mode-debug-message
+   (message
+    "Pushed state: %s"
+    phps-mode-lexer--state))
+  (phps-mode-lexer--begin state))
+
+(defun phps-mode-lexer--yy-pop-state ()
   "Pop current state from stack."
   (let ((old-state (pop phps-mode-lexer--state-stack)))
+    (phps-mode-debug-message
+     (message
+      "Popped state: %s"
+      old-state))
+
     ;; (message "Going back to poppped state %s" old-state)
     (if old-state
-        (phps-mode-lexer--BEGIN old-state)
+        (phps-mode-lexer--begin old-state)
       (signal
        'phps-lexer-error
        (list
         (format "Trying to pop last state at %d" (point))
         (point))))))
 
-(defun phps-mode-lexer--MOVE_FORWARD (position)
+(defun phps-mode-lexer--move-forward (position)
   "Move forward to POSITION."
   (setq semantic-lex-end-point position))
 
 (defun phps-mode-lexer--yyless (points)
   "Move lexer back POINTS."
-  (setq semantic-lex-end-point (- semantic-lex-end-point points)))
+  (setq semantic-lex-end-point (- semantic-lex-end-point points))
+  (forward-char (- points)))
 
 (defun phps-mode-lexer--inline-char-handler ()
   "Mimic inline_char_handler."
   (let ((start (match-beginning 0)))
     (let ((string-start (search-forward "<?" nil t)))
       (if string-start
-          (phps-mode-lexer--RETURN_TOKEN 'T_INLINE_HTML start (- string-start 
2))
-        (phps-mode-lexer--RETURN_TOKEN 'T_INLINE_HTML start (point-max))))))
+          (phps-mode-lexer--return-token 'T_INLINE_HTML start (- string-start 
2))
+        (phps-mode-lexer--return-token 'T_INLINE_HTML start (point-max))))))
+
+(defun phps-mode-lexer--enter-nesting (&optional opening)
+  "Enter nesting of OPENING."
+  (unless opening
+    (setq
+     opening
+     (buffer-substring-no-properties
+      (match-beginning 0)
+      (match-end 0))))
+  (phps-mode-debug-message
+   (message
+    "Entered nesting '%s'"
+    opening))
+  (push
+   opening
+   phps-mode-lexer--nest-location-stack))
 
-(defun phps-mode-lexer--emit-token (token start end)
-  "Emit TOKEN with START and END."
+(defun phps-mode-lexer--handle-newline ()
+  "Handle newline."
+  ;; TODO Implement this?
+  )
 
-  ;; (when (and
-  ;;        (equal token 'T_INLINE_HTML)
-  ;;        phps-mode-inline-mmm-submode
-  ;;        (fboundp 'mmm-make-region))
-  ;;   (mmm-make-region phps-mode-inline-mmm-submode start end))
+(defun phps-mode-lexer--exit-nesting (closing)
+  "Exit nesting of CLOSING."
+  (unless phps-mode-lexer--nest-location-stack
+    (signal
+     'phps-lexer-error
+     (list
+      (format "Unmatched '%s' at point %d" closing (point))
+      (point))))
+  (let ((opening
+         (car
+          phps-mode-lexer--nest-location-stack)))
+    (when (and
+           opening
+           (or
+            (and (string= opening "{")
+                 (not (string= closing "}")))
+            (and (string= opening "[")
+                 (not (string= closing "]")))
+            (and (string= opening "(")
+                 (not (string= closing ")")))))
+      (signal
+       'phps-lexer-error
+       (list
+        (format "Bad nesting '%s' vs '%s' at %d'" opening closing (point))
+        (point))))
+    (phps-mode-debug-message
+     (message
+      "Exited nesting '%s'"
+      closing))
+    (pop phps-mode-lexer--nest-location-stack)
+    t))
 
+(defun phps-mode-lexer--emit-token (token start end)
+  "Emit TOKEN with START and END."
   (semantic-lex-push-token (semantic-lex-token token start end))
-
-  (push `(,token ,start . ,end) phps-mode-lexer--tokens)
+  (push `(,token ,start . ,end) phps-mode-lexer--generated-tokens)
+
+  (phps-mode-debug-message
+   (message
+    "Emitted token '%s' -> %s"
+    (buffer-substring-no-properties
+     start
+     end)
+    `(,token ,start . ,end)))
   
   ;; Push token start, end, lexer state and state stack to variable
   (push
@@ -195,7 +279,8 @@
     phps-mode-lexer--state
     phps-mode-lexer--state-stack
     phps-mode-lexer--heredoc-label
-    phps-mode-lexer--heredoc-label-stack)
+    phps-mode-lexer--heredoc-label-stack
+    phps-mode-lexer--nest-location-stack)
    phps-mode-lexer--states))
 
 (defun phps-mode-lexer--get-next-unescaped (character)
@@ -216,25 +301,115 @@
             (setq escaped nil)))))
     pos))
 
-;; TODO Figure out what this does
-(defun phps-mode-lexer--SKIP_TOKEN (_token _start _end)
-  "Skip TOKEN to list with START and END.")
+(defun phps-mode-lexer--skip-token (_token &optional start end)
+  "Skip TOKEN to list with START and END."
+  (unless start
+    (setq start (match-beginning 0)))
+  (unless end
+    (setq end (match-end 0)))
+  (setq semantic-lex-end-point end))
 
 (defmacro phps-mode-lexer--match-macro (conditions &rest body)
-  "Check if CONDITIONS hold"
+  "Check if CONDITIONS hold, if so execute BODY."
   `(phps-mode-lexer--re2c-rule
     ,conditions
     (lambda()
       ,@body)))
 
-(defun phps-mode-lexer--RETURN_TOKEN (token start end)
-  "Return TOKEN."
-  (phps-mode-lexer--emit-token token start end))
-
-(defun phps-mode-lexer--RETURN_OR_SKIP_TOKEN (token start end)
+(defun phps-mode-lexer--return-token (&optional token start end)
+  "Return TOKEN with START and END."
+  (unless start
+    (setq start (match-beginning 0)))
+  (unless end
+    (setq end (match-end 0)))
+  (unless token
+    (setq
+     token
+     (buffer-substring-no-properties
+      start
+      end)))
+  (phps-mode-lexer--emit-token
+   token
+   start
+   end))
+
+(defun phps-mode-lexer--check-nesting-at-end ()
+  "Check nesting at end."
+  (when phps-mode-lexer--nest-location-stack
+    (signal
+     'phps-lexer-error
+     (list
+      (format "Bad nesting end at '%d'" (point))
+      (point))))
+  t)
+
+(defun phps-mode-lexer--return-end-token ()
+  "Return end token."
+  (if (and
+       (phps-mode-lexer--check-nesting-at-end)
+       (phps-mode-lexer--parser-mode))
+      (phps-mode-lexer--return-token 'T_ERROR)
+    (phps-mode-lexer--return-token 'END)))
+
+(defun phps-mode-lexer--reset-doc-comment ()
+  "Reset doc comment."
+  (when (phps-mode-parser-grammar-macro-CG 'doc_comment)
+    (phps-mode-parser-grammar-macro-CG 'doc_comment nil)))
+
+(defun phps-mode-lexer--return-token-with-indent (&optional token start end)
+  "Return TOKEN with START and END."
+  (phps-mode-lexer--return-token
+   token
+   start
+   end))
+
+;; TODO Do something with offset?
+(defun phps-mode-lexer--return-token-with-str (token _offset &optional start 
end)
+  "Return TOKEN at OFFSET with START and END."
+  (unless start
+    (setq start (match-beginning 0)))
+  (unless end
+    (setq end (match-end 0)))
+  (phps-mode-lexer--return-token token start end))
+
+(defun phps-mode-lexer--return-whitespace ()
+  "Return whitespace."
+  (phps-mode-lexer--move-forward (match-end 0)))
+
+(defun phps-mode-lexer--return-exit-nesting-token (&optional token start end)
+  "Return TOKEN if it does not exit a nesting with optional START and END."
+  (unless start
+    (setq start (match-beginning 0)))
+  (unless end
+    (setq end (match-end 0)))
+  (unless token
+    (setq
+     token
+     (buffer-substring-no-properties
+      start
+      end)))
+  (if (and
+       (phps-mode-lexer--exit-nesting token)
+       (phps-mode-lexer--parser-mode))
+      (phps-mode-lexer--return-token 'T_ERROR)
+    (phps-mode-lexer--return-token
+     token
+     start
+     end)))
+
+(defun phps-mode-lexer--restart ()
+  "Restart."
+  (setq phps-mode-lexer--restart-flag t))
+
+(defun phps-mode-lexer--return-token-with-val (&optional token start end)
+  "Return TOKEN with START and END."
+  (phps-mode-lexer--return-token token start end))
+
+(defun phps-mode-lexer--return-or-skip-token (&optional token start end)
   "Return TOKEN with START and END but only in parse-mode."
-  (when (phps-mode-parser-grammar-macro-CG 'PARSER_MODE)
-    (phps-mode-lexer--RETURN_TOKEN token start end)))
+  (if (phps-mode-lexer--parser-mode)
+      (phps-mode-lexer--skip-token token start end)
+    (phps-mode-lexer--return-token token start end)))
 
 
 ;; LEXER FUNCTIONS BELOW
@@ -277,8 +452,24 @@
 (defun phps-mode-lexer--re2c ()
   "Elisp port of original Zend re2c lexer."
 
+  (setq phps-mode-lexer--restart-flag nil)
   (let ((old-start (point)))
-    (phps-mode-debug-message (message "Running lexer from %s" old-start))
+    (phps-mode-debug-message
+     (let ((start (point))
+           (end (+ (point) 5))
+           (lookahead))
+       (when (> end (point-max))
+         (setq end (point-max)))
+       (setq
+        lookahead
+        (buffer-substring-no-properties
+         start
+         end))
+     (message
+      "\nRunning lexer from point %s, state: %s, lookahead: '%s'.."
+      old-start
+      phps-mode-lexer--state
+      lookahead)))
     (phps-mode-lexer--reset-match-data)
     
     (let ((SHEBANG (equal phps-mode-lexer--state 'SHEBANG))
@@ -295,695 +486,723 @@
 
       (phps-mode-lexer--match-macro
        (and ST_IN_SCRIPTING (looking-at "exit"))
-       (phps-mode-lexer--RETURN_TOKEN 'T_EXIT (match-beginning 0) (match-end 
0)))
+       (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 'T_DIE (match-beginning 0) (match-end 
0)))
+       (phps-mode-lexer--return-token-with-indent 'T_DIE))
 
       (phps-mode-lexer--match-macro
        (and ST_IN_SCRIPTING (looking-at "fn"))
-       (phps-mode-lexer--RETURN_TOKEN 'T_FN (match-beginning 0) (match-end 0)))
+       (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 'T_FUNCTION (match-beginning 0) 
(match-end 0)))
+       (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 'T_CONST (match-beginning 0) (match-end 
0)))
+       (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 'T_RETURN (match-beginning 0) (match-end 
0)))
+       (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 'T_YIELD_FROM (match-beginning 0) 
(match-end 0)))
+         (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 'T_YIELD (match-beginning 0) (match-end 
0)))
+       (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 'T_TRY (match-beginning 0) (match-end 
0)))
+       (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 'T_CATCH (match-beginning 0) (match-end 
0)))
+       (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 'T_FINALLY (match-beginning 0) 
(match-end 0)))
+       (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 'T_THROW (match-beginning 0) (match-end 
0)))
+       (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 'T_IF (match-beginning 0) (match-end 0)))
+       (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 'T_ELSEIF (match-beginning 0) (match-end 
0)))
+       (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 'T_ENDIF (match-beginning 0) (match-end 
0)))
+       (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 'T_ELSE (match-beginning 0) (match-end 
0)))
+       (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 'T_WHILE (match-beginning 0) (match-end 
0)))
+       (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 'T_ENDWHILE (match-beginning 0) 
(match-end 0)))
+       (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 'T_DO (match-beginning 0) (match-end 0)))
+       (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 'T_FOR (match-beginning 0) (match-end 
0)))
+       (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 'T_ENDFOR (match-beginning 0) (match-end 
0)))
+       (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 'T_FOREACH (match-beginning 0) 
(match-end 0)))
+       (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 'T_ENDFOREACH (match-beginning 0) 
(match-end 0)))
+       (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 'T_DECLARE (match-beginning 0) 
(match-end 0)))
+       (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 'T_ENDDECLARE (match-beginning 0) 
(match-end 0)))
+       (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 'T_INSTANCEOF (match-beginning 0) 
(match-end 0)))
+       (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 'T_AS (match-beginning 0) (match-end 0)))
+       (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 'T_SWITCH (match-beginning 0) (match-end 
0)))
+       (phps-mode-lexer--return-token-with-indent 'T_SWITCH))
 
       (phps-mode-lexer--match-macro
        (and ST_IN_SCRIPTING (looking-at "endswitch"))
-       (phps-mode-lexer--RETURN_TOKEN 'T_ENDSWITCH (match-beginning 0) 
(match-end 0)))
+       (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 'T_CASE (match-beginning 0) (match-end 
0)))
+       (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 'T_DEFAULT (match-beginning 0) 
(match-end 0)))
+       (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 'T_BREAK (match-beginning 0) (match-end 
0)))
+       (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 'T_CONTINUE (match-beginning 0) 
(match-end 0)))
+       (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 'T_GOTO (match-beginning 0) (match-end 
0)))
+       (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 'T_ECHO (match-beginning 0) (match-end 
0)))
+       (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 'T_PRINT (match-beginning 0) (match-end 
0)))
+       (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 'T_CLASS (match-beginning 0) (match-end 
0)))
+       (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 'T_INTERFACE (match-beginning 0) 
(match-end 0)))
+       (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 'T_TRAIT (match-beginning 0) (match-end 
0)))
+       (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 'T_EXTENDS (match-beginning 0) 
(match-end 0)))
+       (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 'T_IMPLEMENTS (match-beginning 0) 
(match-end 0)))
+       (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 'T_OBJECT_OPERATOR (match-beginning 0) 
(match-end 0)))
+       (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))
-       (let* ((start (match-beginning 0))
-              (end (match-end 0))
-              (data (buffer-substring-no-properties start end)))
-         (if (phps-mode-parser-grammar-macro-CG 'PARSER_MODE)
-             (phps-mode-lexer--MOVE_FORWARD end)
-           (phps-mode-lexer--RETURN_TOKEN data start end))))
+            (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 (match-beginning 0) 
(match-end 0)))
+       (phps-mode-lexer--return-token 'T_OBJECT_OPERATOR))
 
       (phps-mode-lexer--match-macro
-       (and ST_LOOKING_FOR_PROPERTY (looking-at phps-mode-lexer--LABEL))
-       (let ((start (match-beginning 0))
-             (end (match-end 0)))
-         (phps-mode-lexer--yy_pop_state)
-         (phps-mode-lexer--RETURN_TOKEN 'T_STRING start end)))
+       (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--ANY_CHAR))
-       (phps-mode-lexer--yy_pop_state)
-      (phps-mode-lexer--re2c))
+       (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_IN_SCRIPTING (looking-at "::"))
-       (phps-mode-lexer--RETURN_TOKEN 'T_PAAMAYIM_NEKUDOTAYIM (match-beginning 
0) (match-end 0)))
+       (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_NS_SEPARATOR (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)
-                                      ))
+       (phps-mode-lexer--return-token 'T_COALESCE))
 
       (phps-mode-lexer--match-macro
        (and ST_IN_SCRIPTING (looking-at "new"))
-       (phps-mode-lexer--RETURN_TOKEN 'T_NEW (match-beginning 0) (match-end 
0)))
+       (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 'T_CLONE (match-beginning 0) (match-end 
0)))
+       (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 'T_VAR (match-beginning 0) (match-end 
0)))
+       (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
+              phps-mode-lexer--tabs-and-spaces
               "\\(int\\|integer\\)"
-              phps-mode-lexer--TABS_AND_SPACES
+              phps-mode-lexer--tabs-and-spaces
               ")")))
-       (phps-mode-lexer--RETURN_TOKEN 'T_INT_CAST (match-beginning 0) 
(match-end 0)))
+       (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
+              phps-mode-lexer--tabs-and-spaces
               "\\(double\\|float\\)"
-              phps-mode-lexer--TABS_AND_SPACES
+              phps-mode-lexer--tabs-and-spaces
               ")")))
-       (phps-mode-lexer--RETURN_TOKEN 'T_DOUBLE_CAST (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
+              phps-mode-lexer--tabs-and-spaces
               "\\(real\\)"
-              phps-mode-lexer--TABS_AND_SPACES
+              phps-mode-lexer--tabs-and-spaces
               ")")))
-       (when (phps-mode-parser-grammar-macro-CG 'PARSER_MODE)
+       (when (phps-mode-lexer--parser-mode)
          (signal
           'phps-lexer-error
           (list
            (format
-            "The (real) cast is deprecated, use (float) instead at %d"
+            "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 (match-beginning 0) 
(match-end 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
+              phps-mode-lexer--tabs-and-spaces
               "\\(string\\|binary\\)"
-              phps-mode-lexer--TABS_AND_SPACES
+              phps-mode-lexer--tabs-and-spaces
               ")")))
-       (phps-mode-lexer--RETURN_TOKEN 'T_STRING_CAST (match-beginning 0) 
(match-end 0)))
+       (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
+              phps-mode-lexer--tabs-and-spaces
               "array"
-              phps-mode-lexer--TABS_AND_SPACES
+              phps-mode-lexer--tabs-and-spaces
               ")")))
-       (phps-mode-lexer--RETURN_TOKEN 'T_ARRAY_CAST (match-beginning 0) 
(match-end 0)))
+       (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
+              phps-mode-lexer--tabs-and-spaces
               "object"
-              phps-mode-lexer--TABS_AND_SPACES
+              phps-mode-lexer--tabs-and-spaces
               ")")))
-       (phps-mode-lexer--RETURN_TOKEN 'T_OBJECT_CAST (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+        (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 (match-beginning 0) 
(match-end 0)))
+       (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))
 
       (phps-mode-lexer--match-macro
        (and ST_IN_SCRIPTING (looking-at "eval"))
-       (phps-mode-lexer--RETURN_TOKEN 'T_EVAL (match-beginning 0) (match-end 
0)))
+       (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 'T_INCLUDE (match-beginning 0) 
(match-end 0)))
+       (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 'T_INCLUDE_ONCE (match-beginning 0) 
(match-end 0)))
+       (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 'T_REQUIRE (match-beginning 0) 
(match-end 0)))
+       (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 'T_REQUIRE_ONCE (match-beginning 0) 
(match-end 0)))
+       (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 'T_NAMESPACE (match-beginning 0) 
(match-end 0)))
+       (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 'T_USE (match-beginning 0) (match-end 
0)))
+       (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 'T_INSTEADOF (match-beginning 0) 
(match-end 0)))
+       (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 'T_GLOBAL (match-beginning 0) (match-end 
0)))
+       (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 'T_ISSET (match-beginning 0) (match-end 
0)))
+       (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 'T_EMPTY (match-beginning 0) (match-end 
0)))
+       (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 'T_HALT_COMPILER (match-beginning 0) 
(match-end 0)))
+       (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 'T_STATIC (match-beginning 0) (match-end 
0)))
+       (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 'T_ABSTRACT (match-beginning 0) 
(match-end 0)))
+       (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 'T_FINAL (match-beginning 0) (match-end 
0)))
+       (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 'T_PRIVATE (match-beginning 0) 
(match-end 0)))
+       (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 'T_PROTECTED (match-beginning 0) 
(match-end 0)))
+       (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 'T_PUBLIC (match-beginning 0) (match-end 
0)))
+       (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 'T_UNSET (match-beginning 0) (match-end 
0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 'T_LIST (match-beginning 0) (match-end 
0)))
+       (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 'T_ARRAY (match-beginning 0) (match-end 
0)))
+       (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 'T_CALLABLE (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) (match-end 
0)))
+       (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 (match-beginning 0) (match-end 
0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 
0) (match-end 0)))
+       (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 (match-beginning 
0) (match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) (match-end 
0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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 (match-beginning 0) (match-end 0)))
+       (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 (match-beginning 0) (match-end 0)))
+       (phps-mode-lexer--return-token 'T_SR))
 
       (phps-mode-lexer--match-macro
-       (and ST_IN_SCRIPTING (looking-at phps-mode-lexer--TOKENS))
-       (let* ((start (match-beginning 0))
-              (end (match-end 0))
-              (data (buffer-substring-no-properties start end))
-              (use-brace nil))
-         ;; (message "Found token '%s'" data)
-         (if use-brace
-             (phps-mode-lexer--RETURN_TOKEN "{" start end)
-           (phps-mode-lexer--RETURN_TOKEN data start end))))
+       (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--RETURN_TOKEN "{" (match-beginning 0) (match-end 0)))
+       (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--RETURN_TOKEN 'T_DOLLAR_OPEN_CURLY_BRACES 
(match-beginning 0) (match-end 0)))
+       (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_TOKEN "}" (match-beginning 0) (match-end 
0))))
+         (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 (- (match-end 0) 1)))
-         ;; (message "Stopped here")
-         (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)))
+       (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--yy_pop_state)
-       (phps-mode-lexer--yy_push_state 'ST_IN_SCRIPTING))
+       (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))
+       (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 start end)
-           (phps-mode-lexer--RETURN_TOKEN 'T_LNUMBER start end))))
+             (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))
+       (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 start end)
-           (phps-mode-lexer--RETURN_TOKEN 'T_LNUMBER start end))))
+             (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))
+       (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 start end)
-           (phps-mode-lexer--RETURN_TOKEN 'T_LNUMBER start end))))
+             (phps-mode-lexer--return-token 'T_DNUMBER)
+           (phps-mode-lexer--return-token 'T_LNUMBER))))
 
       (phps-mode-lexer--match-macro
        (and ST_VAR_OFFSET (looking-at "\\([0]\\|[1-9][0-9]*\\)"))
-       (let ((start (match-beginning 0))
-             (end (match-end 0)))
-         (phps-mode-lexer--RETURN_TOKEN 'T_NUM_STRING start end)))
+       (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 (match-beginning 0) 
(match-end 0)))
+       (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--EXPONENT_DNUM)
-                                (looking-at phps-mode-lexer--DNUM)))
-       (let* ((start (match-beginning 0))
-              (end (match-end 0))
-              (_data (buffer-substring-no-properties start end)))
-         ;; (message "Exponent/double at: %s" _data)
-         (phps-mode-lexer--RETURN_TOKEN 'T_DNUMBER start end)))
+       (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 'T_CLASS_C (match-beginning 0) 
(match-end 0))
-       )
+       (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 'T_TRAIT_C (match-beginning 0) 
(match-end 0)))
+       (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 'T_FUNC_C (match-beginning 0) (match-end 
0)))
+       (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 'T_METHOD_C (match-beginning 0) 
(match-end 0)))
+       (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 'T_LINE (match-beginning 0) (match-end 
0)))
+       (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 'T_FILE (match-beginning 0) (match-end 
0)))
+       (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 'T_DIR (match-beginning 0) (match-end 
0)))
+       (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 'T_NS_C (match-beginning 0) (match-end 
0)))
+       (phps-mode-lexer--return-token-with-indent 'T_NS_C))
 
       (phps-mode-lexer--match-macro
-       (and SHEBANG (looking-at (concat "#!.*" phps-mode-lexer--NEWLINE)))
-       (phps-mode-lexer--BEGIN 'ST_INITIAL))
+       (and SHEBANG (looking-at (concat "#!.*" phps-mode-lexer--newline)))
+       (let ((lineno
+              (1+
+               (phps-mode-parser-grammar-macro-CG 'zend_lineno))))
+         (phps-mode-parser-grammar-macro-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--BEGIN 'ST_INITIAL))
+       (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 "<\\?="))
-       (let ((start (match-beginning 0))
-             (end (match-end 0)))
-         (phps-mode-lexer--BEGIN 'ST_IN_SCRIPTING)
-         (when (phps-mode-parser-grammar-macro-CG 'PARSER_MODE)
-           (phps-mode-lexer--RETURN_TOKEN 'T_ECHO start end))
-         (phps-mode-lexer--RETURN_TOKEN 'T_OPEN_TAG_WITH_ECHO start end)))
+       (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 
"\\)")))
-       (let ((start (match-beginning 0))
-             (end (match-end 0)))
-         (phps-mode-lexer--BEGIN 'ST_IN_SCRIPTING)
-         ;; (message "Starting scripting after <?php")
-         (when phps-mode-lexer--EXPECTED
-           (phps-mode-lexer--SKIP_TOKEN 'T_OPEN_TAG start end))
-         (phps-mode-lexer--RETURN_TOKEN 'T_OPEN_TAG start end)))
+        (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"))
@@ -994,17 +1213,14 @@
          (cond
 
           ((equal end (point-max))
-           (phps-mode-lexer--BEGIN 'ST_IN_SCRIPTING)
-           (phps-mode-lexer--RETURN_OR_SKIP_TOKEN
-            'T_OPEN_TAG
-            start
-            end))
-
-          ((phps-mode-parser-grammar-macro-CG 'SHORT_TAGS)
-           (phps-mode-lexer--yyless 3)
-           (setq end (- end 3))
-           (phps-mode-lexer--BEGIN 'ST_IN_SCRIPTING)
-           (phps-mode-lexer--RETURN_OR_SKIP_TOKEN
+           (phps-mode-lexer--begin 'ST_IN_SCRIPTING)
+           (phps-mode-lexer--return-or-skip-token 'T_OPEN_TAG))
+
+          ((phps-mode-parser-grammar-macro-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))
@@ -1014,74 +1230,153 @@
 
       (phps-mode-lexer--match-macro
        (and ST_INITIAL (looking-at "<\\?"))
-       (when (phps-mode-parser-grammar-macro-CG 'SHORT_TAGS)
-         (let ((start (match-beginning 0))
-               (end (match-end 0)))
-           (phps-mode-lexer--BEGIN 'ST_IN_SCRIPTING)
-           (when phps-mode-lexer--EXPECTED
-             (phps-mode-lexer--SKIP_TOKEN 'T_OPEN_TAG start end))
-           ;; (message "Starting scripting after <?")
-           (phps-mode-lexer--RETURN_TOKEN 'T_OPEN_TAG start end))))
+       (if (phps-mode-parser-grammar-macro-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))
-       (phps-mode-lexer--inline-char-handler))
+       (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
+              phps-mode-lexer--label
               "->"
               "[a-zA-Z_\x80-\xff]")))
-       (phps-mode-lexer--yy_push_state 'ST_LOOKING_FOR_PROPERTY)
-       (forward-char -3)
-       (phps-mode-lexer--RETURN_TOKEN 'T_VARIABLE (match-beginning 0) (- 
(match-end 0) 3)))
+       (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
-              "\\[")))
-       (phps-mode-lexer--yy_push_state 'ST_VAR_OFFSET)
-       (forward-char -1)
-       (phps-mode-lexer--RETURN_TOKEN 'T_VARIABLE (match-beginning 0) (- 
(match-end 0) 1)))
+              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_IN_SCRIPTING ST_DOUBLE_QUOTES ST_HEREDOC ST_BACKQUOTE 
ST_VAR_OFFSET)
+       (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 'T_VARIABLE (match-beginning 0) 
(match-end 0)))
+              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 "]" (match-beginning 0) (match-end 0)))
+       (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
-                                              "\\|[{}\"`]\\)")))
+       (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)))
-         (phps-mode-lexer--RETURN_TOKEN data 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'#]")))
-       (let* ((start (match-beginning 0))
-              (end (- (match-end 0) 1)))
-         (phps-mode-lexer--yy_pop_state)
-         (phps-mode-lexer--RETURN_TOKEN 'T_ENCAPSED_AND_WHITESPACE start end)))
+       ;; 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 (or ST_IN_SCRIPTING ST_VAR_OFFSET) (looking-at 
phps-mode-lexer--LABEL))
-       ;; (message "Adding T_STRING from %s to %s" (match-beginning 0) 
(match-end 0))
-       (phps-mode-lexer--RETURN_TOKEN 'T_STRING (match-beginning 0) (match-end 
0)))
+       (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 "\\(#\\|//\\)"))
@@ -1090,48 +1385,67 @@
               (_data (buffer-substring-no-properties start end))
               (line (buffer-substring-no-properties end (line-end-position))))
          (if (string-match "\\?>" line)
-             (progn
-               (phps-mode-lexer--RETURN_TOKEN 'T_COMMENT start (+ end 
(match-beginning 0))))
-           (progn
-             ;; TODO Handle expecting values here
-             ;; (message "Found comment 2 from %s to %s" start 
(line-end-position))
-             (phps-mode-lexer--RETURN_TOKEN 'T_COMMENT start 
(line-end-position))))))
+             (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
+              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))))
+              (doc-com (looking-at-p (concat "/\\*\\*" 
phps-mode-lexer--whitespace))))
          (let ((string-start (search-forward "*/" nil t)))
            (if string-start
                (if doc-com
-                   (phps-mode-lexer--RETURN_TOKEN 'T_DOC_COMMENT start 
(match-end 0))
-                 (phps-mode-lexer--RETURN_TOKEN 'T_COMMENT start (match-end 
0)))
+                   (progn
+                     (phps-mode-lexer--reset-doc-comment)
+                     (phps-mode-lexer--return-token
+                      'T_DOC_COMMENT
+                      start)
+                     (phps-mode-parser-grammar-macro-CG 'doc_comment t))
+                 (phps-mode-lexer--return-token
+                  'T_COMMENT start))
              (progn
                (signal
                 'phps-lexer-error
                 (list
                  (format
-                  "Un-terminated comment starting at %d"
+                  "Unterminated comment starting at %d"
                   start)
                  start)))))))
 
       (phps-mode-lexer--match-macro
-       (and ST_IN_SCRIPTING (looking-at (concat "\\?>" 
phps-mode-lexer--NEWLINE "?")))
+       (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-parser-grammar-macro-CG 'PARSER_MODE)
-           (phps-mode-lexer--RETURN_TOKEN ";" start end))
-         (phps-mode-lexer--RETURN_TOKEN 'T_CLOSE_TAG start 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 "'"))
@@ -1140,12 +1454,17 @@
               (_data (buffer-substring-no-properties start end))
               (un-escaped-end (phps-mode-lexer--get-next-unescaped "'")))
          (if un-escaped-end
-             (progn
-               (phps-mode-lexer--RETURN_TOKEN 'T_CONSTANT_ENCAPSED_STRING 
start un-escaped-end))
-           (progn
-             ;; Unclosed single quotes
-             (phps-mode-lexer--RETURN_TOKEN 'T_ENCAPSED_AND_WHITESPACE start 
(point-max))
-             (phps-mode-lexer--MOVE_FORWARD (point-max))))))
+             (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
@@ -1163,9 +1482,9 @@
                   (search-forward-regexp
                    (concat
                     "\\(\""
-                    "\\|\\$" phps-mode-lexer--LABEL
-                    "\\|\\${" phps-mode-lexer--LABEL
-                    "\\|{\\$" phps-mode-lexer--LABEL "\\)")
+                    "\\|\\$" phps-mode-lexer--label
+                    "\\|\\${" phps-mode-lexer--label
+                    "\\|{\\$" phps-mode-lexer--label "\\)")
                    nil t)))
 
              ;; Do we find a ending double quote or starting variable?
@@ -1199,17 +1518,13 @@
                          (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
+                           (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))
-                       (phps-mode-lexer--RETURN_TOKEN
-                        'T_ENCAPSED_AND_WHITESPACE
-                        (1+ start)
-                        string-start))))
+                       (phps-mode-lexer--begin 'ST_DOUBLE_QUOTES)
+                       (phps-mode-lexer--return-token "\"" start (1+ start)))))
                (progn
                  (setq open-quote nil)
                  (signal
@@ -1223,18 +1538,21 @@
             (looking-at
              (concat
               "<<<"
-              phps-mode-lexer--TABS_AND_SPACES
+              phps-mode-lexer--tabs-and-spaces
               "\\("
-              phps-mode-lexer--LABEL
+              phps-mode-lexer--label
               "\\|'"
-              phps-mode-lexer--LABEL
+              phps-mode-lexer--label
               "'\\|\""
-              phps-mode-lexer--LABEL
+              phps-mode-lexer--label
               "\"\\)"
-              phps-mode-lexer--NEWLINE)))
+              phps-mode-lexer--newline)))
        (let* ((start (match-beginning 0))
               (end (match-end 0))
-              (data (buffer-substring-no-properties (match-beginning 1) 
(match-end 1))))
+              (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) "'")
@@ -1242,7 +1560,7 @@
                (setq
                 phps-mode-lexer--heredoc-label
                 (substring data 1 (- (length data) 1)))
-               (phps-mode-lexer--BEGIN 'ST_NOWDOC))
+               (phps-mode-lexer--begin 'ST_NOWDOC))
            (progn
              (if (string= (substring data 0 1) "\"")
                  (setq
@@ -1251,7 +1569,7 @@
                (setq
                 phps-mode-lexer--heredoc-label
                 data))
-             (phps-mode-lexer--BEGIN 'ST_HEREDOC)))
+             (phps-mode-lexer--begin 'ST_HEREDOC)))
 
          ;; Check for ending label on the next line
          (when (string=
@@ -1261,23 +1579,31 @@
                     (length
                      phps-mode-lexer--heredoc-label)))
                 phps-mode-lexer--heredoc-label)
-           (phps-mode-lexer--BEGIN 'ST_END_HEREDOC))
+           (phps-mode-lexer--begin 'ST_END_HEREDOC))
 
          (push
-          phps-mode-lexer--heredoc-label
+          `(,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--RETURN_TOKEN 'T_START_HEREDOC start end)))
+         (phps-mode-parser-grammar-macro-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 "`" (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)))
+       (and ST_END_HEREDOC
+            (looking-at
+             (concat phps-mode-lexer--any-char)))
        (let* ((start (match-beginning 0))
               (end (+ start
                       (length
@@ -1286,44 +1612,55 @@
               (_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--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 (concat 
"{\\$")))
-       (phps-mode-lexer--yy_push_state 'ST_IN_SCRIPTING)
-       (phps-mode-lexer--RETURN_TOKEN 'T_CURLY_OPEN (match-beginning 0) (- 
(match-end 0) 1)))
+       (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)
-       ;; (message "Ended double-quote at %s" (match-beginning 0))
-       (phps-mode-lexer--RETURN_TOKEN "\"" (match-beginning 0) (match-end 0)))
+       (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 "`" (match-beginning 0) (match-end 0)))
+       (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))
+       (and ST_DOUBLE_QUOTES
+            (looking-at phps-mode-lexer--any-char))
        (let ((start (point))
-             (start-error (car (cdr (nth 2 phps-mode-lexer--tokens)))))
+             (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))
+                 (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 
'T_CONSTANT_ENCAPSED_STRING start variable-start)))
+                         (phps-mode-lexer--return-token-with-val
+                          'T_CONSTANT_ENCAPSED_STRING
+                          start
+                          variable-start)))
                    (progn
-                     (phps-mode-lexer--RETURN_TOKEN 
'T_CONSTANT_ENCAPSED_STRING start end)
+                     (phps-mode-lexer--return-token-with-val
+                      'T_CONSTANT_ENCAPSED_STRING
+                      start
+                      end)
                      ;; (message "Found end of quote at %s-%s, moving ahead 
after '%s'" start end (buffer-substring-no-properties start end))
                      )))
              (progn
@@ -1334,13 +1671,16 @@
                  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--tokens)))))
+       (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 'T_CONSTANT_ENCAPSED_STRING 
old-start start))
+                 (phps-mode-lexer--return-token-with-val
+                  'T_ENCAPSED_AND_WHITESPACE
+                  old-start
+                  start))
              (progn
                (signal
                 'phps-lexer-error
@@ -1349,27 +1689,29 @@
                  start)))))))
 
       (phps-mode-lexer--match-macro
-       (and ST_HEREDOC (looking-at phps-mode-lexer--ANY_CHAR))
+       (and ST_HEREDOC (looking-at phps-mode-lexer--any-char))
        ;; Check for $, ${ and {$ forward
-       (let ((start (car (cdr (car phps-mode-lexer--tokens)))))
+       (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
+                  phps-mode-lexer--label
                   "\\|\\${"
-                  phps-mode-lexer--LABEL
+                  phps-mode-lexer--label
                   "\\)"
-                  ) nil t)))
+                  )
+                 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)
 
                  (cond
 
@@ -1378,27 +1720,34 @@
                      "\n"
                      phps-mode-lexer--heredoc-label
                      ";?\n"
-                     ) data)
+                     )
+                    data)
                    ;; (message "Found heredoc end at %s-%s" start end)
-                   (phps-mode-lexer--RETURN_TOKEN 'T_ENCAPSED_AND_WHITESPACE 
old-start start)
-                   (phps-mode-lexer--BEGIN 'ST_END_HEREDOC))
+                   (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 'T_ENCAPSED_AND_WHITESPACE 
old-start 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" start)
-                 start)))))))
+                 (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--tokens)))))
+       (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"
@@ -1411,8 +1760,12 @@
                       (_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 'T_ENCAPSED_AND_WHITESPACE 
old-start start)
-                 (phps-mode-lexer--BEGIN 'ST_END_HEREDOC))
+                 (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
@@ -1421,17 +1774,30 @@
                  start)))))))
 
       (phps-mode-lexer--match-macro
-       (and (or ST_IN_SCRIPTING ST_VAR_OFFSET) (looking-at 
phps-mode-lexer--ANY_CHAR))
+       (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))))
 
-      (when phps-mode-lexer--match-length
-        (phps-mode-lexer--re2c-execute)))))
+      (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 "Restarting lexer"))
+              (phps-mode-lexer--re2c)))
+        (phps-mode-debug-message
+         (message "Found nothing at %d" (point)))))))
 
 
 (provide 'phps-mode-lexer)
 
-;;; phps-mode-lexer.el ends here 
+;;; phps-mode-lexer.el ends here
diff --git a/phps-mode-macros.el b/phps-mode-macros.el
index 5b7e17f..9e505e7 100644
--- a/phps-mode-macros.el
+++ b/phps-mode-macros.el
@@ -1,6 +1,6 @@
 ;;; phps-mode-macros.el --- Macros for major mode -*- lexical-binding: t -*-
 
-;; Copyright (C) 2018-2020  Free Software Foundation, Inc.
+;; Copyright (C) 2018-2021  Free Software Foundation, Inc.
 
 ;;; Commentary:
 
diff --git a/phps-mode-parser-grammar-macro.el 
b/phps-mode-parser-grammar-macro.el
index 99b0c50..526c253 100644
--- a/phps-mode-parser-grammar-macro.el
+++ b/phps-mode-parser-grammar-macro.el
@@ -1,6 +1,6 @@
 ;;; phps-mode-parser-grammar-macro.el --- Potential grammar macros for parser  
-*- lexical-binding:t -*-
 
-;; Copyright (C) 2018-2020  Free Software Foundation, Inc.
+;; Copyright (C) 2018-2021  Free Software Foundation, Inc.
 
 ;; This program is free software; you can redistribute it and/or
 ;; modify it under the terms of the GNU General Public License as
diff --git a/phps-mode-serial.el b/phps-mode-serial.el
index dccbc70..48b2027 100644
--- a/phps-mode-serial.el
+++ b/phps-mode-serial.el
@@ -1,6 +1,6 @@
 ;;; phps-mode-serial.el --- Functions for serial commands with varied 
synchronicity -*- lexical-binding: t -*-
 
-;; Copyright (C) 2018-2020  Free Software Foundation, Inc.
+;; Copyright (C) 2018-2021  Free Software Foundation, Inc.
 
 ;;; Commentary:
 
diff --git a/phps-mode-syntax-table.el b/phps-mode-syntax-table.el
index 8e55da9..ecf7e51 100644
--- a/phps-mode-syntax-table.el
+++ b/phps-mode-syntax-table.el
@@ -1,6 +1,6 @@
 ;;; phps-mode-syntax-table.el --- Syntax table for PHPs -*- lexical-binding: t 
-*-
 
-;; Copyright (C) 2017-2019  Free Software Foundation, Inc.
+;; Copyright (C) 2018-2021  Free Software Foundation, Inc.
 
 ;; This file is not part of GNU Emacs.
 
diff --git a/phps-mode-test.el b/phps-mode-test.el
index 603d6a4..7ec869b 100644
--- a/phps-mode-test.el
+++ b/phps-mode-test.el
@@ -1,6 +1,6 @@
 ;;; phps-mode-test.el --- Commons for tests -*- lexical-binding: t -*-
 
-;; Copyright (C) 2018-2019  Free Software Foundation, Inc.
+;; Copyright (C) 2018-2021  Free Software Foundation, Inc.
 
 ;; This file is not part of GNU Emacs.
 
@@ -30,19 +30,21 @@
 (defmacro phps-mode-test--incremental-vs-intial-buffer (source &optional title 
&rest change)
   "Set up test buffer with SOURCE, TITLE, apply CHANGE and compare incremental 
values with initial values."
   `(let ((test-buffer-incremental (generate-new-buffer "test-incremental"))
-         (incremental-states nil)
-         (incremental-tokens nil)
-         (incremental-imenu nil)
-         (incremental-indent nil)
-         (incremental-buffer nil)
-         (incremental-bookkeeping nil)
+         (incremental-states)
+         (incremental-tokens)
+         (incremental-imenu)
+         (incremental-indent)
+         (incremental-buffer)
+         (incremental-bookkeeping)
+         (incremental-nest-location-stack)
          (test-buffer-initial (generate-new-buffer "test-initial"))
-         (initial-states nil)
-         (initial-tokens nil)
-         (initial-imenu nil)
-         (initial-indent nil)
-         (initial-buffer nil)
-         (initial-bookkeeping nil))
+         (initial-states)
+         (initial-tokens)
+         (initial-imenu)
+         (initial-indent)
+         (initial-buffer)
+         (initial-bookkeeping)
+         (initial-nest-location-stack))
 
      ;; Setup incremental buffer
      (switch-to-buffer test-buffer-incremental)
@@ -51,6 +53,10 @@
      (phps-mode-debug-message
        (message "\nTesting incremental buffer '%s':\n'%s'\n" ,title ,source))
      (phps-mode)
+
+     (phps-mode-debug-message
+      (message "\nPerforming changes\n"))
+     
      ,@change
      (phps-mode-lex-analyzer--process-changes test-buffer-incremental)
      (setq incremental-states phps-mode-lex-analyzer--states)
@@ -59,6 +65,7 @@
      (setq incremental-indent (phps-mode-test--hash-to-list 
phps-mode-lex-analyzer--lines-indent))
      (setq incremental-buffer (buffer-substring (point-min) (point-max)))
      (setq incremental-bookkeeping (phps-mode-test--hash-to-list 
phps-mode-lex-analyzer--bookkeeping t))
+     (setq incremental-nest-location-stack 
phps-mode-lex-analyzer--nest-location-stack)
 
      ;; Setup incremental buffer
      (switch-to-buffer test-buffer-initial)
@@ -73,6 +80,7 @@
      (setq initial-indent (phps-mode-test--hash-to-list 
phps-mode-lex-analyzer--lines-indent))
      (setq initial-buffer (buffer-substring (point-min) (point-max)))
      (setq initial-bookkeeping (phps-mode-test--hash-to-list 
phps-mode-lex-analyzer--bookkeeping t))
+     (setq initial-nest-location-stack 
phps-mode-lex-analyzer--nest-location-stack)
 
      ;; Run tests
      (phps-mode-debug-message
@@ -87,6 +95,7 @@
      (should (equal initial-indent incremental-indent))
      (should (equal initial-imenu incremental-imenu))
      (should (equal initial-bookkeeping incremental-bookkeeping))
+     (should (equal initial-nest-location-stack 
incremental-nest-location-stack))
 
      (kill-buffer test-buffer-incremental)
      (kill-buffer test-buffer-initial)
diff --git a/phps-mode.el b/phps-mode.el
index 099dd9a..5339a28 100644
--- a/phps-mode.el
+++ b/phps-mode.el
@@ -1,12 +1,12 @@
 ;;; phps-mode.el --- Major mode for PHP with Semantic integration -*- 
lexical-binding: t -*-
 
-;; Copyright (C) 2018-2020  Free Software Foundation, Inc.
+;; Copyright (C) 2018-2021  Free Software Foundation, Inc.
 
 ;; Author: Christian Johansson <christian@cvj.se>
 ;; Maintainer: Christian Johansson <christian@cvj.se>
 ;; Created: 3 Mar 2018
-;; Modified: 21 Oct 2020
-;; Version: 0.3.65
+;; Modified: 28 Jan 2021
+;; Version: 0.4.0
 ;; Keywords: tools, convenience
 ;; URL: https://github.com/cjohansson/emacs-phps-mode
 
diff --git a/test/phps-mode-test-integration.el 
b/test/phps-mode-test-integration.el
index 04b8601..cf2ce03 100644
--- a/test/phps-mode-test-integration.el
+++ b/test/phps-mode-test-integration.el
@@ -1,6 +1,6 @@
 ;;; phps-mode-test-integration.el --- Tests for integration -*- 
lexical-binding: t -*-
 
-;; Copyright (C) 2017-2019  Free Software Foundation, Inc.
+;; Copyright (C) 2017-2021  Free Software Foundation, Inc.
 
 ;; This file is not part of GNU Emacs.
 
@@ -306,7 +306,7 @@
 
 (defun phps-mode-test-integration ()
   "Run test for integration."
-  (setq debug-on-error t)
+  ;; (setq debug-on-error t)
   ;; (setq phps-mode-analyzer--process-on-indent-and-imenu t)
   (phps-mode-test-integration--incremental-vs-initial-buffers)
   ;; (phps-mode-test-integration--whitespace-modifications)
diff --git a/test/phps-mode-test-lex-analyzer.el 
b/test/phps-mode-test-lex-analyzer.el
index 16b1ae0..80d4318 100644
--- a/test/phps-mode-test-lex-analyzer.el
+++ b/test/phps-mode-test-lex-analyzer.el
@@ -1,6 +1,6 @@
 ;;; phps-mode-test-lex-analyzer.el --- Tests for functions -*- 
lexical-binding: t -*-
 
-;; Copyright (C) 2018-2019  Free Software Foundation, Inc.
+;; Copyright (C) 2018-2021  Free Software Foundation, Inc.
 
 ;; This file is not part of GNU Emacs.
 
@@ -1404,18 +1404,20 @@
             (list (list " id $var2" 1) (list (list 8 13) 1) (list " function 
myFunction id $var" 1) (list (list 40 44) 1) (list " function myFunction id 
$var3" 1) (list (list 52 57) 1) (list (list 70 74) 1) (list (list 112 117) 0) 
(list (list 156 161) 1) (list " function myFunction2 id $abc" 1) (list (list 
215 219) 1) (list (list 231 235) 0) (list (list 274 278) 1) (list (list 315 
319) 0) (list (list 346 351) 1)))))
 
   (phps-mode-test--with-buffer
-   "<?php\n\n// Super-globals\n\nif ($_GET) {\n    echo 'Hit';\n}\nif ($_POST) 
{\n    echo 'Hit';\n}\nif ($_COOKIE) {\n    echo 'Hit';\n}\nif ($_SESSION) {\n  
  echo 'Hit';\n}\nif ($_REQUEST) {\n    echo 'Hit';\n}\nif ($_GLOBALS) {\n    
echo 'Hit';\n}\nif ($_SERVER) {\n    echo 'Hit';\n}\nif ($_FILES) {\n    echo 
'Hit';\n}\n"
+   "<?php\n\n// Super-globals\n\nif ($_GET) {\n    echo 'Hit';\n}\nif ($_POST) 
{\n    echo 'Hit';\n}\nif ($_COOKIE) {\n    echo 'Hit';\n}\nif ($_SESSION) {\n  
  echo 'Hit';\n}\nif ($_REQUEST) {\n    echo 'Hit';\n}\nif ($GLOBALS) {\n    
echo 'Hit';\n}\nif ($_SERVER) {\n    echo 'Hit';\n}\nif ($_FILES) {\n    echo 
'Hit';\n}\nif ($_ENV) {\n    echo 'Hit';\n}"
    "Bookkeeping of super-globals"
-   (should (equal
-            (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
-            (list (list (list 30 35) 1) (list (list 61 67) 1) (list (list 93 
101) 1) (list (list 127 136) 1) (list (list 162 171) 1) (list (list 197 206) 1) 
(list (list 232 240) 1) (list (list 266 273) 1)))))
+   (should
+    (equal
+     (phps-mode-test--hash-to-list (phps-mode-lex-analyzer--get-bookkeeping) t)
+     (list (list (list 30 35) 1) (list (list 61 67) 1) (list (list 93 101) 1) 
(list (list 127 136) 1) (list (list 162 171) 1) (list (list 197 205) 1) (list 
(list 231 239) 1) (list (list 265 272) 1) (list (list 298 303) 1)))))
 
   (phps-mode-test--with-buffer
    "<?php\n\nnamespace myNamespaceA {\n    $var = 123;\n    class myClassA {\n 
       private $var2 = 123;\n        function myFunctionA($var3) {\n            
$var4 = 123;\n            if ($var) {\n                echo 'Miss';\n           
 }\n            if ($var2) {\n                echo 'Miss';\n            }\n     
       if ($var3) {\n                echo 'Hit';\n            }\n            if 
($var4) {\n                echo 'Hit';\n            }\n        }\n\n        
function myFuncti [...]
    "Bookkeeping in maximum level with namespaces, classes and functions."
-   (should (equal
-            (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) 1)
-            (list (list " id $var" 1) (list (list 37 41) 1) (list " namespace 
myNamespaceA class myClassA id $var2" 1) (list (list 86 91) 1) (list " 
namespace myNamespaceA class myClassA function myFunctionA id $this" 1) (list " 
namespace myNamespaceA class myClassA function myFunctionA id $var3" 1) (list 
(list 128 133) 1) (list " namespace myNamespaceA class myClassA function 
myFunctionA id $var4" 1) (list (list 149 154) 1) (list (list 178 182) 0) (list 
(list 245 250) 0) (list (list 313 [...]
+   (should
+    (equal
+     (phps-mode-test--hash-to-list (phps-mode-lex-analyzer--get-bookkeeping) 1)
+     (list (list " id $var" 1) (list (list 37 41) 1) (list " namespace 
myNamespaceA class myClassA id $var2" 1) (list (list 86 91) 1) (list " 
namespace myNamespaceA class myClassA function myFunctionA id $this" 1) (list " 
namespace myNamespaceA class myClassA function myFunctionA id $var3" 1) (list 
(list 128 133) 1) (list " namespace myNamespaceA class myClassA function 
myFunctionA id $var4" 1) (list (list 149 154) 1) (list (list 178 182) 0) (list 
(list 245 250) 0) (list (list 313 318) 1 [...]
 
   (phps-mode-test--with-buffer
    "<?php\n\n// Conditional assignments\n\n$items = array(1, 2, 3);\nforeach 
($items as $item) {\n    if ($item) {\n        echo 'Hit';\n    }\n}\nforeach 
($items as $key => $value) {\n    if ($key || $value) {\n        echo 'Hit';\n  
  }\n}\nfor ($i = 0; $i < count($items); $i++) {\n    if ($i) {\n        echo 
'Hit';\n    }\n}\nif ($a = 123) {\n    if ($a) {\n        echo 'Hit';\n    
}\n}\nwhile ($b = 123) {\n    if ($a) {\n        echo 'Hit';\n    }\n}\ndo {\n  
  echo 'Hit';\n} while ( [...]
@@ -1463,7 +1465,7 @@
             (list (list " id $items" 1) (list (list 7 13) 1) (list (list 41 
47) 1) (list " id $item" 1) (list (list 52 57) 1) (list (list 69 74) 1) (list 
(list 115 121) 1) (list " id $key" 1) (list (list 125 129) 1) (list " id 
$item2" 1) (list (list 134 140) 1) (list (list 152 157) 1)))))
 
   (phps-mode-test--with-buffer
-   "<?php\n\n[$random, $bandom] = myValues();\nif ($random) {\n    echo 
'Hit';\n}\nif ($bandom) {\n    echo 'Hit';\n}\n\narray($random2, $bandom2] = 
myValues2();\nif ($random2) {\n    echo 'Hit';\n}\nif ($bandom3) {\n    echo 
'Hit';\n}\n\n    "
+   "<?php\n\n[$random, $bandom] = myValues();\nif ($random) {\n    echo 
'Hit';\n}\nif ($bandom) {\n    echo 'Hit';\n}\n\narray($random2, $bandom2) = 
myValues2();\nif ($random2) {\n    echo 'Hit';\n}\nif ($bandom3) {\n    echo 
'Hit';\n}\n\n    "
    "Bookkeeping of variable declarations in array"
    (should (equal
             (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
diff --git a/test/phps-mode-test-lexer.el b/test/phps-mode-test-lexer.el
index c4a2d35..8c6b635 100644
--- a/test/phps-mode-test-lexer.el
+++ b/test/phps-mode-test-lexer.el
@@ -1,6 +1,6 @@
 ;;; phps-mode-test-lexer.el --- Tests for lexer -*- lexical-binding: t -*-
 
-;; Copyright (C) 2018-2019  Free Software Foundation, Inc.
+;; Copyright (C) 2018-2021  Free Software Foundation, Inc.
 
 ;; This file is not part of GNU Emacs.
 
@@ -35,33 +35,42 @@
   (phps-mode-test--with-buffer
    "<?php\t$öar=1; exit $var;\t?>"
    "Simple PHP with two expression"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 11 . 12) 
(T_LNUMBER 12 . 13) (";" 13 . 14) (T_EXIT 15 . 19) (T_VARIABLE 20 . 24) (";" 24 
. 25) (";" 26 . 28) (T_CLOSE_TAG 26 . 28)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 11 . 12) (T_LNUMBER 12 . 
13) (";" 13 . 14) (T_EXIT 15 . 19) (T_VARIABLE 20 . 24) (";" 24 . 25) 
(T_CLOSE_TAG 26 . 28)))))
 
   (phps-mode-test--with-buffer
    "<?php\nexit;\n?>"
    "Minimal PHP expression"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_EXIT 7 . 11) (";" 11 . 12) (";" 13 . 
15) (T_CLOSE_TAG 13 . 15)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_EXIT 7 . 11) (";" 11 . 12) (T_CLOSE_TAG 13 . 
15)))))
 
   (phps-mode-test--with-buffer
    "<?php exit; ?>"
    "Small PHP file"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_EXIT 7 . 11) (";" 11 . 12) (";" 13 . 
15) (T_CLOSE_TAG 13 . 15)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_EXIT 7 . 11) (";" 11 . 12) (T_CLOSE_TAG 13 . 
15)))))
 
   (phps-mode-test--with-buffer
    "<html><head>blabla</head<body>\n\n \t<?php\nexit;\n?>\n\n</body></html>"
    "Mixed inline HTML and PHP"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_INLINE_HTML 1 . 35) (T_OPEN_TAG 35 . 41) (T_EXIT 41 . 
45) (";" 45 . 46) (";" 47 . 49) (T_CLOSE_TAG 47 . 49) (T_INLINE_HTML 49 . 
65)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_INLINE_HTML 1 . 35) (T_OPEN_TAG 35 . 41) (T_EXIT 41 . 45) (";" 45 . 
46) (T_CLOSE_TAG 47 . 49) (T_INLINE_HTML 49 . 65)))))
 
   (phps-mode-test--with-buffer
    "\n\n \t<html><title>echo 
\"Blaha\";</title><?php\n\n\nexit?>\n\n<html><random /></html><?php exit ?>"
    "Another mixed inline HTML and PHP"
-   (should (equal
-            phps-mode-lex-analyzer--tokens
-            '((T_INLINE_HTML 1 . 39) (T_OPEN_TAG 39 . 45) (T_EXIT 47 . 51) 
(";" 51 . 53) (T_CLOSE_TAG 51 . 53) (T_INLINE_HTML 53 . 78) (T_OPEN_TAG 78 . 
84) (T_EXIT 84 . 88) (";" 89 . 91) (T_CLOSE_TAG 89 . 91)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_INLINE_HTML 1 . 39) (T_OPEN_TAG 39 . 45) (T_EXIT 47 . 51) 
(T_CLOSE_TAG 51 . 53) (T_INLINE_HTML 53 . 78) (T_OPEN_TAG 78 . 84) (T_EXIT 84 . 
88) (T_CLOSE_TAG 89 . 91)))))
 
   (phps-mode-test--with-buffer
    "<?php\n\n$k = 'key';\n\necho \"\\$a['{$k}']\";"
@@ -69,7 +78,7 @@
    ;; (message "Tokens: %s" phps-mode-lex-analyzer--tokens)
    (should (equal
             phps-mode-lex-analyzer--tokens
-            '((T_OPEN_TAG 1 . 7) (T_VARIABLE 8 . 10) ("=" 11 . 12) 
(T_CONSTANT_ENCAPSED_STRING 13 . 18) (";" 18 . 19) (T_ECHO 21 . 25) ("\"" 26 . 
27) (T_ENCAPSED_AND_WHITESPACE 27 . 32) (T_CURLY_OPEN 32 . 33) (T_VARIABLE 33 . 
35) ("}" 35 . 36) (T_CONSTANT_ENCAPSED_STRING 36 . 38) ("\"" 38 . 39) (";" 39 . 
40)))))
+            '((T_OPEN_TAG 1 . 7) (T_VARIABLE 8 . 10) ("=" 11 . 12) 
(T_CONSTANT_ENCAPSED_STRING 13 . 18) (";" 18 . 19) (T_ECHO 21 . 25) ("\"" 26 . 
27) (T_CONSTANT_ENCAPSED_STRING 27 . 32) (T_CURLY_OPEN 32 . 33) (T_VARIABLE 33 
. 35) ("}" 35 . 36) (T_CONSTANT_ENCAPSED_STRING 36 . 38) ("\"" 38 . 39) (";" 39 
. 40)))))
 
   )
 
@@ -87,111 +96,208 @@
   (phps-mode-test--with-buffer
    "<?php if 
(empty($parameters[self::PARAMETER_CONFIGURATION_INTERNAL_FILENAME])) { 
$parameters[self::PARAMETER_CONFIGURATION_INTERNAL_FILENAME] = ''; }"
    "Complex PHP with conditional"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_IF 7 . 9) ("(" 10 . 11) (T_EMPTY 11 
. 16) ("(" 16 . 17) (T_VARIABLE 17 . 28) ("[" 28 . 29) (T_STRING 29 . 33) 
(T_PAAMAYIM_NEKUDOTAYIM 33 . 35) (T_STRING 35 . 76) ("]" 76 . 77) (")" 77 . 78) 
(")" 78 . 79) ("{" 80 . 81) (T_VARIABLE 82 . 93) ("[" 93 . 94) (T_STRING 94 . 
98) (T_PAAMAYIM_NEKUDOTAYIM 98 . 100) (T_STRING 100 . 141) ("]" 141 . 142) ("=" 
143 . 144) (T_CONSTANT_ENCAPSED_STRING 145 . 147) (";" 147 . 148) ("}" 149 . 
150)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_IF 7 . 9) ("(" 10 . 11) (T_EMPTY 11 . 16) ("(" 16 
. 17) (T_VARIABLE 17 . 28) ("[" 28 . 29) (T_STRING 29 . 33) 
(T_PAAMAYIM_NEKUDOTAYIM 33 . 35) (T_STRING 35 . 76) ("]" 76 . 77) (")" 77 . 78) 
(")" 78 . 79) ("{" 80 . 81) (T_VARIABLE 82 . 93) ("[" 93 . 94) (T_STRING 94 . 
98) (T_PAAMAYIM_NEKUDOTAYIM 98 . 100) (T_STRING 100 . 141) ("]" 141 . 142) ("=" 
143 . 144) (T_CONSTANT_ENCAPSED_STRING 145 . 147) (";" 147 . 148) ("}" 149 . 
150)))))
 
   (phps-mode-test--with-buffer
    "<?php echo $var = array(\"\");"
    "Simple PHP with empty array assignment"
-   (should (equal phps-mode-lex-analyzer--tokens
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
                   '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_VARIABLE 12 . 16) 
("=" 17 . 18) (T_ARRAY 19 . 24) ("(" 24 . 25) (T_CONSTANT_ENCAPSED_STRING 25 . 
27) (")" 27 . 28) (";" 28 . 29)))))
 
   (phps-mode-test--with-buffer
    "<?php echo $var = array('abc' => '123');"
    "Simple PHP with associative array assignment"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_VARIABLE 12 . 16) 
("=" 17 . 18) (T_ARRAY 19 . 24) ("(" 24 . 25) (T_CONSTANT_ENCAPSED_STRING 25 . 
30) (T_DOUBLE_ARROW 31 . 33) (T_CONSTANT_ENCAPSED_STRING 34 . 39) (")" 39 . 40) 
(";" 40 . 41)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_VARIABLE 12 . 16) ("=" 17 . 18) 
(T_ARRAY 19 . 24) ("(" 24 . 25) (T_CONSTANT_ENCAPSED_STRING 25 . 30) 
(T_DOUBLE_ARROW 31 . 33) (T_CONSTANT_ENCAPSED_STRING 34 . 39) (")" 39 . 40) 
(";" 40 . 41)))))
 
   (phps-mode-test--with-buffer
    "<?php $var = []; "
    "PHP with short-handed array declaration assignment"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 12 . 13) ("[" 
14 . 15) ("]" 15 . 16) (";" 16 . 17)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 12 . 13) ("[" 14 . 15) ("]" 
15 . 16) (";" 16 . 17)))))
 
   (phps-mode-test--with-buffer
    "<?php $var = ''; $var = 'abc'; "
    "PHP with string assignments"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 12 . 13) 
(T_CONSTANT_ENCAPSED_STRING 14 . 16) (";" 16 . 17) (T_VARIABLE 18 . 22) ("=" 23 
. 24) (T_CONSTANT_ENCAPSED_STRING 25 . 30) (";" 30 . 31)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 12 . 13) 
(T_CONSTANT_ENCAPSED_STRING 14 . 16) (";" 16 . 17) (T_VARIABLE 18 . 22) ("=" 23 
. 24) (T_CONSTANT_ENCAPSED_STRING 25 . 30) (";" 30 . 31)))))
 
   (phps-mode-test--with-buffer
    "<?php\nswitch (myRandomCondition()) {\ncase 'Something here':\necho 
'Something else here';\n}\n"
    "Switch case PHP"
    ;; (message "Tokens: %s" phps-mode-lex-analyzer--tokens)
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_SWITCH 7 . 13) ("(" 14 . 15) 
(T_STRING 15 . 32) ("(" 32 . 33) (")" 33 . 34) (")" 34 . 35) ("{" 36 . 37) 
(T_CASE 38 . 42) (T_CONSTANT_ENCAPSED_STRING 43 . 59) (":" 59 . 60) (T_ECHO 61 
. 65) (T_CONSTANT_ENCAPSED_STRING 66 . 87) (";" 87 . 88) ("}" 89 . 90)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_SWITCH 7 . 13) ("(" 14 . 15) (T_STRING 15 . 32) 
("(" 32 . 33) (")" 33 . 34) (")" 34 . 35) ("{" 36 . 37) (T_CASE 38 . 42) 
(T_CONSTANT_ENCAPSED_STRING 43 . 59) (":" 59 . 60) (T_ECHO 61 . 65) 
(T_CONSTANT_ENCAPSED_STRING 66 . 87) (";" 87 . 88) ("}" 89 . 90)))))
 
   (phps-mode-test--with-buffer
    "<?php $var = \"\"; $var = \"abc\"; $var = \"abc\\def\\ghj\";"
    "PHP with three string assignments"
    ;; (message "Tokens: %s" phps-mode-lex-analyzer--tokens)
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 12 . 13) 
(T_CONSTANT_ENCAPSED_STRING 14 . 16) (";" 16 . 17) (T_VARIABLE 18 . 22) ("=" 23 
. 24) (T_CONSTANT_ENCAPSED_STRING 25 . 30) (";" 30 . 31) (T_VARIABLE 32 . 36) 
("=" 37 . 38) (T_CONSTANT_ENCAPSED_STRING 39 . 52) (";" 52 . 53)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 12 . 13) 
(T_CONSTANT_ENCAPSED_STRING 14 . 16) (";" 16 . 17) (T_VARIABLE 18 . 22) ("=" 23 
. 24) (T_CONSTANT_ENCAPSED_STRING 25 . 30) (";" 30 . 31) (T_VARIABLE 32 . 36) 
("=" 37 . 38) (T_CONSTANT_ENCAPSED_STRING 39 . 52) (";" 52 . 53)))))
 
   (phps-mode-test--with-buffer
    "<?php echo isset($backtrace[1]['file']) ? 'yes' : 'no'; "
    "PHP with short-handed conditional echo"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_ISSET 12 . 17) ("(" 
17 . 18) (T_VARIABLE 18 . 28) ("[" 28 . 29) (T_LNUMBER 29 . 30) ("]" 30 . 31) 
("[" 31 . 32) (T_CONSTANT_ENCAPSED_STRING 32 . 38) ("]" 38 . 39) (")" 39 . 40) 
("?" 41 . 42) (T_CONSTANT_ENCAPSED_STRING 43 . 48) (":" 49 . 50) 
(T_CONSTANT_ENCAPSED_STRING 51 . 55) (";" 55 . 56)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_ISSET 12 . 17) ("(" 17 . 18) 
(T_VARIABLE 18 . 28) ("[" 28 . 29) (T_LNUMBER 29 . 30) ("]" 30 . 31) ("[" 31 . 
32) (T_CONSTANT_ENCAPSED_STRING 32 . 38) ("]" 38 . 39) (")" 39 . 40) ("?" 41 . 
42) (T_CONSTANT_ENCAPSED_STRING 43 . 48) (":" 49 . 50) 
(T_CONSTANT_ENCAPSED_STRING 51 . 55) (";" 55 . 56)))))
 
   (phps-mode-test--with-buffer
    "<?php myFunction(); "
    "A single function call"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_STRING 7 . 17) ("(" 17 . 18) (")" 18 
. 19) (";" 19 . 20)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_STRING 7 . 17) ("(" 17 . 18) (")" 18 . 19) (";" 
19 . 20)))))
 
   (phps-mode-test--with-buffer
    "<?php // echo 'random';?><!--</div>-->"
    "Commented out PHP expression and inline-html"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_COMMENT 7 . 24) (";" 24 . 26) 
(T_CLOSE_TAG 24 . 26) (T_INLINE_HTML 26 . 39)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_COMMENT 7 . 24) (T_CLOSE_TAG 24 . 26) 
(T_INLINE_HTML 26 . 39)))))
 
   (phps-mode-test--with-buffer
    "<?php //echo $contact_position;?><!--</div>-->"
    "Commented out PHP expression and inline-html 2"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_COMMENT 7 . 32) (";" 32 . 34) 
(T_CLOSE_TAG 32 . 34) (T_INLINE_HTML 34 . 47)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_COMMENT 7 . 32) (T_CLOSE_TAG 32 . 34) 
(T_INLINE_HTML 34 . 47)))))
 
   (phps-mode-test--with-buffer
    "<?php echo isset($backtrace[1]['file']) ? 'yes' : 'no';\n//a random 
comment\n// another random comment\n/**\n * More comments\n* More\n **/\necho 
$backtrace; ?>"
    "Conditional echo, comment and doc-comment block"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_ISSET 12 . 17) ("(" 
17 . 18) (T_VARIABLE 18 . 28) ("[" 28 . 29) (T_LNUMBER 29 . 30) ("]" 30 . 31) 
("[" 31 . 32) (T_CONSTANT_ENCAPSED_STRING 32 . 38) ("]" 38 . 39) (")" 39 . 40) 
("?" 41 . 42) (T_CONSTANT_ENCAPSED_STRING 43 . 48) (":" 49 . 50) 
(T_CONSTANT_ENCAPSED_STRING 51 . 55) (";" 55 . 56) (T_COMMENT 57 . 75) 
(T_COMMENT 76 . 101) (T_DOC_COMMENT 102 . 134) (T_ECHO 135 . 139) (T_VARIABLE 
140 . 150) (";" 150 . 151) (";" 152 . 154)  [...]
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_ISSET 12 . 17) ("(" 17 . 18) 
(T_VARIABLE 18 . 28) ("[" 28 . 29) (T_LNUMBER 29 . 30) ("]" 30 . 31) ("[" 31 . 
32) (T_CONSTANT_ENCAPSED_STRING 32 . 38) ("]" 38 . 39) (")" 39 . 40) ("?" 41 . 
42) (T_CONSTANT_ENCAPSED_STRING 43 . 48) (":" 49 . 50) 
(T_CONSTANT_ENCAPSED_STRING 51 . 55) (";" 55 . 56) (T_COMMENT 57 . 75) 
(T_COMMENT 76 . 101) (T_DOC_COMMENT 102 . 134) (T_ECHO 135 . 139) (T_VARIABLE 
140 . 150) (";" 150 . 151) (T_CLOSE_TAG 152 . 154)))))
 
   (phps-mode-test--with-buffer
    "<?php forgerarray($arg1, $arg2)"
    "A function call containing keywords in its name"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_STRING 7 . 18) ("(" 18 . 19) 
(T_VARIABLE 19 . 24) ("," 24 . 25) (T_VARIABLE 26 . 31) (")" 31 . 32)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_STRING 7 . 18) ("(" 18 . 19) (T_VARIABLE 19 . 24) 
("," 24 . 25) (T_VARIABLE 26 . 31) (")" 31 . 32)))))
 
   (phps-mode-test--with-buffer
    "<?php\n$username = $_GET['user'] ?? 
'nobody';\n$this->request->data['comments']['user_id'] ??= 'value';\n"
    "Coalescing comparison operator and coalescing assignment operator"
    ;; (message "Tokens: %s" phps-mode-lex-analyzer--tokens)
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 16) ("=" 17 . 18) 
(T_VARIABLE 19 . 24) ("[" 24 . 25) (T_CONSTANT_ENCAPSED_STRING 25 . 31) ("]" 31 
. 32) (T_COALESCE 33 . 35) (T_CONSTANT_ENCAPSED_STRING 36 . 44) (";" 44 . 45) 
(T_VARIABLE 46 . 51) (T_OBJECT_OPERATOR 51 . 53) (T_STRING 53 . 60) 
(T_OBJECT_OPERATOR 60 . 62) (T_STRING 62 . 66) ("[" 66 . 67) 
(T_CONSTANT_ENCAPSED_STRING 67 . 77) ("]" 77 . 78) ("[" 78 . 79) 
(T_CONSTANT_ENCAPSED_STRING 79 . 88) ("]" 88 . 89) (T_COALESCE_EQUA [...]
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 16) ("=" 17 . 18) (T_VARIABLE 19 . 
24) ("[" 24 . 25) (T_CONSTANT_ENCAPSED_STRING 25 . 31) ("]" 31 . 32) 
(T_COALESCE 33 . 35) (T_CONSTANT_ENCAPSED_STRING 36 . 44) (";" 44 . 45) 
(T_VARIABLE 46 . 51) (T_OBJECT_OPERATOR 51 . 53) (T_STRING 53 . 60) 
(T_OBJECT_OPERATOR 60 . 62) (T_STRING 62 . 66) ("[" 66 . 67) 
(T_CONSTANT_ENCAPSED_STRING 67 . 77) ("]" 77 . 78) ("[" 78 . 79) 
(T_CONSTANT_ENCAPSED_STRING 79 . 88) ("]" 88 . 89) (T_COALESCE_EQUAL 90 . 93) 
(T [...]
 
   (phps-mode-test--with-buffer
    "<?php\necho $array['abc'];\necho \"My $array[12] random statement\";\n"
    "Long inside array offset"
    ;; (message "Tokens: %s" phps-mode-lex-analyzer--tokens)
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_VARIABLE 12 . 18) 
("[" 18 . 19) (T_CONSTANT_ENCAPSED_STRING 19 . 24) ("]" 24 . 25) (";" 25 . 26) 
(T_ECHO 27 . 31) ("\"" 32 . 33) (T_ENCAPSED_AND_WHITESPACE 33 . 36) (T_VARIABLE 
36 . 42) ("[" 42 . 43) (T_NUM_STRING 43 . 45) ("]" 45 . 46) 
(T_CONSTANT_ENCAPSED_STRING 46 . 63) ("\"" 63 . 64) (";" 64 . 65)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_VARIABLE 12 . 18) ("[" 18 . 19) 
(T_CONSTANT_ENCAPSED_STRING 19 . 24) ("]" 24 . 25) (";" 25 . 26) (T_ECHO 27 . 
31) ("\"" 32 . 33) (T_CONSTANT_ENCAPSED_STRING 33 . 36) (T_VARIABLE 36 . 42) 
("[" 42 . 43) (T_NUM_STRING 43 . 45) ("]" 45 . 46) (T_CONSTANT_ENCAPSED_STRING 
46 . 63) ("\"" 63 . 64) (";" 64 . 65)))))
 
   (phps-mode-test--with-buffer
    "<?php\n/*my comment */\n/** my doc comment */"
    "Comment vs doc-comment"
    ;; (message "Tokens: %s" phps-mode-lex-analyzer--tokens)
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_COMMENT 7 . 22) (T_DOC_COMMENT 23 . 
44)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_COMMENT 7 . 22) (T_DOC_COMMENT 23 . 44)))))
+
+  ;; https://www.php.net/releases/8.0/en.php
+  (phps-mode-test--with-buffer
+   "<?php\nhtmlspecialchars($string, double_encode: false);"
+   "PHP 8.0 Named arguments"
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_STRING 7 . 23) ("(" 23 . 24) (T_VARIABLE 24 . 31) 
("," 31 . 32) (T_STRING 33 . 46) (":" 46 . 47) (T_STRING 48 . 53) (")" 53 . 54) 
(";" 54 . 55)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\nclass PostsController\n{\n    #[Route(\"/api/posts/{id}\", methods: 
[\"GET\"])]\n    public function get($id) { /* ... */ }\n}"
+   "PHP 8.0 Attributes"
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_CLASS 7 . 12) (T_STRING 13 . 28) ("{" 29 . 30) 
(T_ATTRIBUTE 35 . 37) (T_STRING 37 . 42) ("(" 42 . 43) 
(T_CONSTANT_ENCAPSED_STRING 43 . 60) ("," 60 . 61) (T_STRING 62 . 69) (":" 69 . 
70) ("[" 71 . 72) (T_CONSTANT_ENCAPSED_STRING 72 . 77) ("]" 77 . 78) (")" 78 . 
79) ("]" 79 . 80) (T_PUBLIC 85 . 91) (T_FUNCTION 92 . 100) (T_STRING 101 . 104) 
("(" 104 . 105) (T_VARIABLE 105 . 108) (")" 108 . 109) ("{" 110 . 111) 
(T_COMMENT 112 . 121) ("}" 122 . 123) ("}" 124 . 125)))))
+  
+  (phps-mode-test--with-buffer
+   "<?php\nclass Point {\n  public function __construct(\n    public float $x 
= 0.0,\n    public float $y = 0.0,\n    public float $z = 0.0,\n  ) {}\n}"
+   "PHP 8.0 Constructor property promotion"
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_CLASS 7 . 12) (T_STRING 13 . 18) ("{" 19 . 20) 
(T_PUBLIC 23 . 29) (T_FUNCTION 30 . 38) (T_STRING 39 . 50) ("(" 50 . 51) 
(T_PUBLIC 56 . 62) (T_STRING 63 . 68) (T_VARIABLE 69 . 71) ("=" 72 . 73) 
(T_DNUMBER 74 . 77) ("," 77 . 78) (T_PUBLIC 83 . 89) (T_STRING 90 . 95) 
(T_VARIABLE 96 . 98) ("=" 99 . 100) (T_DNUMBER 101 . 104) ("," 104 . 105) 
(T_PUBLIC 110 . 116) (T_STRING 117 . 122) (T_VARIABLE 123 . 125) ("=" 126 . 
127) (T_DNUMBER 128 . 131) ("," 131 . 132) (")"  [...]
+
+  (phps-mode-test--with-buffer
+   "<?php\nclass Number {\n  public function __construct(\n    private 
int|float $number\n  ) {}\n}\n\nnew Number('NaN'); // TypeError"
+   "PHP 8.0 Union types"
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_CLASS 7 . 12) (T_STRING 13 . 19) ("{" 20 . 21) 
(T_PUBLIC 24 . 30) (T_FUNCTION 31 . 39) (T_STRING 40 . 51) ("(" 51 . 52) 
(T_PRIVATE 57 . 64) (T_STRING 65 . 68) ("|" 68 . 69) (T_STRING 69 . 74) 
(T_VARIABLE 75 . 82) (")" 85 . 86) ("{" 87 . 88) ("}" 88 . 89) ("}" 90 . 91) 
(T_NEW 93 . 96) (T_STRING 97 . 103) ("(" 103 . 104) (T_CONSTANT_ENCAPSED_STRING 
104 . 109) (")" 109 . 110) (";" 110 . 111) (T_COMMENT 112 . 124)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\necho match (8.0) {\n  '8.0' => \"Oh no!\",\n  8.0 => \"This is what 
I expected\",\n};\n//> This is what I expected"
+   "PHP 8.0 Match expression"
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_STRING 12 . 17) ("(" 18 . 19) 
(T_DNUMBER 19 . 22) (")" 22 . 23) ("{" 24 . 25) (T_CONSTANT_ENCAPSED_STRING 28 
. 33) (T_DOUBLE_ARROW 34 . 36) (T_CONSTANT_ENCAPSED_STRING 37 . 45) ("," 45 . 
46) (T_DNUMBER 49 . 52) (T_DOUBLE_ARROW 53 . 55) (T_CONSTANT_ENCAPSED_STRING 56 
. 81) ("," 81 . 82) ("}" 83 . 84) (";" 84 . 85) (T_COMMENT 86 . 113)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\n\n$country = $session?->user?->getAddress()?->country;\n"
+   "PHP 8.0 Nullsafe operator"
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 8 . 16) ("=" 17 . 18) (T_VARIABLE 19 . 
27) (T_NULLSAFE_OBJECT_OPERATOR 27 . 30) (T_STRING 30 . 34) 
(T_NULLSAFE_OBJECT_OPERATOR 34 . 37) (T_STRING 37 . 47) ("(" 47 . 48) (")" 48 . 
49) (T_NULLSAFE_OBJECT_OPERATOR 49 . 52) (T_STRING 52 . 59) (";" 59 . 60)))))
 
-  ;; (phps-mode-test--with-buffer
-  ;;  "<?php ??= $var EXIT die function return yield from yield try catch 
finally throw if elseif endif else while endwhile do for endfor foreach 
endforeach declare enddeclare instanceof as switch endswitch case default break 
continue goto echo print class interface trait extends implements :: \\ ... ?? 
new clone var (int) (integer) (real) (double) (float) (string) (binary) (array) 
(object) (boolean) (bool) (unset) eval include include_once require 
require_once namespace use insteadof gl [...]
-  ;;  "All PHP tokens after each other"
-  ;;  (message "Tokens: %s" phps-mode-lex-analyzer--tokens)
-  ;;  (should (equal phps-mode-lex-analyzer--tokens
-  ;;                 '((T_OPEN_TAG 1 . 7) (T_COALESCE_EQUAL 7 . 10) 
(T_VARIABLE 11 . 15) (T_EXIT 16 . 20) (T_DIE 21 . 24) (T_FUNCTION 25 . 33) 
(T_RETURN 34 . 40) (T_YIELD_FROM 41 . 52) (T_YIELD 52 . 57) (T_TRY 58 . 61) 
(T_CATCH 62 . 67) (T_FINALLY 68 . 75) (T_THROW 76 . 81) (T_IF 82 . 84) 
(T_ELSEIF 85 . 91) (T_ENDIF 92 . 97) (T_ELSE 98 . 102) (T_WHILE 103 . 108) 
(T_ENDWHILE 109 . 117) (T_DO 118 . 120) (T_FOR 121 . 124) (T_ENDFOR 125 . 131) 
(T_FOREACH 132 . 139) (T_ENDFOREACH 140 . 150) ( [...]
+  (phps-mode-test--with-buffer
+   "<?php\n\n0 == 'foobar' // false\n"
+   "PHP 8.0 Saner string to number comparisons"
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_LNUMBER 8 . 9) (T_IS_EQUAL 10 . 12) 
(T_CONSTANT_ENCAPSED_STRING 13 . 21) (T_COMMENT 22 . 30)))))
 
+  (phps-mode-test--with-buffer
+   "<?php\n\nstrlen([]); // TypeError: strlen(): Argument #1 ($str) must be of 
type string, array given\n\narray_chunk([], -1); // ValueError: array_chunk(): 
Argument #2 ($length) must be greater than 0\n"
+   "PHP 8.0 Consistent type errors for internal functions"
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_STRING 8 . 14) ("(" 14 . 15) ("[" 15 . 16) ("]" 
16 . 17) (")" 17 . 18) (";" 18 . 19) (T_COMMENT 20 . 98) (T_STRING 100 . 111) 
("(" 111 . 112) ("[" 112 . 113) ("]" 113 . 114) ("," 114 . 115) ("-" 116 . 117) 
(T_LNUMBER 117 . 118) (")" 118 . 119) (";" 119 . 120) (T_COMMENT 121 . 195)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\nFoo;\n// Before: T_STRING\n// After:  T_STRING\n// Rule:   
{LABEL}\n \nFoo\\Bar;\n// Before: T_STRING T_NS_SEPARATOR T_STRING\n// After:  
T_NAME_QUALIFIED\n// Rule:   {LABEL}(\"\\\"{LABEL})+\n \n\\Foo;\n// Before: 
T_NS_SEPARATOR T_STRING\n// After:  T_NAME_FULLY_QUALIFIED\n// Rule:   
(\"\\\"{LABEL})+\n \nnamespace\\Foo;\n// Before: T_NAMESPACE T_NS_SEPARATOR 
T_STRING\n// After:  T_NAME_RELATIVE\n// Rule:   \"namespace\"(\"\\\"{LABEL})+"
+   "PHP 8.0 Treat namespaced names as single token"
+   (should
+    (equal
+     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)))))
 
   )
 
@@ -201,171 +307,224 @@
   (phps-mode-test--with-buffer
    "<?php $var->property;"
    "Object property"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) (T_OBJECT_OPERATOR 
11 . 13) (T_STRING 13 . 21) (";" 21 . 22)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) (T_OBJECT_OPERATOR 11 . 13) 
(T_STRING 13 . 21) (";" 21 . 22)))))
 
   (phps-mode-test--with-buffer
    "<?php echo \"My $variable is here\"; echo \"you know\";"
    "Double quoted strings with variables"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) ("\"" 12 . 13) 
(T_ENCAPSED_AND_WHITESPACE 13 . 16) (T_VARIABLE 16 . 25) 
(T_CONSTANT_ENCAPSED_STRING 25 . 33) ("\"" 33 . 34) (";" 34 . 35) (T_ECHO 36 . 
40) (T_CONSTANT_ENCAPSED_STRING 41 . 51) (";" 51 . 52)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) ("\"" 12 . 13) 
(T_CONSTANT_ENCAPSED_STRING 13 . 16) (T_VARIABLE 16 . 25) 
(T_CONSTANT_ENCAPSED_STRING 25 . 33) ("\"" 33 . 34) (";" 34 . 35) (T_ECHO 36 . 
40) (T_CONSTANT_ENCAPSED_STRING 41 . 51) (";" 51 . 52)))))
 
   (phps-mode-test--with-buffer
    "<?php echo \"My ${variable} is here 1\";"
    "Double quoted string with variable"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) ("\"" 12 . 13) 
(T_ENCAPSED_AND_WHITESPACE 13 . 16) (T_DOLLAR_OPEN_CURLY_BRACES 16 . 18) 
(T_STRING_VARNAME 18 . 26) ("}" 26 . 27) (T_CONSTANT_ENCAPSED_STRING 27 . 37) 
("\"" 37 . 38) (";" 38 . 39)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) ("\"" 12 . 13) 
(T_CONSTANT_ENCAPSED_STRING 13 . 16) (T_DOLLAR_OPEN_CURLY_BRACES 16 . 18) 
(T_STRING_VARNAME 18 . 26) ("}" 26 . 27) (T_CONSTANT_ENCAPSED_STRING 27 . 37) 
("\"" 37 . 38) (";" 38 . 39)))))
 
   (phps-mode-test--with-buffer
    "<?php echo \"Mine {$first_variable} is here and my $second is there.\";"
    "Another double quoted string with variable"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) ("\"" 12 . 13) 
(T_ENCAPSED_AND_WHITESPACE 13 . 18) (T_CURLY_OPEN 18 . 19) (T_VARIABLE 19 . 34) 
("}" 34 . 35) (T_CONSTANT_ENCAPSED_STRING 35 . 51) (T_VARIABLE 51 . 58) 
(T_CONSTANT_ENCAPSED_STRING 58 . 68) ("\"" 68 . 69) (";" 69 . 70)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) ("\"" 12 . 13) 
(T_CONSTANT_ENCAPSED_STRING 13 . 18) (T_CURLY_OPEN 18 . 19) (T_VARIABLE 19 . 
34) ("}" 34 . 35) (T_CONSTANT_ENCAPSED_STRING 35 . 51) (T_VARIABLE 51 . 58) 
(T_CONSTANT_ENCAPSED_STRING 58 . 68) ("\"" 68 . 69) (";" 69 . 70)))))
 
   (phps-mode-test--with-buffer
    "<?php echo \" Hello $variable[0], how are you?\";"
    nil
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) ("\"" 12 . 13) 
(T_ENCAPSED_AND_WHITESPACE 13 . 20) (T_VARIABLE 20 . 29) ("[" 29 . 30) 
(T_NUM_STRING 30 . 31) ("]" 31 . 32) (T_CONSTANT_ENCAPSED_STRING 32 . 46) ("\"" 
46 . 47) (";" 47 . 48)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) ("\"" 12 . 13) 
(T_CONSTANT_ENCAPSED_STRING 13 . 20) (T_VARIABLE 20 . 29) ("[" 29 . 30) 
(T_NUM_STRING 30 . 31) ("]" 31 . 32) (T_CONSTANT_ENCAPSED_STRING 32 . 46) ("\"" 
46 . 47) (";" 47 . 48)))))
 
   ;; HEREDOC
 
   (phps-mode-test--with-buffer
    "<?php\nclass foo {\n    public $bar = <<<EOT\nbar\n    EOT;\n}\n// 
Identifier must not be indented\n?>\n"
    "Example #1 Invalid example (HEREDOC)"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  nil)))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     nil)))
 
   (phps-mode-test--with-buffer
    "<?php\nclass foo {\n    public $bar = <<<EOT\nbar\nEOT;\n}\n?>\n"
    "Example #2 Valid example (HEREDOC)"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_CLASS 7 . 12) (T_STRING 13 . 16) 
("{" 17 . 18) (T_PUBLIC 23 . 29) (T_VARIABLE 30 . 34) ("=" 35 . 36) 
(T_START_HEREDOC 37 . 44) (T_ENCAPSED_AND_WHITESPACE 44 . 47) (T_END_HEREDOC 47 
. 51) (";" 51 . 52) ("}" 53 . 54) (";" 55 . 57) (T_CLOSE_TAG 55 . 57) 
(T_INLINE_HTML 57 . 58)))))
+   ;; (message "tokens: %s" phps-mode-lex-analyzer--tokens)
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_CLASS 7 . 12) (T_STRING 13 . 16) ("{" 17 . 18) 
(T_PUBLIC 23 . 29) (T_VARIABLE 30 . 34) ("=" 35 . 36) (T_START_HEREDOC 37 . 44) 
(T_ENCAPSED_AND_WHITESPACE 44 . 47) (T_END_HEREDOC 47 . 51) (";" 51 . 52) ("}" 
53 . 54) (T_CLOSE_TAG 55 . 57) (T_INLINE_HTML 57 . 58)))))
 
   (phps-mode-test--with-buffer
    "<?php\n$str = <<<EOD\nExample of string\nspanning multiple lines\nusing 
heredoc syntax.\nEOD;\n\n/* More complex example, with variables. */\nclass 
foo\n{\n    var $foo;\n    var $bar;\n\n    function __construct()\n    {\n     
   $this->foo = 'Foo';\n        $this->bar = array('Bar1', 'Bar2', 'Bar3');\n   
 }\n}\n\n$foo = new foo();\n$name = 'MyName';\n\necho <<<EOT\nMy name is 
\"$name\". I am printing some $foo->foo.\nNow, I am printing some 
{$foo->bar[1]}.\nThis should print a capi [...]
    "Example #3 Heredoc string quoting example"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 12 . 13) 
(T_START_HEREDOC 14 . 21) (T_ENCAPSED_AND_WHITESPACE 21 . 84) (T_END_HEREDOC 84 
. 88) (";" 88 . 89) (T_COMMENT 91 . 134) (T_CLASS 135 . 140) (T_STRING 141 . 
144) ("{" 145 . 146) (T_VAR 151 . 154) (T_VARIABLE 155 . 159) (";" 159 . 160) 
(T_VAR 165 . 168) (T_VARIABLE 169 . 173) (";" 173 . 174) (T_FUNCTION 180 . 188) 
(T_STRING 189 . 200) ("(" 200 . 201) (")" 201 . 202) ("{" 207 . 208) 
(T_VARIABLE 217 . 222) (T_OBJECT_OP [...]
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 12 . 13) (T_START_HEREDOC 
14 . 21) (T_ENCAPSED_AND_WHITESPACE 21 . 84) (T_END_HEREDOC 84 . 88) (";" 88 . 
89) (T_COMMENT 91 . 134) (T_CLASS 135 . 140) (T_STRING 141 . 144) ("{" 145 . 
146) (T_VAR 151 . 154) (T_VARIABLE 155 . 159) (";" 159 . 160) (T_VAR 165 . 168) 
(T_VARIABLE 169 . 173) (";" 173 . 174) (T_FUNCTION 180 . 188) (T_STRING 189 . 
200) ("(" 200 . 201) (")" 201 . 202) ("{" 207 . 208) (T_VARIABLE 217 . 222) 
(T_OBJECT_OPERATOR 222 .  [...]
 
   (phps-mode-test--with-buffer
    "<?php\nvar_dump(array(<<<EOD\nfoobar!\nEOD\n));\n?>\n"
    "Example #4 Heredoc in arguments example"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_STRING 7 . 15) ("(" 15 . 16) 
(T_ARRAY 16 . 21) ("(" 21 . 22) (T_START_HEREDOC 22 . 29) 
(T_ENCAPSED_AND_WHITESPACE 29 . 36) (T_END_HEREDOC 36 . 40) (")" 41 . 42) (")" 
42 . 43) (";" 43 . 44) (";" 45 . 47) (T_CLOSE_TAG 45 . 47) (T_INLINE_HTML 47 . 
48)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_STRING 7 . 15) ("(" 15 . 16) (T_ARRAY 16 . 21) 
("(" 21 . 22) (T_START_HEREDOC 22 . 29) (T_ENCAPSED_AND_WHITESPACE 29 . 36) 
(T_END_HEREDOC 36 . 40) (")" 41 . 42) (")" 42 . 43) (";" 43 . 44) (T_CLOSE_TAG 
45 . 47) (T_INLINE_HTML 47 . 48)))))
 
   (phps-mode-test--with-buffer
    "<?php\n// Static variables\nfunction foo()\n{\n    static $bar = 
<<<LABEL\nNothing in here...\nLABEL;\n}\n\n// Class properties/constants\nclass 
foo\n{\n    const BAR = <<<FOOBAR\nConstant example\nFOOBAR;\n\n    public $baz 
= <<<FOOBAR\nProperty example\nFOOBAR;\n}\n?>\n"
    "Example #5 Using Heredoc to initialize static values"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_COMMENT 7 . 26) (T_FUNCTION 27 . 35) 
(T_STRING 36 . 39) ("(" 39 . 40) (")" 40 . 41) ("{" 42 . 43) (T_STATIC 48 . 54) 
(T_VARIABLE 55 . 59) ("=" 60 . 61) (T_START_HEREDOC 62 . 71) 
(T_ENCAPSED_AND_WHITESPACE 71 . 89) (T_END_HEREDOC 89 . 95) (";" 95 . 96) ("}" 
97 . 98) (T_COMMENT 100 . 129) (T_CLASS 130 . 135) (T_STRING 136 . 139) ("{" 
140 . 141) (T_CONST 146 . 151) (T_STRING 152 . 155) ("=" 156 . 157) 
(T_START_HEREDOC 158 . 168) (T_ENCAPSED_AND_WHIT [...]
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_COMMENT 7 . 26) (T_FUNCTION 27 . 35) (T_STRING 36 
. 39) ("(" 39 . 40) (")" 40 . 41) ("{" 42 . 43) (T_STATIC 48 . 54) (T_VARIABLE 
55 . 59) ("=" 60 . 61) (T_START_HEREDOC 62 . 71) (T_ENCAPSED_AND_WHITESPACE 71 
. 89) (T_END_HEREDOC 89 . 95) (";" 95 . 96) ("}" 97 . 98) (T_COMMENT 100 . 129) 
(T_CLASS 130 . 135) (T_STRING 136 . 139) ("{" 140 . 141) (T_CONST 146 . 151) 
(T_STRING 152 . 155) ("=" 156 . 157) (T_START_HEREDOC 158 . 168) 
(T_ENCAPSED_AND_WHITESPACE 168 .  [...]
 
   (phps-mode-test--with-buffer
    "<?php\necho <<<\"FOOBAR\"\nHello World!\nFOOBAR;\n?>\n"
    "Example #6 Using double quotes in Heredoc"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_START_HEREDOC 12 . 
24) (T_ENCAPSED_AND_WHITESPACE 24 . 36) (T_END_HEREDOC 36 . 43) (";" 43 . 44) 
(";" 45 . 47) (T_CLOSE_TAG 45 . 47) (T_INLINE_HTML 47 . 48)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_START_HEREDOC 12 . 24) 
(T_ENCAPSED_AND_WHITESPACE 24 . 36) (T_END_HEREDOC 36 . 43) (";" 43 . 44) 
(T_CLOSE_TAG 45 . 47) (T_INLINE_HTML 47 . 48)))))
 
   ;; NOWDOC
 
   (phps-mode-test--with-buffer
    "<?php\necho <<<'EOD'\nExample of string spanning multiple lines\nusing 
nowdoc syntax. Backslashes are always treated literally,\ne.g. \\ and 
\'.\nEOD;\n"
    "Example #7 Nowdoc string quoting example"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_START_HEREDOC 12 . 
21) (T_ENCAPSED_AND_WHITESPACE 21 . 139) (T_END_HEREDOC 139 . 143) (";" 143 . 
144)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_START_HEREDOC 12 . 21) 
(T_ENCAPSED_AND_WHITESPACE 21 . 139) (T_END_HEREDOC 139 . 143) (";" 143 . 
144)))))
 
   (phps-mode-test--with-buffer
    "<?php\nclass foo\n{\n    public $foo;\n    public $bar;\n\n    function 
__construct()\n    {\n        $this->foo = 'Foo';\n        $this->bar = 
array('Bar1', 'Bar2', 'Bar3');\n    }\n}\n\n$foo = new foo();\n$name = 
'MyName';\n\necho <<<'EOT'\nMy name is \"$name\". I am printing some 
$foo->foo.\nNow, I am printing some {$foo->bar[1]}.\nThis should not print a 
capital 'A': \x41\nEOT;\n?>\n"
    "Example #8 Nowdoc string quoting example with variables"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_CLASS 7 . 12) (T_STRING 13 . 16) 
("{" 17 . 18) (T_PUBLIC 23 . 29) (T_VARIABLE 30 . 34) (";" 34 . 35) (T_PUBLIC 
40 . 46) (T_VARIABLE 47 . 51) (";" 51 . 52) (T_FUNCTION 58 . 66) (T_STRING 67 . 
78) ("(" 78 . 79) (")" 79 . 80) ("{" 85 . 86) (T_VARIABLE 95 . 100) 
(T_OBJECT_OPERATOR 100 . 102) (T_STRING 102 . 105) ("=" 106 . 107) 
(T_CONSTANT_ENCAPSED_STRING 108 . 113) (";" 113 . 114) (T_VARIABLE 123 . 128) 
(T_OBJECT_OPERATOR 128 . 130) (T_STRING 130 .  [...]
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_CLASS 7 . 12) (T_STRING 13 . 16) ("{" 17 . 18) 
(T_PUBLIC 23 . 29) (T_VARIABLE 30 . 34) (";" 34 . 35) (T_PUBLIC 40 . 46) 
(T_VARIABLE 47 . 51) (";" 51 . 52) (T_FUNCTION 58 . 66) (T_STRING 67 . 78) ("(" 
78 . 79) (")" 79 . 80) ("{" 85 . 86) (T_VARIABLE 95 . 100) (T_OBJECT_OPERATOR 
100 . 102) (T_STRING 102 . 105) ("=" 106 . 107) (T_CONSTANT_ENCAPSED_STRING 108 
. 113) (";" 113 . 114) (T_VARIABLE 123 . 128) (T_OBJECT_OPERATOR 128 . 130) 
(T_STRING 130 . 133) ("=" 134 [...]
 
   (phps-mode-test--with-buffer
    "<?php\nclass foo {\n    public $bar = <<<'EOT'\nbar\nEOT;\n}\n?>\n"
    "Example #9 Static data example (Nowdoc)"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_CLASS 7 . 12) (T_STRING 13 . 16) 
("{" 17 . 18) (T_PUBLIC 23 . 29) (T_VARIABLE 30 . 34) ("=" 35 . 36) 
(T_START_HEREDOC 37 . 46) (T_ENCAPSED_AND_WHITESPACE 46 . 49) (T_END_HEREDOC 49 
. 53) (";" 53 . 54) ("}" 55 . 56) (";" 57 . 59) (T_CLOSE_TAG 57 . 59) 
(T_INLINE_HTML 59 . 60)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_CLASS 7 . 12) (T_STRING 13 . 16) ("{" 17 . 18) 
(T_PUBLIC 23 . 29) (T_VARIABLE 30 . 34) ("=" 35 . 36) (T_START_HEREDOC 37 . 46) 
(T_ENCAPSED_AND_WHITESPACE 46 . 49) (T_END_HEREDOC 49 . 53) (";" 53 . 54) ("}" 
55 . 56) (T_CLOSE_TAG 57 . 59) (T_INLINE_HTML 59 . 60)))))
 
   ;; Backquotes
   (phps-mode-test--with-buffer
    "<?php `echo \"HELLO\"`;"
    "Backquote basic test"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) ("`" 7 . 8) (T_CONSTANT_ENCAPSED_STRING 
8 . 20) ("`" 20 . 21) (";" 21 . 22)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) ("`" 7 . 8) (T_ENCAPSED_AND_WHITESPACE 8 . 20) ("`" 
20 . 21) (";" 21 . 22)))))
 
   (phps-mode-test--with-buffer
    "<?php `echo \"HELLO $variable or {$variable2} or ${variable3} or 
$variable[index][0] here\"`;"
    "Double quoted strings with mixed variables"
    ;; (message "Tokens: %s" phps-mode-lex-analyzer--tokens)
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) ("`" 7 . 8) (T_CONSTANT_ENCAPSED_STRING 
8 . 20) (T_VARIABLE 20 . 29) (T_CONSTANT_ENCAPSED_STRING 29 . 33) (T_CURLY_OPEN 
33 . 34) (T_VARIABLE 34 . 44) ("}" 44 . 45) (T_CONSTANT_ENCAPSED_STRING 45 . 
49) (T_DOLLAR_OPEN_CURLY_BRACES 49 . 51) (T_STRING_VARNAME 51 . 60) ("}" 60 . 
61) (T_CONSTANT_ENCAPSED_STRING 61 . 65) (T_VARIABLE 65 . 74) ("[" 74 . 75) 
(T_STRING 75 . 80) ("]" 80 . 81) (T_CONSTANT_ENCAPSED_STRING 81 . 90) ("`" 90 . 
91) (";" 91 . 92)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) ("`" 7 . 8) (T_ENCAPSED_AND_WHITESPACE 8 . 20) 
(T_VARIABLE 20 . 29) (T_ENCAPSED_AND_WHITESPACE 29 . 33) (T_CURLY_OPEN 33 . 34) 
(T_VARIABLE 34 . 44) ("}" 44 . 45) (T_ENCAPSED_AND_WHITESPACE 45 . 49) 
(T_DOLLAR_OPEN_CURLY_BRACES 49 . 51) (T_STRING_VARNAME 51 . 60) ("}" 60 . 61) 
(T_ENCAPSED_AND_WHITESPACE 61 . 65) (T_VARIABLE 65 . 74) ("[" 74 . 75) 
(T_STRING 75 . 80) ("]" 80 . 81) (T_ENCAPSED_AND_WHITESPACE 81 . 90) ("`" 90 . 
91) (";" 91 . 92)))))
 
   (phps-mode-test--with-buffer
    "<?php $wpdb->posts; ?>"
-   nil
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 12) (T_OBJECT_OPERATOR 
12 . 14) (T_STRING 14 . 19) (";" 19 . 20) (";" 21 . 23) (T_CLOSE_TAG 21 . 
23)))))
+   "Wordpress example object operator"
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 12) (T_OBJECT_OPERATOR 12 . 14) 
(T_STRING 14 . 19) (";" 19 . 20) (T_CLOSE_TAG 21 . 23)))))
 
   (phps-mode-test--with-buffer
    "<?php $var = \"SELECT post_parent FROM $wpdb->posts WHERE ID = 
'\".$id.\"'\"; ?>"
-   nil
+   "Wordpress example SQL query in double-quoted string with variables"
    ;; (message "Tokens 1: %s" phps-mode-lex-analyzer--tokens)
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 12 . 13) ("\"" 
14 . 15) (T_ENCAPSED_AND_WHITESPACE 15 . 39) (T_VARIABLE 39 . 44) 
(T_OBJECT_OPERATOR 44 . 46) (T_STRING 46 . 51) (T_CONSTANT_ENCAPSED_STRING 51 . 
64) ("\"" 64 . 65) ("." 65 . 66) (T_VARIABLE 66 . 69) ("." 69 . 70) 
(T_CONSTANT_ENCAPSED_STRING 70 . 73) (";" 73 . 74) (";" 75 . 77) (T_CLOSE_TAG 
75 . 77)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 12 . 13) ("\"" 14 . 15) 
(T_CONSTANT_ENCAPSED_STRING 15 . 39) (T_VARIABLE 39 . 44) (T_OBJECT_OPERATOR 44 
. 46) (T_STRING 46 . 51) (T_CONSTANT_ENCAPSED_STRING 51 . 64) ("\"" 64 . 65) 
("." 65 . 66) (T_VARIABLE 66 . 69) ("." 69 . 70) (T_CONSTANT_ENCAPSED_STRING 70 
. 73) (";" 73 . 74) (T_CLOSE_TAG 75 . 77)))))
 
   (phps-mode-test--with-buffer
    "<?php $wpdb->get_var(\"SELECT post_parent FROM $wpdb->posts WHERE ID = 
'\".$id.\"'\"); ?>"
-   nil
+   "Wordpress example object operator with sql in double quotes with variable 
inside"
    ;; (message "Tokens 2: %s" phps-mode-lex-analyzer--tokens)
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 12) (T_OBJECT_OPERATOR 
12 . 14) (T_STRING 14 . 21) ("(" 21 . 22) ("\"" 22 . 23) 
(T_ENCAPSED_AND_WHITESPACE 23 . 47) (T_VARIABLE 47 . 52) (T_OBJECT_OPERATOR 52 
. 54) (T_STRING 54 . 59) (T_CONSTANT_ENCAPSED_STRING 59 . 72) ("\"" 72 . 73) 
("." 73 . 74) (T_VARIABLE 74 . 77) ("." 77 . 78) (T_CONSTANT_ENCAPSED_STRING 78 
. 81) (")" 81 . 82) (";" 82 . 83) (";" 84 . 86) (T_CLOSE_TAG 84 . 86)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 12) (T_OBJECT_OPERATOR 12 . 14) 
(T_STRING 14 . 21) ("(" 21 . 22) ("\"" 22 . 23) (T_CONSTANT_ENCAPSED_STRING 23 
. 47) (T_VARIABLE 47 . 52) (T_OBJECT_OPERATOR 52 . 54) (T_STRING 54 . 59) 
(T_CONSTANT_ENCAPSED_STRING 59 . 72) ("\"" 72 . 73) ("." 73 . 74) (T_VARIABLE 
74 . 77) ("." 77 . 78) (T_CONSTANT_ENCAPSED_STRING 78 . 81) (")" 81 . 82) (";" 
82 . 83) (T_CLOSE_TAG 84 . 86)))))
 
   (phps-mode-test--with-buffer
    "<?php $this->add($option['style']['selectors'], array('background' => 
\"{$value['color']} url('{$value['image']}')\"));"
    "Complex tokens with tokens inside double-quoted string"
    ;; (message "Tokens 2: %s" phps-mode-lex-analyzer--tokens)
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 12) (T_OBJECT_OPERATOR 
12 . 14) (T_STRING 14 . 17) ("(" 17 . 18) (T_VARIABLE 18 . 25) ("[" 25 . 26) 
(T_CONSTANT_ENCAPSED_STRING 26 . 33) ("]" 33 . 34) ("[" 34 . 35) 
(T_CONSTANT_ENCAPSED_STRING 35 . 46) ("]" 46 . 47) ("," 47 . 48) (T_ARRAY 49 . 
54) ("(" 54 . 55) (T_CONSTANT_ENCAPSED_STRING 55 . 67) (T_DOUBLE_ARROW 68 . 70) 
("\"" 71 . 72) (T_ENCAPSED_AND_WHITESPACE 72 . 72) (T_CURLY_OPEN 72 . 73) 
(T_VARIABLE 73 . 79) ("[" 79 . 80) (T_C [...]
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 12) (T_OBJECT_OPERATOR 12 . 14) 
(T_STRING 14 . 17) ("(" 17 . 18) (T_VARIABLE 18 . 25) ("[" 25 . 26) 
(T_CONSTANT_ENCAPSED_STRING 26 . 33) ("]" 33 . 34) ("[" 34 . 35) 
(T_CONSTANT_ENCAPSED_STRING 35 . 46) ("]" 46 . 47) ("," 47 . 48) (T_ARRAY 49 . 
54) ("(" 54 . 55) (T_CONSTANT_ENCAPSED_STRING 55 . 67) (T_DOUBLE_ARROW 68 . 70) 
("\"" 71 . 72) (T_CURLY_OPEN 72 . 73) (T_VARIABLE 73 . 79) ("[" 79 . 80) 
(T_CONSTANT_ENCAPSED_STRING 80 . 87) ("]" 87 . 88) (" [...]
 
   (phps-mode-test--with-buffer
    "<?php\n$var = <<<EOD\nrandom {$value['color']->property} again 
{$value->head()}; random\nEOD;\n"
    "Complex tokens with tokens inside HEREDOC string"
    ;; (message "Tokens 2: %s" phps-mode-lex-analyzer--tokens)
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 12 . 13) 
(T_START_HEREDOC 14 . 21) (T_ENCAPSED_AND_WHITESPACE 21 . 28) (T_CURLY_OPEN 28 
. 29) (T_VARIABLE 29 . 35) ("[" 35 . 36) (T_CONSTANT_ENCAPSED_STRING 36 . 43) 
("]" 43 . 44) (T_OBJECT_OPERATOR 44 . 46) (T_STRING 46 . 54) ("}" 54 . 55) 
(T_ENCAPSED_AND_WHITESPACE 55 . 62) (T_CURLY_OPEN 62 . 63) (T_VARIABLE 63 . 69) 
(T_OBJECT_OPERATOR 69 . 71) (T_STRING 71 . 75) ("(" 75 . 76) (")" 76 . 77) ("}" 
77 . 78) (T_ENCAPSED_AND_WH [...]
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 12 . 13) (T_START_HEREDOC 
14 . 21) (T_ENCAPSED_AND_WHITESPACE 21 . 28) (T_CURLY_OPEN 28 . 29) (T_VARIABLE 
29 . 35) ("[" 35 . 36) (T_CONSTANT_ENCAPSED_STRING 36 . 43) ("]" 43 . 44) 
(T_OBJECT_OPERATOR 44 . 46) (T_STRING 46 . 54) ("}" 54 . 55) 
(T_ENCAPSED_AND_WHITESPACE 55 . 62) (T_CURLY_OPEN 62 . 63) (T_VARIABLE 63 . 69) 
(T_OBJECT_OPERATOR 69 . 71) (T_STRING 71 . 75) ("(" 75 . 76) (")" 76 . 77) ("}" 
77 . 78) (T_ENCAPSED_AND_WHITESPACE 78 . [...]
 
   (phps-mode-test--with-buffer
    "<?php echo \"\\\"$string\\\"\";"
    "Escaped double quotes with variable in it"
    ;; (message "Tokens 2: %s" phps-mode-lex-analyzer--tokens)
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) ("\"" 12 . 13) 
(T_ENCAPSED_AND_WHITESPACE 13 . 15) (T_VARIABLE 15 . 22) 
(T_CONSTANT_ENCAPSED_STRING 22 . 24) ("\"" 24 . 25) (";" 25 . 26)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) ("\"" 12 . 13) 
(T_CONSTANT_ENCAPSED_STRING 13 . 15) (T_VARIABLE 15 . 22) 
(T_CONSTANT_ENCAPSED_STRING 22 . 24) ("\"" 24 . 25) (";" 25 . 26)))))
 
   (phps-mode-test--with-buffer
    "<?php $var = \"\\\\\";"
    "Double quoted string containing only two backslashes"
    ;; (message "Tokens 2: %s" phps-mode-lex-analyzer--tokens)
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 12 . 13) 
(T_CONSTANT_ENCAPSED_STRING 14 . 18) (";" 18 . 19)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 12 . 13) 
(T_CONSTANT_ENCAPSED_STRING 14 . 18) (";" 18 . 19)))))
 
   (phps-mode-test--with-buffer
    "<?php\n\n$object = (object) array(\n    'field_random' => 25\n);\n$field = 
'random';\necho $object->{\"field_$field\"};"
    "Dynamic object property"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_VARIABLE 8 . 15) ("=" 16 . 17) 
(T_OBJECT_CAST 18 . 26) (T_ARRAY 27 . 32) ("(" 32 . 33) 
(T_CONSTANT_ENCAPSED_STRING 38 . 52) (T_DOUBLE_ARROW 53 . 55) (T_LNUMBER 56 . 
58) (")" 59 . 60) (";" 60 . 61) (T_VARIABLE 62 . 68) ("=" 69 . 70) 
(T_CONSTANT_ENCAPSED_STRING 71 . 79) (";" 79 . 80) (T_ECHO 81 . 85) (T_VARIABLE 
86 . 93) (T_OBJECT_OPERATOR 93 . 95) ("{" 95 . 96) ("\"" 96 . 97) 
(T_ENCAPSED_AND_WHITESPACE 97 . 103) (T_VARIABLE 103 . 109) ("\"" 109 .  [...]
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 8 . 15) ("=" 16 . 17) (T_OBJECT_CAST 18 
. 26) (T_ARRAY 27 . 32) ("(" 32 . 33) (T_CONSTANT_ENCAPSED_STRING 38 . 52) 
(T_DOUBLE_ARROW 53 . 55) (T_LNUMBER 56 . 58) (")" 59 . 60) (";" 60 . 61) 
(T_VARIABLE 62 . 68) ("=" 69 . 70) (T_CONSTANT_ENCAPSED_STRING 71 . 79) (";" 79 
. 80) (T_ECHO 81 . 85) (T_VARIABLE 86 . 93) (T_OBJECT_OPERATOR 93 . 95) ("{" 95 
. 96) ("\"" 96 . 97) (T_CONSTANT_ENCAPSED_STRING 97 . 103) (T_VARIABLE 103 . 
109) ("\"" 109 . 110) ("}" 11 [...]
 
   (phps-mode-test--with-buffer
    "<?php\nclass MyClass { function myFunction() { return 'hello'; }}\n$class 
= new MyClass();\n$function = \"Function\";\necho $class->{\"my$function\"}();"
    "Dynamic object method"
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_CLASS 7 . 12) (T_STRING 13 . 20) 
("{" 21 . 22) (T_FUNCTION 23 . 31) (T_STRING 32 . 42) ("(" 42 . 43) (")" 43 . 
44) ("{" 45 . 46) (T_RETURN 47 . 53) (T_CONSTANT_ENCAPSED_STRING 54 . 61) (";" 
61 . 62) ("}" 63 . 64) ("}" 64 . 65) (T_VARIABLE 66 . 72) ("=" 73 . 74) (T_NEW 
75 . 78) (T_STRING 79 . 86) ("(" 86 . 87) (")" 87 . 88) (";" 88 . 89) 
(T_VARIABLE 90 . 99) ("=" 100 . 101) (T_CONSTANT_ENCAPSED_STRING 102 . 112) 
(";" 112 . 113) (T_ECHO 114 . 118)  [...]
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_CLASS 7 . 12) (T_STRING 13 . 20) ("{" 21 . 22) 
(T_FUNCTION 23 . 31) (T_STRING 32 . 42) ("(" 42 . 43) (")" 43 . 44) ("{" 45 . 
46) (T_RETURN 47 . 53) (T_CONSTANT_ENCAPSED_STRING 54 . 61) (";" 61 . 62) ("}" 
63 . 64) ("}" 64 . 65) (T_VARIABLE 66 . 72) ("=" 73 . 74) (T_NEW 75 . 78) 
(T_STRING 79 . 86) ("(" 86 . 87) (")" 87 . 88) (";" 88 . 89) (T_VARIABLE 90 . 
99) ("=" 100 . 101) (T_CONSTANT_ENCAPSED_STRING 102 . 112) (";" 112 . 113) 
(T_ECHO 114 . 118) (T_VARIABLE 1 [...]
 
   (phps-mode-test--with-buffer
    "<?php\n$product_path = \"${filename[0]}/${filename[1]}/\";\n    echo 
'here';\n"
    "String with two dollar_open_curly_braces with indexes"
    ;; (message "Tokens: %s" phps-mode-lex-analyzer--tokens)
-   (should (equal phps-mode-lex-analyzer--tokens
-                  '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 20) ("=" 21 . 22) ("\"" 
23 . 24) (T_ENCAPSED_AND_WHITESPACE 24 . 24) (T_DOLLAR_OPEN_CURLY_BRACES 24 . 
26) (T_STRING_VARNAME 26 . 34) ("[" 34 . 35) (T_LNUMBER 35 . 36) ("]" 36 . 37) 
("}" 37 . 38) (T_CONSTANT_ENCAPSED_STRING 38 . 39) (T_DOLLAR_OPEN_CURLY_BRACES 
39 . 41) (T_STRING_VARNAME 41 . 49) ("[" 49 . 50) (T_LNUMBER 50 . 51) ("]" 51 . 
52) ("}" 52 . 53) (T_CONSTANT_ENCAPSED_STRING 53 . 54) ("\"" 54 . 55) (";" 55 . 
56) (T_ECHO 61 .  [...]
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 20) ("=" 21 . 22) ("\"" 23 . 24) 
(T_DOLLAR_OPEN_CURLY_BRACES 24 . 26) (T_STRING_VARNAME 26 . 34) ("[" 34 . 35) 
(T_LNUMBER 35 . 36) ("]" 36 . 37) ("}" 37 . 38) (T_CONSTANT_ENCAPSED_STRING 38 
. 39) (T_DOLLAR_OPEN_CURLY_BRACES 39 . 41) (T_STRING_VARNAME 41 . 49) ("[" 49 . 
50) (T_LNUMBER 50 . 51) ("]" 51 . 52) ("}" 52 . 53) (T_CONSTANT_ENCAPSED_STRING 
53 . 54) ("\"" 54 . 55) (";" 55 . 56) (T_ECHO 61 . 65) 
(T_CONSTANT_ENCAPSED_STRING 66 . 72) (";" 72  [...]
 
   )
 
@@ -375,9 +534,10 @@
   (phps-mode-test--with-buffer
    "<?php\nNAMESPACE MyNameSpace;\nCLASS MyClass {\n\tpublic function 
__construct() {\n\t\texit;\n\t}\n}\n"
    "Capitalized object-oriented namespace file"
-   (should (equal
-            phps-mode-lex-analyzer--tokens
-            '((T_OPEN_TAG 1 . 7) (T_NAMESPACE 7 . 16) (T_STRING 17 . 28) (";" 
28 . 29) (T_CLASS 30 . 35) (T_STRING 36 . 43) ("{" 44 . 45) (T_PUBLIC 47 . 53) 
(T_FUNCTION 54 . 62) (T_STRING 63 . 74) ("(" 74 . 75) (")" 75 . 76) ("{" 77 . 
78) (T_EXIT 81 . 85) (";" 85 . 86) ("}" 88 . 89) ("}" 90 . 91)))))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_NAMESPACE 7 . 16) (T_STRING 17 . 28) (";" 28 . 
29) (T_CLASS 30 . 35) (T_STRING 36 . 43) ("{" 44 . 45) (T_PUBLIC 47 . 53) 
(T_FUNCTION 54 . 62) (T_STRING 63 . 74) ("(" 74 . 75) (")" 75 . 76) ("{" 77 . 
78) (T_EXIT 81 . 85) (";" 85 . 86) ("}" 88 . 89) ("}" 90 . 91)))))
   )
 
 (defun phps-mode-test-lexer--errors ()
@@ -386,105 +546,116 @@
   (phps-mode-test--with-buffer
    "<?php\necho \"My neverending double quotation\n"
    "Neverending double quotation"
-   (should (equal
-            phps-mode-lex-analyzer--tokens
-            nil)))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     nil)))
 
   (phps-mode-test--with-buffer
    "<?php\n`My neverending backquotes\n"
    "Neverending backquotes"
-   (should (equal
-            phps-mode-lex-analyzer--tokens
-            nil)))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     nil)))
 
   (phps-mode-test--with-buffer
    "<?php\n<<<LABEL\nMy neverending heredoc\ngoes on forever\n"
    "Neverending heredoc"
-   (should (equal
-            phps-mode-lex-analyzer--tokens
-            nil)))
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     nil)))
 
   )
 
 (defun phps-mode-test-lexer--get-moved-lexer-tokens ()
   "Run test for get moved lexer tokens."
 
-  (should (equal
-           '((T_OPEN_TAG 1 . 7) (T_START_HEREDOC 7 . 21) (T_ERROR 21 . 60))
-           (phps-mode-lex-analyzer--get-moved-tokens '((T_OPEN_TAG 1 . 7) 
(T_START_HEREDOC 7 . 16) (T_ERROR 16 . 55)) 8 5)))
+  (should
+   (equal
+    '((T_OPEN_TAG 1 . 7) (T_START_HEREDOC 7 . 21) (T_ERROR 21 . 60))
+    (phps-mode-lex-analyzer--get-moved-tokens '((T_OPEN_TAG 1 . 7) 
(T_START_HEREDOC 7 . 16) (T_ERROR 16 . 55)) 8 5)))
 
-  (should (equal
-           '((T_OPEN_TAG 1 . 7) (T_START_HEREDOC 7 . 11) (T_ERROR 11 . 50))
-           (phps-mode-lex-analyzer--get-moved-tokens '((T_OPEN_TAG 1 . 7) 
(T_START_HEREDOC 7 . 16) (T_ERROR 16 . 55)) 8 -5)))
+  (should
+   (equal
+    '((T_OPEN_TAG 1 . 7) (T_START_HEREDOC 7 . 11) (T_ERROR 11 . 50))
+    (phps-mode-lex-analyzer--get-moved-tokens '((T_OPEN_TAG 1 . 7) 
(T_START_HEREDOC 7 . 16) (T_ERROR 16 . 55)) 8 -5)))
 
-  (should (equal
-           '((T_OPEN_TAG 1 . 8) (T_START_HEREDOC 8 . 17) (T_ERROR 17 . 56))
-           (phps-mode-lex-analyzer--get-moved-tokens '((T_OPEN_TAG 1 . 7) 
(T_START_HEREDOC 7 . 16) (T_ERROR 16 . 55)) 6 1)))
+  (should
+   (equal
+    '((T_OPEN_TAG 1 . 8) (T_START_HEREDOC 8 . 17) (T_ERROR 17 . 56))
+    (phps-mode-lex-analyzer--get-moved-tokens '((T_OPEN_TAG 1 . 7) 
(T_START_HEREDOC 7 . 16) (T_ERROR 16 . 55)) 6 1)))
 
-  (should (equal
-           '((T_OPEN_TAG 1 . 7) (T_START_HEREDOC 7 . 16) (T_ERROR 16 . 56))
-           (phps-mode-lex-analyzer--get-moved-tokens '((T_OPEN_TAG 1 . 7) 
(T_START_HEREDOC 7 . 16) (T_ERROR 16 . 55)) 20 1)))
+  (should
+   (equal
+    '((T_OPEN_TAG 1 . 7) (T_START_HEREDOC 7 . 16) (T_ERROR 16 . 56))
+    (phps-mode-lex-analyzer--get-moved-tokens '((T_OPEN_TAG 1 . 7) 
(T_START_HEREDOC 7 . 16) (T_ERROR 16 . 55)) 20 1)))
 
-  (should (equal
-           '((T_OPEN_TAG 1 . 7) (T_START_HEREDOC 7 . 16) (T_ERROR 16 . 54))
-           (phps-mode-lex-analyzer--get-moved-tokens '((T_OPEN_TAG 1 . 7) 
(T_START_HEREDOC 7 . 16) (T_ERROR 16 . 55)) 20 -1)))
+  (should
+   (equal
+    '((T_OPEN_TAG 1 . 7) (T_START_HEREDOC 7 . 16) (T_ERROR 16 . 54))
+    (phps-mode-lex-analyzer--get-moved-tokens '((T_OPEN_TAG 1 . 7) 
(T_START_HEREDOC 7 . 16) (T_ERROR 16 . 55)) 20 -1)))
 
   )
 
 (defun phps-mode-test-lexer--get-moved-lexer-states ()
   "Run test for get moved lexer states."
 
-  (should (equal
-           '((68 76 1 '(1))
-             (10 67 1 '(1))
-             (1 9 1 '(1)))
-           
-           (phps-mode-lex-analyzer--get-moved-states
-            '((66 74 1 '(1))
-              (8 65 1 '(1))
-              (1 7 1 '(1)))
-            6
-            2)))
-
-  (should (equal
-           '((67 75 1 '(1))
-             (9 66 1 '(1))
-             (2 8 1 '(1)))
-           
-           (phps-mode-lex-analyzer--get-moved-states
-            '((66 74 1 '(1))
-              (8 65 1 '(1))
-              (1 7 1 '(1)))
-            0
-            1)))
-
-  (should (equal
-           '((66 74 1 '(1))
-             (8 65 1 '(1))
-             (1 7 1 '(1)))
-           
-           (phps-mode-lex-analyzer--get-moved-states
-            '((66 74 1 '(1))
-              (8 65 1 '(1))
-              (1 7 1 '(1)))
-            100
-            1)))
-
-  (should (equal
-           '((64 72 1 '(1))
-             (6 63 1 '(1))
-             (1 7 1 '(1)))
-           
-           (phps-mode-lex-analyzer--get-moved-states
-            '((66 74 1 '(1))
-              (8 65 1 '(1))
-              (3 9 1 '(1)))
-            3
-            -2)))
-  )
+  (should
+   (equal
+    '((68 76 1 '(1))
+      (10 67 1 '(1))
+      (1 9 1 '(1)))
+
+    (phps-mode-lex-analyzer--get-moved-states
+     '((66 74 1 '(1))
+       (8 65 1 '(1))
+       (1 7 1 '(1)))
+     6
+     2)))
+
+  (should
+   (equal
+    '((67 75 1 '(1))
+      (9 66 1 '(1))
+      (2 8 1 '(1)))
+    
+    (phps-mode-lex-analyzer--get-moved-states
+     '((66 74 1 '(1))
+       (8 65 1 '(1))
+       (1 7 1 '(1)))
+     0
+     1)))
+
+  (should
+   (equal
+    '((66 74 1 '(1))
+      (8 65 1 '(1))
+      (1 7 1 '(1)))
+    
+    (phps-mode-lex-analyzer--get-moved-states
+     '((66 74 1 '(1))
+       (8 65 1 '(1))
+       (1 7 1 '(1)))
+     100
+     1)))
+
+  (should
+   (equal
+    '((64 72 1 '(1))
+      (6 63 1 '(1))
+      (1 7 1 '(1)))
+    
+    (phps-mode-lex-analyzer--get-moved-states
+     '((66 74 1 '(1))
+       (8 65 1 '(1))
+       (3 9 1 '(1)))
+     3
+     -2))))
 
 (defun phps-mode-test-lexer--benchmark ()
-  "Benchmark the lexer tests."
+  "Benchmark the lexer test."
   (require 'benchmark)
   (let ((iteration 1)
         (iterations 50))
diff --git a/test/phps-mode-test-parser.el b/test/phps-mode-test-parser.el
index 01c4dbf..1da580a 100644
--- a/test/phps-mode-test-parser.el
+++ b/test/phps-mode-test-parser.el
@@ -1,6 +1,6 @@
 ;;; phps-mode-test-parser.el --- Tests for parser -*- lexical-binding: t -*-
 
-;; Copyright (C) 2017-2019  Free Software Foundation, Inc.
+;; Copyright (C) 2017-2021  Free Software Foundation, Inc.
 
 ;; This file is not part of GNU Emacs.
 
diff --git a/test/phps-mode-test-syntax-table.el 
b/test/phps-mode-test-syntax-table.el
index 00b3939..16fb02e 100644
--- a/test/phps-mode-test-syntax-table.el
+++ b/test/phps-mode-test-syntax-table.el
@@ -1,6 +1,6 @@
 ;;; phps-mode-test-syntax-table.el --- Tests for syntax-table -*- 
lexical-binding: t -*-
 
-;; Copyright (C) 2018-2019  Free Software Foundation, Inc.
+;; Copyright (C) 2018-2021  Free Software Foundation, Inc.
 
 ;; This file is not part of GNU Emacs.
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]