branch: externals/phps-mode
commit f44577a3ede0b0d7bc7f9adb380921f9d425599c
Author: Christian Johansson <[email protected]>
Commit: Christian Johansson <[email protected]>
More testing integrating parser and lex-analyzer
---
phps-mode-automation-grammar.el | 2 +-
phps-mode-lex-analyzer.el | 250 +++++++++++++++++++++++-----------------
phps-mode-parser.el | 21 +++-
test/phps-mode-test-lexer.el | 44 +++----
test/phps-mode-test-parser.el | 15 +++
5 files changed, 198 insertions(+), 134 deletions(-)
diff --git a/phps-mode-automation-grammar.el b/phps-mode-automation-grammar.el
index 790760b..5a1cc34 100644
--- a/phps-mode-automation-grammar.el
+++ b/phps-mode-automation-grammar.el
@@ -52,7 +52,7 @@
(defvar
phps-mode-automation-grammar--header
- "\n\n(defvar-local\n phps-mode-parser-position\n nil\n \"Position of
parser.\")\n\n(defvar-local\n phps-mode-parser-tokens\n nil\n \"Tokens for
parser.\")\n\n"
+ "\n\n(defvar-local\n phps-mode-parser-position\n nil\n \"Position of
parser.\")\n\n(defvar-local\n phps-mode-parser-tokens\n nil\n \"Tokens for
parser.\")\n\n(define-error\n 'phps-parser-error\n \"PHPs Lexer Error\")\n\n"
"Header contents for parser.")
(defvar
diff --git a/phps-mode-lex-analyzer.el b/phps-mode-lex-analyzer.el
index 3b0932a..ce891a2 100644
--- a/phps-mode-lex-analyzer.el
+++ b/phps-mode-lex-analyzer.el
@@ -387,16 +387,39 @@
buffer-name
(lambda()
- (let* ((lex-result
- (phps-mode-lex-analyzer--lex-string buffer-contents))
- (processed-result
- (phps-mode-lex-analyzer--process-tokens-in-string
- (nth 0 lex-result)
- buffer-contents)))
- ;; TODO Async parse here?
- (list
- lex-result
- processed-result)))
+ (let ((lex-result
+ (phps-mode-lex-analyzer--lex-string buffer-contents))
+ (parse-trail))
+
+ ;; Prepare parser
+ (setq
+ phps-mode-lex-analyzer--parse-trail
+ nil)
+ (setq
+ phps-mode-lex-analyzer--parse-error
+ nil)
+ (setq
+ phps-mode-parser-tokens
+ (nth 0 lex-result))
+
+ (condition-case conditions
+ (progn
+ (setq
+ parse-trail
+ (phps-mode-parser-parse)))
+ (error
+ (signal
+ 'phps-parser-error
+ conditions)))
+
+ (let ((processed-result
+ (phps-mode-lex-analyzer--process-tokens-in-string
+ (nth 0 lex-result)
+ buffer-contents)))
+ (list
+ lex-result
+ processed-result
+ parse-trail))))
(lambda(result)
(when (get-buffer buffer-name)
@@ -413,27 +436,6 @@
(setq phps-mode-lex-analyzer--heredoc-label-stack (nth 5
lex-result))
(setq phps-mode-lex-analyzer--nest-location-stack (nth 6
lex-result))
- ;; TODO Synchronous parse here?
- (setq phps-mode-lex-analyzer--parse-trail nil)
- (setq phps-mode-lex-analyzer--parse-error nil)
- (setq phps-mode-parser-tokens phps-mode-lex-analyzer--tokens)
- (condition-case conditions
- (progn
- (setq
- phps-mode-lex-analyzer--parse-trail
- (phps-mode-parser-parse)))
- (error
- (message "GOT ERROR 2: %S" conditions)
- (setq
- phps-mode-lex-analyzer--parse-error
- conditions)))
- ;; (when phps-mode-lex-analyzer--parse-error
- ;; (display-warning
- ;; 'phps-mode
- ;; phps-mode-lex-analyzer--parse-error
- ;; :warning
- ;; "*PHPs Parse Errors*"))
-
;; Save processed result
(setq phps-mode-lex-analyzer--processed-buffer-p t)
(setq phps-mode-lex-analyzer--imenu (nth 0 processed-result))
@@ -461,27 +463,45 @@
(phps-mode-lex-analyzer--reset-local-variables)
(when error-message
- (if (equal error-type 'phps-lexer-error)
- (progn
- (when error-start
- (if error-end
- (phps-mode-lex-analyzer--set-region-syntax-color
- error-start
- error-end
- (list 'font-lock-face 'font-lock-warning-face))
- (phps-mode-lex-analyzer--set-region-syntax-color
- error-start
- (point-max)
- (list 'font-lock-face 'font-lock-warning-face))))
- (display-warning
- 'phps-mode
- error-message
- :warning
- "*PHPs Lexer Errors*"))
+ (cond
+
+ ((equal error-type 'phps-lexer-error)
+ (when error-start
+ (if error-end
+ (phps-mode-lex-analyzer--set-region-syntax-color
+ error-start
+ error-end
+ (list 'font-lock-face 'font-lock-warning-face))
+ (phps-mode-lex-analyzer--set-region-syntax-color
+ error-start
+ (point-max)
+ (list 'font-lock-face 'font-lock-warning-face))))
+ (display-warning
+ 'phps-mode
+ error-message
+ :warning
+ "*PHPs Lexer Errors*"))
+
+ ((equal error-type 'phps-parser-error)
+ (phps-mode-lex-analyzer--set-region-syntax-color
+ (nth 5 result)
+ (point-max)
+ (list 'font-lock-face 'font-lock-warning-face))
+ (display-warning
+ 'phps-mode
+ (nth 2 result)
+ :warning
+ "*PHPs Parser Errors*"))
+
+ (t
(display-warning
error-type
error-message
- :warning)))))))
+ :warning))
+
+ )
+
+ )))))
nil
@@ -503,24 +523,49 @@
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
- incremental-nest-location-stack
- head-tokens))
- (processed-result
- (phps-mode-lex-analyzer--process-tokens-in-string
- (nth 0 lex-result)
- buffer-contents)))
- ;; TODO Async parse here?
- (list lex-result processed-result)))
+ (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))
+ (parse-trail))
+
+ ;; Prepare parser
+ (setq
+ phps-mode-lex-analyzer--parse-trail
+ nil)
+ (setq
+ phps-mode-lex-analyzer--parse-error
+ nil)
+ (setq
+ phps-mode-parser-tokens
+ (nth 0 lex-result))
+
+ (condition-case conditions
+ (progn
+ (setq
+ parse-trail
+ (phps-mode-parser-parse)))
+ (error
+ (signal
+ 'phps-parser-error
+ conditions)))
+
+ (let ((processed-result
+ (phps-mode-lex-analyzer--process-tokens-in-string
+ (nth 0 lex-result)
+ buffer-contents)))
+ (list
+ lex-result
+ processed-result
+ parse-trail))))
(lambda(result)
(when (get-buffer buffer-name)
@@ -539,27 +584,6 @@
(setq phps-mode-lex-analyzer--heredoc-label-stack (nth 5
lex-result))
(setq phps-mode-lex-analyzer--nest-location-stack (nth 6
lex-result))
- ;; TODO Synchronous parse here?
- (setq phps-mode-lex-analyzer--parse-trail nil)
- (setq phps-mode-lex-analyzer--parse-error nil)
- (setq phps-mode-parser-tokens phps-mode-lex-analyzer--tokens)
- (condition-case conditions
- (progn
- (setq
- phps-mode-lex-analyzer--parse-trail
- (phps-mode-parser-parse)))
- (error
- (message "GOT ERROR 1: %S" conditions)
- (setq
- phps-mode-lex-analyzer--parse-error
- conditions)))
- ;; (when phps-mode-lex-analyzer--parse-error
- ;; (display-warning
- ;; 'phps-mode
- ;; phps-mode-lex-analyzer--parse-error
- ;; :warning
- ;; "*PHPs Parse Errors*"))
-
;; Save processed result
(setq phps-mode-lex-analyzer--processed-buffer-p t)
(setq phps-mode-lex-analyzer--imenu (nth 0 processed-result))
@@ -592,27 +616,41 @@
(phps-mode-lex-analyzer--reset-local-variables)
(when error-message
- (if (equal error-type 'phps-lexer-error)
- (progn
- (when error-start
- (if error-end
- (phps-mode-lex-analyzer--set-region-syntax-color
- error-start
- error-end
- (list 'font-lock-face 'font-lock-warning-face))
- (phps-mode-lex-analyzer--set-region-syntax-color
- error-start
- (point-max)
- (list 'font-lock-face 'font-lock-warning-face))))
- (display-warning
- 'phps-mode
- error-message
- :warning
- "*PHPs Lexer Errors*"))
+ (cond
+
+ ((equal error-type 'phps-lexer-error)
+ (when error-start
+ (if error-end
+ (phps-mode-lex-analyzer--set-region-syntax-color
+ error-start
+ error-end
+ (list 'font-lock-face 'font-lock-warning-face))
+ (phps-mode-lex-analyzer--set-region-syntax-color
+ error-start
+ (point-max)
+ (list 'font-lock-face 'font-lock-warning-face))))
+ (display-warning
+ 'phps-mode
+ error-message
+ :warning
+ "*PHPs Lexer Errors*"))
+
+ ((equal error-type 'phps-parser-error)
+ (phps-mode-lex-analyzer--set-region-syntax-color
+ (nth 5 result)
+ (point-max)
+ (list 'font-lock-face 'font-lock-warning-face))
+ (display-warning
+ 'phps-mode
+ (nth 2 result)
+ :warning
+ "*PHPs Parser Errors*"))
+
+ (t
(display-warning
error-type
error-message
- :warning)))))))
+ :warning))))))))
nil
async
diff --git a/phps-mode-parser.el b/phps-mode-parser.el
index 2c9739a..fee65b1 100644
--- a/phps-mode-parser.el
+++ b/phps-mode-parser.el
@@ -17,6 +17,10 @@
nil
"Tokens for parser.")
+(define-error
+ 'phps-parser-error
+ "PHPs Lexer Error")
+
;;; Constants:
@@ -543,12 +547,17 @@
(unless action-match
;; (c) If f(u) = error, we halt parsing (and, in practice
;; transfer to an error recovery routine).
- (error
- "Invalid syntax! Expected one of %s found %s at %s"
-
- possible-look-aheads
- look-ahead
- phps-mode-parser-lex-analyzer--index))
+ (signal
+ 'error
+ (list
+ (format
+ "Invalid syntax! Expected one of %s found %s at %s"
+ possible-look-aheads
+ look-ahead
+ phps-mode-parser-lex-analyzer--index)
+ possible-look-aheads
+ look-ahead
+ phps-mode-parser-lex-analyzer--index)))
(cond
diff --git a/test/phps-mode-test-lexer.el b/test/phps-mode-test-lexer.el
index 2254bdc..9a48959 100644
--- a/test/phps-mode-test-lexer.el
+++ b/test/phps-mode-test-lexer.el
@@ -33,12 +33,12 @@
"Run test for lexer."
(phps-mode-test--with-buffer
- "<?php\t$öar=1; exit $var;\t?>"
+ "<?php\t$öar=1; exit;\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)
(T_CLOSE_TAG 26 . 28)))))
+ '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 11) ("=" 11 . 12) (T_LNUMBER 12 .
13) (";" 13 . 14) (T_EXIT 15 . 19) (";" 19 . 20) (T_CLOSE_TAG 21 . 23)))))
(phps-mode-test--with-buffer
"<?php\nexit;\n?>"
@@ -65,20 +65,21 @@
'((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 ?>"
+ "\n\n \t<html><title>echo \"Blahs\";</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)
(T_CLOSE_TAG 51 . 53) (T_INLINE_HTML 53 . 78) (T_OPEN_TAG 78 . 84) (T_EXIT 84 .
88) (T_CLOSE_TAG 89 . 91)))))
+ '((T_INLINE_HTML 1 . 39) (T_OPEN_TAG 39 . 45) (T_EXIT 47 . 51) (";" 51 .
52) (T_CLOSE_TAG 53 . 55) (T_INLINE_HTML 55 . 80) (T_OPEN_TAG 80 . 86) (T_EXIT
86 . 90) (";" 90 . 91) (T_CLOSE_TAG 92 . 94)))))
- (phps-mode-test--with-buffer
- "<?php\n\n$k = 'key';\n\necho \"\\$a['{$k}']\";"
- "A tricky case where variable inside double quote is escaped"
- ;; (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_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)))))
+ ;; TODO Make parser handle this
+ ;; (phps-mode-test--with-buffer
+ ;; "<?php\n\n$k = 'key';\n\necho \"\\$a['{$k}']\";"
+ ;; "A tricky case where variable inside double quote is escaped"
+ ;; ;; (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_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)))))
)
@@ -192,12 +193,12 @@
'((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)"
+ "<?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)))))
+ '((T_OPEN_TAG 1 . 7) (T_STRING 7 . 18) ("(" 18 . 19) (T_VARIABLE 19 . 24)
("," 24 . 25) (T_VARIABLE 26 . 31) (")" 31 . 32) (";" 32 . 33)))))
(phps-mode-test--with-buffer
"<?php\n$username = $_GET['user'] ??
'nobody';\n$this->request->data['comments']['user_id'] ??= 'value';\n"
@@ -208,14 +209,15 @@
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_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)))))
+ ;; TODO Uncomment when parser handles this
+ ;; (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_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 */"
diff --git a/test/phps-mode-test-parser.el b/test/phps-mode-test-parser.el
index 90451dc..e6d9d11 100644
--- a/test/phps-mode-test-parser.el
+++ b/test/phps-mode-test-parser.el
@@ -254,6 +254,21 @@
(lambda()
(phps-mode-parser-parse)))
+ ;; TODO Make this work
+ (phps-mode-test-parser--buffer-contents
+ "<?php\necho $array['abc'];\necho \"My $array[12] random statement\";\n"
+ "Long inside array offset"
+ (lambda()
+ (phps-mode-parser-parse)))
+
+ ;; TODO Make this work
+ (phps-mode-test-parser--buffer-contents
+ "<?php\n\n$k = 'key';\n\necho \"\\$a['{$k}']\";"
+ "A tricky case where variable inside double quote is escaped"
+ (lambda()
+ (phps-mode-parser-parse)))
+
+
(message "\n-- Ran tests for parser boundaries. --"))
(defun phps-mode-test-parser ()