branch: externals/phps-mode
commit a1db16f24b9e0975cfc5a7928e254414644802c3
Author: Christian Johansson <[email protected]>
Commit: Christian Johansson <[email protected]>
Passing tests after refactoring of lexer rules
---
phps-mode-lexer-generator.el | 409 ++++++++++++++++++++++++++++++++++++++++++-
phps-mode-lexer.el | 404 +-----------------------------------------
2 files changed, 402 insertions(+), 411 deletions(-)
diff --git a/phps-mode-lexer-generator.el b/phps-mode-lexer-generator.el
index 935984c9b6..ac5b19a42a 100644
--- a/phps-mode-lexer-generator.el
+++ b/phps-mode-lexer-generator.el
@@ -9,9 +9,120 @@
;;; Code:
+(require 'phps-mode-macros)
+
+
+
+(defvar-local phps-mode-lexer--generated-tokens nil
+ "List of current generated tokens.")
+
+(defvar-local phps-mode-lexer--generated-new-tokens nil
+ "List of current newly generated tokens.")
+
+(defvar-local phps-mode-lexer--generated-new-tokens-index nil
+ "Index started at when generated new tokens.")
+
+(defvar-local phps-mode-lexer--state nil
+ "Current state of lexer.")
+
+(defvar-local phps-mode-lexer--state-stack nil
+ "Current state-stack of lexer.")
+
+(defvar-local phps-mode-lexer--states nil
+ "History of state and state-stack.")
+
+(defvar-local phps-mode-lexer--heredoc-label nil
+ "Current heredoc label.")
+
+(defvar-local phps-mode-lexer--heredoc-label-stack nil
+ "Stack of heredoc labels.")
+
+(defvar-local phps-mode-lexer--match-length nil
+ "Maximum match length.")
+
+(defvar-local phps-mode-lexer--match-body nil
+ "Lambda om maximum match.")
+
+(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--parser-mode nil
+ "Non-nil means we are in parser-mode.")
+
+(defvar-local phps-mode-lexer--restart-flag nil
+ "Non-nil means restart.")
+
+;; @see https://secure.php.net/manual/en/language.types.integer.php
+(defconst phps-mode-lexer--long-limit
+ 2147483648
+ "Limit for 32-bit integer.")
+
+(defconst phps-mode-lexer--lnum
+ "[0-9]+\\(_[0-9]+\\)*"
+ "Long number.")
+
+(defconst phps-mode-lexer--dnum
+ (format
+ "\\(\\(%s\\)?\\.%s\\|%s\\.\\(%s\\)?\\)"
+ phps-mode-lexer--lnum
+ phps-mode-lexer--lnum
+ phps-mode-lexer--lnum
+ phps-mode-lexer--lnum)
+ "Double number.")
+
+(defconst phps-mode-lexer--exponent-dnum
+ (format "\\(\\(%s\\|%s\\)[eE][\\+-]?%s\\)"
+ phps-mode-lexer--lnum
+ phps-mode-lexer--dnum
+ phps-mode-lexer--lnum)
+ "Exponent double number.")
+
+(defconst phps-mode-lexer--hnum
+ "0x[0-9a-fA-F]+\\(_[0-9a-fA-F]+\\)*"
+ "Hexadecimal number.")
+
+(defconst phps-mode-lexer--bnum
+ "0b[01]+\\(_[01]+\\)*"
+ "Boolean number.")
+
+(defconst phps-mode-lexer--onum
+ "0o[0-7]+\\(_[0-7]+\\)*"
+ "Octal number.")
+
+(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]+"
+ "White-space.")
+
+(defconst phps-mode-lexer--tabs-and-spaces
+ "[ \t]*"
+ "Tabs and white-spaces.")
+
+(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]"
+ "Any character. The Zend equivalent is [^] but is not possible in Emacs
Lisp.")
+
+(defconst phps-mode-lexer--newline
+ "[\n\r]"
+ "Newline characters. The Zend equivalent is (\"\r\"|\"\n\"|\"\r\n\").")
+
(defvar phps-mode-lexer-generator--table nil)
-(defun phps-mode-lexer-generator--add-rule (table states conditions &rest body)
+(defun phps-mode-lexer-generator--add-rule (table states conditions body)
"Place in STATES a check for CONDITIONS to execute BODY."
(unless (listp states)
(setq states (list states)))
@@ -1705,7 +1816,6 @@
t)))
(if string-start
(let* ((start (match-beginning 0))
- (end (match-end 0))
(data (match-string 0)))
(cond
@@ -1718,7 +1828,6 @@
data)
;; Skip possible white-spaces before label
(setq start (match-beginning 2))
- (setq end (match-beginning 2))
;; (message "Found heredoc end at %s-%s" start end)
(phps-mode-lexer--return-token-with-val
'T_ENCAPSED_AND_WHITESPACE
@@ -1756,11 +1865,7 @@
nil
t)))
(if string-start
- (let* ((start (match-beginning 1))
- (end (match-end 1))
- (_data (buffer-substring-no-properties start end)))
- ;; (message "Found something ending at %s" _data)
- ;; (message "Found nowdoc end at %s-%s" start end)
+ (let* ((start (match-beginning 1)))
(phps-mode-lexer--return-token-with-val
'T_ENCAPSED_AND_WHITESPACE
phps-mode-lexer--generated-new-tokens-index
@@ -1787,4 +1892,292 @@
phps-mode-lexer-generator--table)
+(defvar phps-mode-lexer--CG-data
+ (make-hash-table :test 'equal)
+ "A hash-table with all settings.")
+
+(defun phps-mode-lexer--CG (subject &optional value)
+ "Return and optionally set VALUE of SUBJECT."
+ (if value
+ (puthash subject value phps-mode-lexer--CG-data)
+ (gethash subject phps-mode-lexer--CG-data)))
+
+(defun phps-mode-lexer--parser-mode ()
+ "Return whether we have some expected value or not."
+ phps-mode-lexer--parser-mode)
+
+(defun phps-mode-lexer--begin (state)
+ "Begin STATE."
+ (phps-mode-debug-message
+ (message "Begin state: %s" state))
+ (setq phps-mode-lexer--state 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)
+ (signal
+ 'phps-lexer-error
+ (list
+ (format "Trying to pop last state at %d" (point))
+ (point))))))
+
+(defun phps-mode-lexer--move-forward (position)
+ "Move forward to POSITION."
+ (when (boundp 'phps-mode-lex-analyzer--lexer-index)
+ (setq-local
+ phps-mode-lex-analyzer--lexer-index
+ position)))
+
+(defun phps-mode-lexer--yyless (points)
+ "Move lexer back POINTS."
+ (when (boundp 'phps-mode-lex-analyzer--lexer-index)
+ (setq-local
+ phps-mode-lex-analyzer--lexer-index
+ (- phps-mode-lex-analyzer--lexer-index 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))))))
+
+(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 ,(point))
+ phps-mode-lexer--nest-location-stack))
+
+(defun phps-mode-lexer--handle-newline ()
+ "Handle newline."
+ ;; TODO Implement this?
+ )
+
+(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= (car opening) "{")
+ (not (string= closing "}")))
+ (and (string= (car opening) "[")
+ (not (string= closing "]")))
+ (and (string= (car opening) "(")
+ (not (string= closing ")")))))
+ (signal
+ 'phps-lexer-error
+ (list
+ (format
+ "Bad nesting '%s' started at '%s' vs '%s' at %d'"
+ (car opening)
+ (car (cdr 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."
+ (when (= start end)
+ (signal
+ 'phps-lexer-error
+ (list
+ (format "Empty token detected: %s %s %s" token start end)
+ start
+ end
+ token)))
+
+ (push `(,token ,start . ,end) phps-mode-lexer--generated-tokens)
+ (push `(,token ,start . ,end) phps-mode-lexer--generated-new-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
+ (list
+ start
+ end
+ phps-mode-lexer--state
+ phps-mode-lexer--state-stack
+ phps-mode-lexer--heredoc-label
+ phps-mode-lexer--heredoc-label-stack
+ phps-mode-lexer--nest-location-stack)
+ phps-mode-lexer--states))
+
+(defun phps-mode-lexer--get-next-unescaped (character)
+ "Find where next un-escaped CHARACTER comes, if none is found return nil."
+ ;; (message "phps-mode-lexer--get-next-unescaped(%s)" character)
+ (let ((escaped nil)
+ (pos nil))
+ (while (and (not pos)
+ (< (point) (point-max)))
+ (progn
+ ;; (message "Setting forward one %s vs %s" (point) (point-max))
+ (forward-char)
+ (if (and (not escaped)
+ (looking-at-p character))
+ (setq pos (1+ (point)))
+ (if (looking-at-p "\\\\")
+ (setq escaped (not escaped))
+ (setq escaped nil)))))
+ pos))
+
+(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)))
+ (when (boundp 'phps-mode-lex-analyzer--lexer-index)
+ (setq-local
+ phps-mode-lex-analyzer--lexer-index
+ 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-lexer--CG 'doc_comment)
+ (phps-mode-lexer--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 &optional _offset 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."
+ (if (phps-mode-lexer--parser-mode)
+ (phps-mode-lexer--skip-token token start end)
+ (phps-mode-lexer--return-token token start end)))
+
+
(provide 'phps-mode-lexer-generator)
diff --git a/phps-mode-lexer.el b/phps-mode-lexer.el
index 61cad50984..75eae5caf5 100644
--- a/phps-mode-lexer.el
+++ b/phps-mode-lexer.el
@@ -28,92 +28,12 @@
;; INITIALIZE SETTINGS
-
-(defvar phps-mode-lexer--CG-data
- (make-hash-table :test 'equal)
- "A hash-table with all settings.")
-
-(defun phps-mode-lexer--CG (subject &optional value)
- "Return and optionally set VALUE of SUBJECT."
- (if value
- (puthash subject value phps-mode-lexer--CG-data)
- (gethash subject phps-mode-lexer--CG-data)))
-
(phps-mode-lexer--CG
'parser-mode t)
(phps-mode-lexer--CG
'short-tags t)
-;; SETTINGS
-
-
-;; @see https://secure.php.net/manual/en/language.types.integer.php
-(defconst phps-mode-lexer--long-limit
- 2147483648
- "Limit for 32-bit integer.")
-
-(defconst phps-mode-lexer--lnum
- "[0-9]+\\(_[0-9]+\\)*"
- "Long number.")
-
-(defconst phps-mode-lexer--dnum
- (format
- "\\(\\(%s\\)?\\.%s\\|%s\\.\\(%s\\)?\\)"
- phps-mode-lexer--lnum
- phps-mode-lexer--lnum
- phps-mode-lexer--lnum
- phps-mode-lexer--lnum)
- "Double number.")
-
-(defconst phps-mode-lexer--exponent-dnum
- (format "\\(\\(%s\\|%s\\)[eE][\\+-]?%s\\)"
- phps-mode-lexer--lnum
- phps-mode-lexer--dnum
- phps-mode-lexer--lnum)
- "Exponent double number.")
-
-(defconst phps-mode-lexer--hnum
- "0x[0-9a-fA-F]+\\(_[0-9a-fA-F]+\\)*"
- "Hexadecimal number.")
-
-(defconst phps-mode-lexer--bnum
- "0b[01]+\\(_[01]+\\)*"
- "Boolean number.")
-
-(defconst phps-mode-lexer--onum
- "0o[0-7]+\\(_[0-7]+\\)*"
- "Octal number.")
-
-(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]+"
- "White-space.")
-
-(defconst phps-mode-lexer--tabs-and-spaces
- "[ \t]*"
- "Tabs and white-spaces.")
-
-(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]"
- "Any character. The Zend equivalent is [^] but is not possible in Emacs
Lisp.")
-
-(defconst phps-mode-lexer--newline
- "[\n\r]"
- "Newline characters. The Zend equivalent is (\"\r\"|\"\n\"|\"\r\n\").")
-
-
;; VARIABLES
@@ -121,328 +41,6 @@
(eval-when-compile (phps-mode-lexer-generator--lambdas))
"Hash-table of lex-analyzer rules organized by state.")
-(defvar-local phps-mode-lexer--generated-tokens nil
- "List of current generated tokens.")
-
-(defvar-local phps-mode-lexer--generated-new-tokens nil
- "List of current newly generated tokens.")
-
-(defvar-local phps-mode-lexer--generated-new-tokens-index nil
- "Index started at when generated new tokens.")
-
-(defvar-local phps-mode-lexer--state nil
- "Current state of lexer.")
-
-(defvar-local phps-mode-lexer--state-stack nil
- "Current state-stack of lexer.")
-
-(defvar-local phps-mode-lexer--states nil
- "History of state and state-stack.")
-
-(defvar-local phps-mode-lexer--heredoc-label nil
- "Current heredoc label.")
-
-(defvar-local phps-mode-lexer--heredoc-label-stack nil
- "Stack of heredoc labels.")
-
-(defvar-local phps-mode-lexer--match-length nil
- "Maximum match length.")
-
-(defvar-local phps-mode-lexer--match-body nil
- "Lambda om maximum match.")
-
-(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--parser-mode nil
- "Non-nil means we are in parser-mode.")
-
-(defvar-local phps-mode-lexer--restart-flag nil
- "Non-nil means restart.")
-
-;; HELPER FUNCTIONS
-
-
-(defun phps-mode-lexer--parser-mode ()
- "Return whether we have some expected value or not."
- phps-mode-lexer--parser-mode)
-
-(defun phps-mode-lexer--begin (state)
- "Begin STATE."
- (phps-mode-debug-message
- (message "Begin state: %s" state))
- (setq phps-mode-lexer--state 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)
- (signal
- 'phps-lexer-error
- (list
- (format "Trying to pop last state at %d" (point))
- (point))))))
-
-(defun phps-mode-lexer--move-forward (position)
- "Move forward to POSITION."
- (when (boundp 'phps-mode-lex-analyzer--lexer-index)
- (setq-local
- phps-mode-lex-analyzer--lexer-index
- position)))
-
-(defun phps-mode-lexer--yyless (points)
- "Move lexer back POINTS."
- (when (boundp 'phps-mode-lex-analyzer--lexer-index)
- (setq-local
- phps-mode-lex-analyzer--lexer-index
- (- phps-mode-lex-analyzer--lexer-index 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))))))
-
-(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 ,(point))
- phps-mode-lexer--nest-location-stack))
-
-(defun phps-mode-lexer--handle-newline ()
- "Handle newline."
- ;; TODO Implement this?
- )
-
-(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= (car opening) "{")
- (not (string= closing "}")))
- (and (string= (car opening) "[")
- (not (string= closing "]")))
- (and (string= (car opening) "(")
- (not (string= closing ")")))))
- (signal
- 'phps-lexer-error
- (list
- (format
- "Bad nesting '%s' started at '%s' vs '%s' at %d'"
- (car opening)
- (car (cdr 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."
- (when (= start end)
- (signal
- 'phps-lexer-error
- (list
- (format "Empty token detected: %s %s %s" token start end)
- start
- end
- token)))
-
- (push `(,token ,start . ,end) phps-mode-lexer--generated-tokens)
- (push `(,token ,start . ,end) phps-mode-lexer--generated-new-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
- (list
- start
- end
- phps-mode-lexer--state
- phps-mode-lexer--state-stack
- phps-mode-lexer--heredoc-label
- phps-mode-lexer--heredoc-label-stack
- phps-mode-lexer--nest-location-stack)
- phps-mode-lexer--states))
-
-(defun phps-mode-lexer--get-next-unescaped (character)
- "Find where next un-escaped CHARACTER comes, if none is found return nil."
- ;; (message "phps-mode-lexer--get-next-unescaped(%s)" character)
- (let ((escaped nil)
- (pos nil))
- (while (and (not pos)
- (< (point) (point-max)))
- (progn
- ;; (message "Setting forward one %s vs %s" (point) (point-max))
- (forward-char)
- (if (and (not escaped)
- (looking-at-p character))
- (setq pos (1+ (point)))
- (if (looking-at-p "\\\\")
- (setq escaped (not escaped))
- (setq escaped nil)))))
- pos))
-
-(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)))
- (when (boundp 'phps-mode-lex-analyzer--lexer-index)
- (setq-local
- phps-mode-lex-analyzer--lexer-index
- 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-lexer--CG 'doc_comment)
- (phps-mode-lexer--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."
- (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
@@ -521,7 +119,7 @@
(setq
phps-mode-lexer--match-length matching-length)
(setq
- phps-mode-lexer--match-body (car (nth 1 lambd)))
+ phps-mode-lexer--match-body (nth 1 lambd))
(setq
phps-mode-lexer--match-data (match-data))