diff --git a/src/instaparse/gll.clj b/src/instaparse/gll.clj index a95bea8..d8dbe45 100644 --- a/src/instaparse/gll.clj +++ b/src/instaparse/gll.clj @@ -538,30 +538,34 @@ ; The fifth kind of listener is a RepListener, which wants between m and n repetitions of a parser -(defn RepListener [results-so-far parser m n prev-index node-key tramp] - (fn [result] - (let [{parsed-result :result continue-index :index} result] +(defn RepListener [results-so-far n-results-so-far parser m n prev-index node-key tramp] + (fn [result] + (let [{parsed-result :result continue-index :index} result] ;(dprintln "Rep" (type results-so-far)) - (let [new-results-so-far (afs/conj-flat results-so-far parsed-result)] - (when (<= m (count new-results-so-far) n) + (let [new-results-so-far (afs/conj-flat results-so-far parsed-result) + new-n-results-so-far (inc n-results-so-far)] + (when (<= m new-n-results-so-far n) (success tramp node-key new-results-so-far continue-index)) - (when (< (count new-results-so-far) n) + (when (< new-n-results-so-far n) (push-listener tramp [continue-index parser] - (RepListener new-results-so-far parser m n continue-index - node-key tramp))))))) + (RepListener new-results-so-far new-n-results-so-far + parser m n continue-index + node-key tramp))))))) -(defn RepFullListener [results-so-far parser m n prev-index node-key tramp] +(defn RepFullListener [results-so-far n-results-so-far parser m n prev-index node-key tramp] (fn [result] (let [{parsed-result :result continue-index :index} result] ;(dprintln "RepFull" (type parsed-result)) - (let [new-results-so-far (afs/conj-flat results-so-far parsed-result)] + (let [new-results-so-far (afs/conj-flat results-so-far parsed-result) + new-n-results-so-far (inc n-results-so-far)] (if (= continue-index (count (:text tramp))) - (when (<= m (count new-results-so-far) n) + (when (<= m new-n-results-so-far n) (success tramp node-key new-results-so-far continue-index)) - (when (< (count new-results-so-far) n) + (when (< new-n-results-so-far n) (push-listener tramp [continue-index parser] - (RepFullListener new-results-so-far parser m n continue-index - node-key tramp)))))))) + (RepFullListener new-results-so-far new-n-results-so-far + parser m n continue-index + node-key tramp)))))))) ; The top level listener is the final kind of listener @@ -725,9 +729,9 @@ (success tramp [index this] nil index) (when (>= n 1) (push-listener tramp [index parser] - (RepListener empty-cat-result parser 1 n index [index this] tramp)))) + (RepListener empty-cat-result 0 parser 1 n index [index this] tramp)))) (push-listener tramp [index parser] - (RepListener empty-cat-result parser m n index [index this] tramp))))) + (RepListener empty-cat-result 0 parser m n index [index this] tramp))))) (defn rep-full-parse [this index tramp] @@ -739,9 +743,9 @@ (success tramp [index this] nil index) (when (>= n 1) (push-listener tramp [index parser] - (RepFullListener empty-cat-result parser 1 n index [index this] tramp)))) + (RepFullListener empty-cat-result 0 parser 1 n index [index this] tramp)))) (push-listener tramp [index parser] - (RepFullListener empty-cat-result parser m n index [index this] tramp))))) + (RepFullListener empty-cat-result 0 parser m n index [index this] tramp))))) (defn star-parse [this index tramp] diff --git a/test/instaparse/abnf_test.clj b/test/instaparse/abnf_test.clj index 3d0055a..fc10a7e 100644 --- a/test/instaparse/abnf_test.clj +++ b/test/instaparse/abnf_test.clj @@ -101,25 +101,28 @@ to test the lookahead" (def reps "Testing the different kinds of repetitions" (parser - "S = A B C D E + "S = A B C D E FG A = *'a' B = 2*'b' C = *2'c' D = 2'd' - E = 2*4'e'" + E = 2*4'e' + FG = 2('f' 'g')" :input-format :abnf)) (deftest rep-test (are [x] (not (instance? instaparse.gll.Failure x)) - (reps "aabbccddee") - (reps "bbbbbbddeeee") - (reps "bbcddee"))) + (reps "aabbccddeefgfg") + (reps "bbbbbbddeeeefgfg") + (reps "bbcddeefgfg"))) (deftest rep-test-errors (are [x] (instance? instaparse.gll.Failure x) (reps "") - (reps "bccddee") - (reps "aaaabbbbcccddee"))) + (reps "bccddeefgfg") + (reps "aaaabbbbcccddeefgfg") + (reps "aabbccddeefg") + (reps "aabbccddeeffgg"))) (def regex-chars "Testing %d42-91. The boundary chars are \"*\" and \"[\", which normally aren't allowed in a regex."