While Instaparse is (IMHO) the best parser for use with Clojure, you don't have to start from such a low level (i.e. parsing a char stream text file). Just re-write your original problem a little and you can skip writing a custom parser.
In Clojure, perhaps the most popular format (certainly the tersest format) is Hiccup <https://github.com/weavejester/hiccup>. It is written as a series of nested vectors, where the *tag* is the first item and any *attributes* are in a map that is the 2nd item. We choose the keyword *:value* to label anything on the right of the equals sign in your original data. You thus end up with this: (def ast-hiccup [:HeaderRule {:value :hr-ftp} [:Term {:value 100} [:name {:value "ftp"}] [:From {:value 1} [:networkPort {:value "21"}] [:Protocol {:value 1} [:Tcp {:value 1}]]] [:Then {:value 1} [:ProtocolInspection {:value 1} [:ftpRuleSet {:value "frs-ftp"}]] [:ServiceDataFlowId {:value 1} [:payload {:value 99}]]]]] ) Using the tupelo.forest library <http://cloojure.github.io/doc/tupelo/tupelo.forest.html>, we can easily parse this tree of data and then issue queries on it: (ns tst.demo.core (:use demo.core tupelo.test) (:require [tupelo.core :as t] [tupelo.forest :as tf] )) (t/refer-tupelo) (dotest (tf/with-forest (tf/new-forest) (let [root-hid (tf/add-tree-hiccup ast-hiccup) tree-1 (tf/hid->tree root-hid) bush-1 (tf/hid->bush root-hid) >> (spyx-pretty bush-1) ; print the AST in "bush" format (similar to hiccup) networkPort-hid (tf/find-hid root-hid [:** :From :networkPort]) ; find the :networkPort node networkPort-value (spyx (grab :value (tf/hid->node networkPort-hid))) ; extract the :value from it ] (is= bush-1 [{:value :hr-ftp, :tag :HeaderRule} [{:value 100, :tag :Term} [{:value "ftp", :tag :name}] [{:value 1, :tag :From} [{:value "21", :tag :networkPort}] [{:value 1, :tag :Protocol} [{:value 1, :tag :Tcp}]]] [{:value 1, :tag :Then} [{:value 1, :tag :ProtocolInspection} [{:value "frs-ftp", :tag :ftpRuleSet}]] [{:value 1, :tag :ServiceDataFlowId} [{:value 99, :tag :payload}]]]]] ) (is= networkPort-value "21")))) ; verify we found the value "21" For more examples please see the forest-examples.cljc file <https://github.com/cloojure/tupelo/blob/master/test/tst/tupelo/forest_examples.cljc> and the API docs <http://cloojure.github.io/doc/tupelo/tupelo.forest.html>. More documentation forthcoming. Enjoy! Alan On Tue, Aug 15, 2017 at 7:11 PM, dennis zhuang <killme2...@gmail.com> wrote: > In my experience, instaparse + defun is a good choice. > > https://github.com/Engelberg/instaparse > https://github.com/killme2008/defun/ > > 2017-08-15 22:02 GMT+08:00 Gary Trakhman <gary.trakh...@gmail.com>: > >> I enjoyed working with clj-antlr recently, it's a wrapper over a java >> library, but gives you a fast feedback loop with an interpreter instead of >> generated java code. The 'clojurey' part is that the output is a nested >> sequence, from there it's really effective to use tree zippers and >> core.match to transform the parse-tree into the data structure you need. >> >> Take a look at: >> https://github.com/clojure/core.match >> https://github.com/aphyr/clj-antlr >> https://www.ibm.com/developerworks/library/j-treevisit/ >> https://github.com/akhudek/zip-visit >> >> On Tue, Aug 15, 2017 at 9:56 AM Laurens Van Houtven <_...@lvh.cc> wrote: >> >>> Hi, >>> >>> >>> Instaparse is a great parser generator, especially if you already have a >>> BNF. >>> >>> Sent from my iPhone >>> >>> On Aug 15, 2017, at 08:44, sventrax...@gmail.com wrote: >>> >>> Thanks for your input. LFE is quite an unexpected "thing". >>> >>> What I'm trying to do, is just a "lunch time project"; something that I >>> can target without corporate constrains just as a learning exercise. >>> Furthermore I can test the Clojure version against my old working Java >>> version. >>> >>> As I was saying, while experimenting with Instaparse, I'm having the >>> feeling it is not the correct Clojure tool for this type of development >>> >>> >>> >>> On Tuesday, August 15, 2017 at 2:17:50 PM UTC+1, adrians wrote: >>>> >>>> If you need the features of Erlang but would like that in a Lisp (not >>>> Common Lisp, though) environment, have you taken a look at LFE (Lisp >>>> Flavored Erlang)? I'm not trying to discourage you from looking at Clojure, >>>> but if you need/depend on some of the features of Erlang, LFE might be a >>>> closer fit. >>>> >>>> http://lfe.io >>>> >>>> On Tuesday, August 15, 2017 at 8:11:53 AM UTC-4, svent...@gmail.com >>>> wrote: >>>>> >>>>> >>>>> Hi >>>>> >>>>> Months ago I read a review that praised Clojure's clean approach and >>>>> use of JVM that is almost always available in my deployments. >>>>> >>>>> My background: started with 370 assembly ( so I'm not young!!!) and >>>>> during the last four years I've been using Erlang for network >>>>> applications. >>>>> For my type of work the functional approach, concurrency and bit handling >>>>> of Erlang are life savings. Nonetheless I feel "the call" of Clojure. As >>>>> an >>>>> exercise I would like to re implement something I did years ago in Java, >>>>> i.e. a sort of parser. What I have on my hands is a DSL like this >>>>> >>>>> HeaderRule=hr-ftp >>>>> Term=100 >>>>> name="ftp" >>>>> From=1 >>>>> networkPort="21" >>>>> Protocol=1 >>>>> Tcp=1 >>>>> up >>>>> up >>>>> up >>>>> Then=1 >>>>> ProtocolInspection=1 >>>>> ftpRuleSet="frs-ftp" >>>>> up >>>>> ServiceDataFlowId=1 >>>>> payload=99 >>>>> up >>>>> up >>>>> up >>>>> up >>>>> HeaderRule=hr-http >>>>> ...... >>>>> >>>>> For my old Java implementation I used state machines to build an >>>>> internal representation, sort of an AST, that would be used to analyze >>>>> pcap >>>>> files. In my Clojure challenge, I would like to have a different approach. >>>>> Googling around I've found many options: Parsley, Instaparse, cljcc and >>>>> more. Some mentioned on www.clojure-toolbox.com seem to be more >>>>> abandonware. >>>>> At the moment I'm focusing on Instaparse. However, maybe due to the >>>>> previous implementation, I feel that this is not the best approach with >>>>> Clojure. Certainly my rookie state is leading me the wrong way. >>>>> >>>>> Comments and feedback will be greatly appreciated >>>>> >>>>> Fred >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clojure@googlegroups.com >>> Note that posts from new members are moderated - please be patient with >>> your first post. >>> To unsubscribe from this group, send email to >>> clojure+unsubscr...@googlegroups.com >>> For more options, visit this group at >>> http://groups.google.com/group/clojure?hl=en >>> --- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to clojure+unsubscr...@googlegroups.com. >>> For more options, visit https://groups.google.com/d/optout. >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clojure@googlegroups.com >>> Note that posts from new members are moderated - please be patient with >>> your first post. >>> To unsubscribe from this group, send email to >>> clojure+unsubscr...@googlegroups.com >>> For more options, visit this group at >>> http://groups.google.com/group/clojure?hl=en >>> --- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to clojure+unsubscr...@googlegroups.com. >>> For more options, visit https://groups.google.com/d/optout. >>> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > > > > -- > 庄晓丹 > Email: killme2...@gmail.com > Site: http://fnil.net > > 不学习,毋宁死 > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.