Fix five bugs surfaced by commonmark-app (jolt-3xur, dl4s, ik3a, w2wf, xtss) (#158)
* Fix four bugs surfaced by the commonmark-app example
- regex: bounded quantifiers {n,m} no longer expand exponentially. The
desugaring inlined the continuation per optional level, doubling it each
time, so {0,61} built a PEG the compiler expanded to ~2^61 nodes and hung.
Each level is now its own grammar rule referenced by name (jolt-3xur).
- strings are a seqable of chars for vec/set/into, matching seq. They went
through realize-for-iteration, which had no string case, so into/set got
raw bytes (code points) and set threw; vec used string/from-bytes (1-char
strings). realize-for-iteration now maps make-char over the bytes, and
core-vec matches (jolt-dl4s).
- clojure.string/split takes Java Pattern.split limit semantics: negative
keeps trailing empties, 0/omitted drops them (a no-match result stays
[input]), positive caps the part count with the remainder unsplit. It used
to delegate the limit to take, so a negative limit returned [] and the
2-arg form never trimmed trailing empties (jolt-ik3a).
- System/exit is registered (maps to os/exit), so (System/exit n) works
(jolt-w2wf).
* regex: single-digit backreferences \1..\9 (jolt-xtss)
\1..\9 now match the text captured by the corresponding group, so
patterns like ([-*_])\1\1 or (\w+) \1 work. The parser records which
groups are referenced; a referenced group additionally captures its text
under a tag and the backref compiles to a PEG (backmatch). Only referenced
groups change — they match possessively (the CPS-over-possessive-PEG engine
can't backtrack into a tagged capture), so backtracking back into a
backreferenced group isn't supported (rare). Unreferenced groups keep full
backtracking and position-based result capture unchanged.
---------
Co-authored-by: Yogthos <yogthos@gmail.com>
This commit is contained in:
parent
8192fc9541
commit
951a3000e6
9 changed files with 111 additions and 25 deletions
|
|
@ -51,10 +51,16 @@
|
|||
(str-reverse-b s))
|
||||
|
||||
(defn split
|
||||
([s re]
|
||||
(vec (str-split re s)))
|
||||
([s re] (split s re 0))
|
||||
([s re limit]
|
||||
(vec (take limit (str-split re s)))))
|
||||
;; Java Pattern.split semantics: limit > 0 caps the parts (trailing empties
|
||||
;; kept); limit < 0 splits fully and keeps trailing empties; limit 0 (the
|
||||
;; default) splits fully then drops trailing empty strings — but a no-match
|
||||
;; result ([input], the only 1-element case) is returned as-is.
|
||||
(let [parts (vec (str-split re s (if (pos? limit) limit nil)))]
|
||||
(if (and (zero? limit) (> (count parts) 1))
|
||||
(loop [v parts] (if (and (seq v) (= "" (peek v))) (recur (pop v)) v))
|
||||
parts))))
|
||||
|
||||
(defn split-lines
|
||||
"Split s on \\n or \\r\\n, returning a vector of lines."
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue