- Notifications
You must be signed in to change notification settings - Fork 14
error on unmatched closing paren/brace #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| | @@ -71,36 +71,43 @@ OPTIONS is an association list. This list is also passed down to the | |
| REDUCE-BRANCH function. See `parseclj-parser' for more information on | ||
| 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))) | ||
| (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))))) | ||
| (fail-fast (a-get options :fail-fast t))) | ||
| (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) | ||
| | ||
| (let ((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))) | ||
| (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))))))) | ||
| | ||
| (defun parseclj--take-value (stack value-p) | ||
| "Scan STACK until a value is found. | ||
| | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| | @@ -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")) | ||
| ) | ||
| Collaborator There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for adding tests! Contributor Author There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the review | ||
| | ||
| (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 | ||
| ) | ||
| | ||
| | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These let bindings should be aligned as before, if you let Emacs reindent it it should do it correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's due to literal tabs, I'll revert to spaces and set indent-tabs-mode in .dir-locals accordingly