branch: elpa/parseclj
commit eff941126859bc9e949eae5cd6c2592e731629f2
Merge: b34d3e13a2 9e0b51e39c
Author: Arne Brasseur <[email protected]>
Commit: GitHub <[email protected]>
Merge pull request #26 from ikappaki/master
error on unmatched closing paren/brace
---
.dir-locals.el | 1 +
parseclj-parser.el | 62 +++++++++++++++++++++++++++++----------------------
test/parseclj-test.el | 30 ++++++++++++++++++++++++-
3 files changed, 65 insertions(+), 28 deletions(-)
diff --git a/.dir-locals.el b/.dir-locals.el
index ab85ded9a1..c45357d77a 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -1,5 +1,6 @@
((emacs-lisp-mode
(buffer-save-without-query . t)
+ (indent-tabs-mode . nil)
(eval . (flycheck-mode))
(eval . (checkdoc-minor-mode))
(sentence-end-double-space . t)
diff --git a/parseclj-parser.el b/parseclj-parser.el
index d0e5d24a21..fe3bb3c818 100644
--- a/parseclj-parser.el
+++ b/parseclj-parser.el
@@ -73,34 +73,42 @@ available options."
(let ((opening-token-type (parseclj--find-opening-token stack closing-token))
(fail-fast (a-get options :fail-fast t))
(collection nil))
-
- ;; unwind the stack until opening-token-type is found, adding to collection
- (while (and stack (not (eq (parseclj-lex-token-type (car stack))
opening-token-type)))
- (push (pop stack) collection))
-
- ;; did we find the right token?
- (if (eq (parseclj-lex-token-type (car stack)) opening-token-type)
- (progn
- (when fail-fast
- ;; any unreduced tokens left: bail early
- (when-let ((token (seq-find #'parseclj-lex-token-p collection)))
+ (if (not opening-token-type)
+ (if fail-fast
+ (parseclj--error "At position %s, unmatched %S"
+ (a-get closing-token :pos)
+ (parseclj-lex-token-type closing-token))
+
+ stack)
+
+ (progn
+ ;; unwind the stack until opening-token-type is found, adding to
collection
+ (while (and stack (not (eq (parseclj-lex-token-type (car stack))
opening-token-type)))
+ (push (pop stack) collection))
+
+ ;; did we find the right token?
+ (if (eq (parseclj-lex-token-type (car stack)) opening-token-type)
+ (progn
+ (when fail-fast
+ ;; any unreduced tokens left: bail early
+ (when-let ((token (seq-find #'parseclj-lex-token-p
collection)))
+ (parseclj--error "At position %s, unmatched %S"
+ (a-get token :pos)
+ (parseclj-lex-token-type token))))
+
+ ;; all good, call the reducer so it can return an updated stack
with a
+ ;; new node at the top.
+ (let ((opening-token (pop stack)))
+ (funcall reduce-branch stack opening-token collection
options)))
+
+ ;; Unwound the stack without finding a matching paren: either bail
early
+ ;; or return the original stack and continue parsing
+ (if fail-fast
(parseclj--error "At position %s, unmatched %S"
- (a-get token :pos)
- (parseclj-lex-token-type token))))
-
- ;; all good, call the reducer so it can return an updated stack with
a
- ;; new node at the top.
- (let ((opening-token (pop stack)))
- (funcall reduce-branch stack opening-token collection options)))
-
- ;; Unwound the stack without finding a matching paren: either bail early
- ;; or return the original stack and continue parsing
- (if fail-fast
- (parseclj--error "At position %s, unmatched %S"
- (a-get closing-token :pos)
- (parseclj-lex-token-type closing-token))
-
- (reverse collection)))))
+ (a-get closing-token :pos)
+ (parseclj-lex-token-type closing-token))
+
+ (reverse collection)))))))
(defun parseclj--take-value (stack value-p)
"Scan STACK until a value is found.
diff --git a/test/parseclj-test.el b/test/parseclj-test.el
index a60ad9407a..a2c92e5fc2 100644
--- a/test/parseclj-test.el
+++ b/test/parseclj-test.el
@@ -93,7 +93,20 @@
(condition-case errdata
(parseclj-parse-clojure "(1 [2 {3 ( 4}])")
(parseclj-parser-error (cadr errdata)))
- "At position 10, unmatched :lparen")))
+ "At position 10, unmatched :lparen"))
+
+ (should (equal
+ (condition-case errdata
+ (parseclj-parse-clojure "{:a 1}}")
+ (parseclj-parser-error (cadr errdata)))
+ "At position 7, unmatched :rbrace"))
+
+ (should (equal
+ (condition-case errdata
+ (parseclj-parse-clojure "'(1))")
+ (parseclj-parser-error (cadr errdata)))
+ "At position 5, unmatched :rparen"))
+ )
(ert-deftest parseclj-parse-clojure-not-fail-fast-test ()
(should (equal (parseclj-parse-clojure "(1 [2 {3 ( 4}])" :fail-fast nil)
@@ -117,6 +130,21 @@
((:token-type . :lparen) (:form . "(") (:pos . 10))
((:node-type
. :number) (:position . 12) (:form . "4") (:value . 4))))))))))))
+ (should (equal
+ (parseclj-parse-clojure "{:a 1}}" :fail-fast nil)
+ '((:node-type . :root)
+ (:position . 1)
+ (:children ((:node-type . :map)
+ (:position . 1)
+ (:children ((:node-type . :keyword)
+ (:position . 2)
+ (:form . ":a")
+ (:value . :a))
+ ((:node-type . :number)
+ (:position . 5)
+ (:form . "1")
+ (:value . 1))))))))
+
;; TODO: uneven map forms
)