New Upstream Snapshot - parsley-clojure

Ready changes

Summary

Merged new upstream version: 0.9.3+git20180227.1.c5c4783 (was: 0.9.3).

Resulting package

Built on 2022-03-28T07:01 (took 8m31s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-snapshots libparsley-clojure

Lintian Result

Diff

diff --git a/DONTREADME.md b/DONTREADME.md
new file mode 100644
index 0000000..c4eb277
--- /dev/null
+++ b/DONTREADME.md
@@ -0,0 +1,235 @@
+# Parsley
+
+## Parsnip
+
+Parsley has been a test bed and a proof of concept for total incremental parsers. However it suffers from severe limitations (mainly revolving around lookaheads, both at the lexeme and production level) which hinder further development and acceptance.
+
+Further development of the concepts and techniques explored in Parsley will occur in [Parsnip](https://github.com/cgrand/parsnip/).
+
+## Introduction
+
+Parsley generates *total and truly incremental parsers*.
+
+Total: a Parsley parser *yields a parse-tree for any input string*.
+
+Truly incremental: a Parsley parser can operate as a text buffer, in best cases
+recomputing the parse-tree after a sequence of edits happens in *logarithmic 
+time* (worst case: it behaves like a restartable parser).
+
+Parsley parsers have *no separate lexer*, this allows for better compositionality
+of grammars. 
+
+For now Parsley uses the same technique (for lexer-less parsing) as described
+in this paper: 
+Context-Aware Scanning for Parsing Extensible Languages
+http://www.umsec.umn.edu/publications/Context-Aware-Scanning-Parsing-Extensible-Language
+
+(I independently rediscovered this technique and dubbed it LR+.)
+
+Without a separate lexer, a language is entirely defined by its grammar.
+A grammar is an alternation of keywords (non-terminal names) and other values.
+A keyword and another value form a production rule.
+
+
+## Specifying grammars
+
+A simple grammar is:
+
+    :expr #{"x" ["(" :expr* ")"]}
+
+`x` `()` `(xx)` `((x)())` are recognized by this grammar.
+
+By default the main production of a grammar is the first one.
+
+A production right value is a combination of:
+
+* strings and regexes (terminals -- the set of terminal types is broader and
+  even open, more later)
+* keywords (non-terminals) which can be suffixed by `*`, `+` or `?` to denote 
+  repetitions or options.
+* sets to denote an alternative
+* vectors to denote a sequence. Inside vectors `:*`, `:+` and `:?` are postfix unary
+  operators. That is `["ab" :+]` denotes a non-empty repetition of the `ab` 
+  string
+
+A production left value is always a keyword. If this keyword is suffixed by `-`,
+no node will be generated in the parse-tree for this rule, its child nodes are
+inlined in the parent node. Rules with such names are called anonymous rules.
+An anonymous rule must be referred to by its base name (without the `-`).
+
+These two grammars specify the same language but the resulting parse-trees will
+be different (additional `:expr-rep` nodes):
+
+    :expr #{"x" ["(" :expr* ")"]}
+
+    :expr #{"x" :expr-rep}
+    :expr-rep ["(" :expr* ")"]
+
+These two grammars specify the same language and the same parse-trees:
+
+    :expr #{"x" ["(" :expr* ")"]}
+
+    :expr #{"x" :expr-rep}
+    :expr-rep- ["(" :expr* ")"]
+
+## Creating parsers
+
+A parser is created using the `parser` or `make-parser` functions.
+
+    (require '[net.cgrand.parsley :as p])
+    (def p (p/parser :expr #{"x" ["(" :expr* ")"]}))
+    (pprint (p "(x(x))"))
+    
+    {:tag :net.cgrand.parsley/root,
+     :content
+       [{:tag :expr,
+         :content
+           ["("
+            {:tag :expr, :content ["x"]}
+            {:tag :expr, :content ["(" {:tag :expr, :content ["x"]} ")"]}
+            ")"]}]}
+    
+    ; running on malformed input with garbage
+    (pprint (p "a(zldxn(dez)"))
+    
+    {:tag :net.cgrand.parsley/unfinished,
+     :content
+       [{:tag :net.cgrand.parsley/unexpected, :content ["a"]}
+        {:tag :net.cgrand.parsley/unfinished,
+         :content
+           ["("
+            {:tag :net.cgrand.parsley/unexpected, :content ["zld"]}
+            {:tag :expr, :content ["x"]}
+            {:tag :net.cgrand.parsley/unexpected, :content ["n"]}
+            {:tag :expr,
+             :content
+               ["("
+                {:tag :net.cgrand.parsley/unexpected, :content ["dez"]}
+                ")"]}]}]}
+
+ 
+## Creating buffers
+
+Creating a buffer, editing it and getting its resulting parse-tree:
+
+    (-> p p/incremental-buffer (p/edit 0 0 "(") (p/edit 1 0 "(x)") p/parse-tree pprint)
+    
+    {:tag :net.cgrand.parsley/unfinished,
+     :content
+       [{:tag :net.cgrand.parsley/unfinished,
+         :content
+           ["("
+            {:tag :expr, :content ["(" {:tag :expr, :content ["x"]} ")"]}]}]}
+
+Incremental parsing at work:
+  
+    => (def p (p/parser :expr #{"x" "\n" ["(" :expr* ")"]}))
+    #'net.cgrand.parsley/p
+    => (let [line (apply str "\n" (repeat 10 "((x))"))
+             input (str "(" (apply str (repeat 1000 line)) ")")
+             buf (p/incremental-buffer p)
+             buf (p/edit buf 0 0 input)]
+         (time (p/parse-tree buf))
+         (time (p/parse-tree (-> buf (p/edit 2 0 "(") (p/edit 51002 0 ")"))))
+         nil)
+    "Elapsed time: 508.834 msecs"
+    "Elapsed time: 86.038 msecs"
+    nil
+
+Hence, *reparsing the buffer only took a fraction of the original time* despite
+the buffer having been modified at the start and at the end.
+
+## Incremental parsing 
+
+The input string is split into _chunks_ (lines by default) and chunks are always
+reparsed as a whole, so don't experiment with incremental parsing with 1-line
+inputs!
+
+Let's look at a bit more complex example:
+
+    => (def p (p/parser {:main :expr*
+                         :space :ws?
+                         :make-node (fn [tag content] {:tag tag :content content :id (gensym)})}
+                :ws #"\s+"
+                :expr #{#"\w+" ["(" :expr* ")"]}))
+
+This example introduces the option map: if the first arg to `parser` is a map 
+(instead of a keyword), it's a map of options. See Options for more.
+
+The important option here is that we redefine how nodes of the parse-tree are
+constructed (via the `make-node` option). We add a unique identifier to each
+node.
+
+Now let's create a 3-line input and parse it: 
+
+    => (def buf (-> p incremental-buffer (edit 0 0 "((a)\n(b)\n(c))")))
+    => (-> buf parse-tree pprint)
+    nil
+    {:tag :net.cgrand.parsley/root,
+     :content
+       [{:tag :expr,
+         :content
+           ["("
+            {:tag :expr,
+             :content ["(" {:tag :expr, :content ["a"], :id G__1806} ")"],
+             :id G__1807}
+            {:tag :ws, :content ["\n"], :id G__1808}
+            {:tag :expr,
+             :content ["(" {:tag :expr, :content ["b"], :id G__1809} ")"],
+             :id G__1810}
+            {:tag :ws, :content ["\n"], :id G__1811}
+            {:tag :expr,
+             :content ["(" {:tag :expr, :content ["c"], :id G__1812} ")"],
+             :id G__1813}
+            ")"],
+         :id G__1814}],
+     :id G__1815}
+
+Now, let's modify this "B" in "BOO" and parse the buffer again:
+
+    => (-> buf (edit 6 1 "BOO") parse-tree pprint)
+    nil
+    {:tag :net.cgrand.parsley/root,
+     :content
+       [{:tag :expr,
+         :content
+           ["("
+            {:tag :expr,
+             :content ["(" {:tag :expr, :content ["a"], :id G__1806} ")"],
+             :id G__1807}
+            {:tag :ws, :content ["\n"], :id G__1818}
+            {:tag :expr,
+             :content ["(" {:tag :expr, :content ["BOO"], :id G__1819} ")"],
+             :id G__1820}
+            {:tag :ws, :content ["\n"], :id G__1811}
+            {:tag :expr,
+             :content ["(" {:tag :expr, :content ["c"], :id G__1812} ")"],
+             :id G__1813}
+            ")"],
+         :id G__1821}],
+     :id G__1822}
+-----
+
+We can spot that 5 out of the 10 nodes are shared with the previous parse-tree.
+
+
+## Options
+
+`:main` specifies the root production, by default this is the the first 
+production of the grammar.
+
+`:root-tag` specifies the tag name to use for the root node 
+(`:net.cgrand.parsley/root` by default).
+
+`:space` specifies a production which will be interspersed between every symbol
+(terminal or not) *except in a sequence created with `unspaced`.* 
+
+`:make-node` specifies a function whose arglist is `[tag children-vec]` which
+returns a new node. By default create instances the Node record with keys `tag`
+and `content`.
+
+`:make-unexpected` specifies a 1-arg function which converts a string (of 
+unexpected characters) to a node. By defaut delegates to `:make-node`.
+
+`:make-leaf` specifies a 1-arg function which converts a string (token) to a
+node, by default behaves like identity.
diff --git a/README.md b/README.md
index 19357fc..4fccce0 100644
--- a/README.md
+++ b/README.md
@@ -1,235 +1,4 @@
-# Parsley 
+If anyone stumbles here trying to find an incremental parser, here is the 1998 paper ([Efficient and Flexible Incremental Parsing](https://www.researchgate.net/profile/SL_Graham/publication/2377179_Efficient_and_Flexible_Incremental_Parsing/links/004635294e13f23ef1000000/Efficient-and-Flexible-Incremental-Parsing.pdf
+)) that I should have found before embarking in this failed (expectations not met) project.
 
-## Parsnip
-
-Parsley has been a test bed and a proof of concept for total incremental parsers. However it suffers from severe limitations (mainly revolving around lookaheads, both at the lexeme and production level) which hinder further development and acceptance.
-
-Further development of the concepts and techniques explored in Parsley will occur in [Parsnip](https://github.com/cgrand/parsnip/).
-
-## Introduction
-
-Parsley generates *total and truly incremental parsers*.
-
-Total: a Parsley parser *yields a parse-tree for any input string*.
-
-Truly incremental: a Parsley parser can operate as a text buffer, in best cases
-recomputing the parse-tree after a sequence of edits happens in *logarithmic 
-time* (worst case: it behaves like a restartable parser).
-
-Parsley parsers have *no separate lexer*, this allows for better compositionality
-of grammars. 
-
-For now Parsley uses the same technique (for lexer-less parsing) as described
-in this paper: 
-Context-Aware Scanning for Parsing Extensible Languages
-http://www.umsec.umn.edu/publications/Context-Aware-Scanning-Parsing-Extensible-Language
-
-(I independently rediscovered this technique and dubbed it LR+.)
-
-Without a separate lexer, a language is entirely defined by its grammar.
-A grammar is an alternation of keywords (non-terminal names) and other values.
-A keyword and another value form a production rule.
-
-
-## Specifying grammars
-
-A simple grammar is:
-
-    :expr #{"x" ["(" :expr* ")"]}
-
-`x` `()` `(xx)` `((x)())` are recognized by this grammar.
-
-By default the main production of a grammar is the first one.
-
-A production right value is a combination of:
-
-* strings and regexes (terminals -- the set of terminal types is broader and
-  even open, more later)
-* keywords (non-terminals) which can be suffixed by `*`, `+` or `?` to denote 
-  repetitions or options.
-* sets to denote an alternative
-* vectors to denote a sequence. Inside vectors `:*`, `:+` and `:?` are postfix unary
-  operators. That is `["ab" :+]` denotes a non-empty repetition of the `ab` 
-  string
-
-A production left value is always a keyword. If this keyword is suffixed by `-`,
-no node will be generated in the parse-tree for this rule, its child nodes are
-inlined in the parent node. Rules with such names are called anonymous rules.
-An anonymous rule must be referred to by its base name (without the `-`).
-
-These two grammars specify the same language but the resulting parse-trees will
-be different (additional `:expr-rep` nodes):
-
-    :expr #{"x" ["(" :expr* ")"]}
-
-    :expr #{"x" :expr-rep}
-    :expr-rep ["(" :expr* ")"]
-
-These two grammars specify the same language and the same parse-trees:
-
-    :expr #{"x" ["(" :expr* ")"]}
-
-    :expr #{"x" :expr-rep}
-    :expr-rep- ["(" :expr* ")"]
-
-## Creating parsers
-
-A parser is created using the `parser` or `make-parser` functions.
-
-    (require '[net.cgrand.parsley :as p])
-    (def p (p/parser :expr #{"x" ["(" :expr* ")"]}))
-    (pprint (p "(x(x))"))
-    
-    {:tag :net.cgrand.parsley/root,
-     :content
-       [{:tag :expr,
-         :content
-           ["("
-            {:tag :expr, :content ["x"]}
-            {:tag :expr, :content ["(" {:tag :expr, :content ["x"]} ")"]}
-            ")"]}]}
-    
-    ; running on malformed input with garbage
-    (pprint (p "a(zldxn(dez)"))
-    
-    {:tag :net.cgrand.parsley/unfinished,
-     :content
-       [{:tag :net.cgrand.parsley/unexpected, :content ["a"]}
-        {:tag :net.cgrand.parsley/unfinished,
-         :content
-           ["("
-            {:tag :net.cgrand.parsley/unexpected, :content ["zld"]}
-            {:tag :expr, :content ["x"]}
-            {:tag :net.cgrand.parsley/unexpected, :content ["n"]}
-            {:tag :expr,
-             :content
-               ["("
-                {:tag :net.cgrand.parsley/unexpected, :content ["dez"]}
-                ")"]}]}]}
-
- 
-## Creating buffers
-
-Creating a buffer, editing it and getting its resulting parse-tree:
-
-    (-> p p/incremental-buffer (p/edit 0 0 "(") (p/edit 1 0 "(x)") p/parse-tree pprint)
-    
-    {:tag :net.cgrand.parsley/unfinished,
-     :content
-       [{:tag :net.cgrand.parsley/unfinished,
-         :content
-           ["("
-            {:tag :expr, :content ["(" {:tag :expr, :content ["x"]} ")"]}]}]}
-
-Incremental parsing at work:
-  
-    => (def p (p/parser :expr #{"x" "\n" ["(" :expr* ")"]}))
-    #'net.cgrand.parsley/p
-    => (let [line (apply str "\n" (repeat 10 "((x))"))
-             input (str "(" (apply str (repeat 1000 line)) ")")
-             buf (p/incremental-buffer p)
-             buf (p/edit buf 0 0 input)]
-         (time (p/parse-tree buf))
-         (time (p/parse-tree (-> buf (p/edit 2 0 "(") (p/edit 51002 0 ")"))))
-         nil)
-    "Elapsed time: 508.834 msecs"
-    "Elapsed time: 86.038 msecs"
-    nil
-
-Hence, *reparsing the buffer only took a fraction of the original time* despite
-the buffer having been modified at the start and at the end.
-
-## Incremental parsing 
-
-The input string is split into _chunks_ (lines by default) and chunks are always
-reparsed as a whole, so don't experiment with incremental parsing with 1-line
-inputs!
-
-Let's look at a bit more complex example:
-
-    => (def p (p/parser {:main :expr*
-                         :space :ws?
-                         :make-node (fn [tag content] {:tag tag :content content :id (gensym)})}
-                :ws #"\s+"
-                :expr #{#"\w+" ["(" :expr* ")"]}))
-
-This example introduces the option map: if the first arg to `parser` is a map 
-(instead of a keyword), it's a map of options. See Options for more.
-
-The important option here is that we redefine how nodes of the parse-tree are
-constructed (via the `make-node` option). We add a unique identifier to each
-node.
-
-Now let's create a 3-line input and parse it: 
-
-    => (def buf (-> p incremental-buffer (edit 0 0 "((a)\n(b)\n(c))")))
-    => (-> buf parse-tree pprint)
-    nil
-    {:tag :net.cgrand.parsley/root,
-     :content
-       [{:tag :expr,
-         :content
-           ["("
-            {:tag :expr,
-             :content ["(" {:tag :expr, :content ["a"], :id G__1806} ")"],
-             :id G__1807}
-            {:tag :ws, :content ["\n"], :id G__1808}
-            {:tag :expr,
-             :content ["(" {:tag :expr, :content ["b"], :id G__1809} ")"],
-             :id G__1810}
-            {:tag :ws, :content ["\n"], :id G__1811}
-            {:tag :expr,
-             :content ["(" {:tag :expr, :content ["c"], :id G__1812} ")"],
-             :id G__1813}
-            ")"],
-         :id G__1814}],
-     :id G__1815}
-
-Now, let's modify this "B" in "BOO" and parse the buffer again:
-
-    => (-> buf (edit 6 1 "BOO") parse-tree pprint)
-    nil
-    {:tag :net.cgrand.parsley/root,
-     :content
-       [{:tag :expr,
-         :content
-           ["("
-            {:tag :expr,
-             :content ["(" {:tag :expr, :content ["a"], :id G__1806} ")"],
-             :id G__1807}
-            {:tag :ws, :content ["\n"], :id G__1818}
-            {:tag :expr,
-             :content ["(" {:tag :expr, :content ["BOO"], :id G__1819} ")"],
-             :id G__1820}
-            {:tag :ws, :content ["\n"], :id G__1811}
-            {:tag :expr,
-             :content ["(" {:tag :expr, :content ["c"], :id G__1812} ")"],
-             :id G__1813}
-            ")"],
-         :id G__1821}],
-     :id G__1822}
------
-
-We can spot that 5 out of the 10 nodes are shared with the previous parse-tree.
-
-
-## Options
-
-`:main` specifies the root production, by default this is the the first 
-production of the grammar.
-
-`:root-tag` specifies the tag name to use for the root node 
-(`:net.cgrand.parsley/root` by default).
-
-`:space` specifies a production which will be interspersed between every symbol
-(terminal or not) *except in a sequence created with `unspaced`.* 
-
-`:make-node` specifies a function whose arglist is `[tag children-vec]` which
-returns a new node. By default create instances the Node record with keys `tag`
-and `content`.
-
-`:make-unexpected` specifies a 1-arg function which converts a string (of 
-unexpected characters) to a node. By defaut delegates to `:make-node`.
-
-`:make-leaf` specifies a 1-arg function which converts a string (token) to a
-node, by default behaves like identity.
+If you are still interested in Parsley, go read the old [README](DONTREADME.md)
diff --git a/debian/changelog b/debian/changelog
index dc31e0e..ce23a47 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,9 +1,12 @@
-parsley-clojure (0.9.3-3) UNRELEASED; urgency=normal
+parsley-clojure (0.9.3+git20180227.1.c5c4783-1) UNRELEASED; urgency=normal
 
   [ Louis-Philippe Véronneau ]
   * d/control: New email for the Clojure Team.
 
- -- Louis-Philippe Véronneau <pollo@debian.org>  Sat, 08 Jan 2022 18:33:03 -0500
+  [ Debian Janitor ]
+  * New upstream snapshot.
+
+ -- Louis-Philippe Véronneau <pollo@debian.org>  Mon, 28 Mar 2022 06:57:24 -0000
 
 parsley-clojure (0.9.3-2) unstable; urgency=medium
 

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/share/doc/libparsley-clojure/README.md
-rw-r--r--  root/root   /usr/share/java/parsley-0.9.3+git20180227.1.c5c4783.jar
lrwxrwxrwx  root/root   /usr/share/java/parsley.jar -> parsley-0.9.3+git20180227.1.c5c4783.jar

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/share/doc/libparsley-clojure/README.md.gz
-rw-r--r--  root/root   /usr/share/java/parsley-0.9.3.jar
lrwxrwxrwx  root/root   /usr/share/java/parsley.jar -> parsley-0.9.3.jar

No differences were encountered in the control files

More details

Full run details