From: Ludovic Brenta <ludovic@ludovic-brenta.org>
Subject: Re: S-expression I/O in Ada
Date: Thu, 12 Aug 2010 05:46:52 -0700 (PDT)
Date: 2010-08-12T05:46:52-07:00 [thread overview]
Message-ID: <0cff56bc-32fc-44fe-9e29-9387a4eb4588@l14g2000yql.googlegroups.com> (raw)
In-Reply-To: 6a5068d7-b774-4c52-8b00-ddcc76865847@p7g2000yqa.googlegroups.com
Natacha Kerensikova wrote on comp.lang.ada:
> On Aug 12, 12:55 pm, Ludovic Brenta <ludo...@ludovic-brenta.org>
> wrote:
>
>> Natacha Kerensikova wrote on comp.lang.ada:
>> [...]
>
>>> Sexp_Stream is supposed to perform S-expression I/O over streams,
>>> without ever constructing a S-expression into memory. It is supposed
>>> to do only the encoding and decoding of S-expression format, to expose
>>> its clients only atoms and relations.
>
>> But how can it expose atoms and relations without an in-memory tree
>> representation? Honestly, I do not think that such a concept is
>> viable.
[...]
> The reading part is a bit more tricky, and I admitted when I proposed
> Sexp_Stream I didn't know how to make it. Having thought (maybe too
> much) since then, here is what the interface might look like:
>
> type Node_Type is (S_None, S_List, S_Atom);
>
> function Current_Node_Type(sstream: in Sexp_Stream) return Atom_Type;
>
> procedure Get_Atom(sstream: in Sexp_Stream, contents: out
> octet_array);
> -- raises an exception when Current_Node_Type is not S_Atom
> -- not sure "out octet_array" works, but that's the idea
> -- maybe turn it into a function for easier atom-to-object
> conversion
>
> procedure Move_Next(sstream: in out Sexp_Stream);
> -- when the client is finished with the current node, it calls this
> -- procedure to update stream internal state to reflect the next
> node in
> -- list
>
> procedure Move_Lower(sstream: in out Sexp_Stream);
> -- raises an exception when Current_Node_Type is not S_List
> -- update the internal state to reflect the first child of the
> current list
>
> procedure Move_Upper(sstream: in out Sexp_Stream);
> -- update the internal state to reflect the node following the list
> -- containing the current node. sortof "uncle" node
> -- the implementation is roughly skipping whatever nodes exist in
> the
> -- current list until reading its ')' and reading the following node
>
> Such an interface support data streams, i.e. reading new data without
> seek or pushback. The data would probably be read octet-by-octet
> (unless reading a verbatim encoded atom), hoping for an efficient
> buffering in the underlying stream. If that's a problem I guess some
> buffering can be transparently implemented in the private part of
> Sexp_Stream.
>
> Of course atoms are to be kept in memory, which means Sexp_Stream will
> have to contain a dynamic array (Vector in Ada terminology, right?)
> populated from the underlying stream until the atom is completely
> read. Get_Atom would hand over a (static) array built from the private
> dynamic array.
>
> The implementation would for example rely on a procedure to advance
> the underlying to the next node (i.e. skipping white space), and from
> the first character know whether it's the beginning of a new list
> (when '(' is encountered) and update the state to S_List, and it's
> finished; whether it's the end of the list (when ')' is encountered)
> and update the state to S_None; or whether it's the beginning of an
> atom, so read it completely, updating the internal dynamic array and
> setting the state to S_Atom.
>
> Well actually, it's probably not the best idea, I'm not yet clear
> enough on the specifications and on stream I/O to clearly think about
> implementation, but that should be enough to make you understand the
> idea of S-expression reading without S-expression objects.
>
> Now regarding the actual use of this interface, I think my previous
> writing example is enough, so here is the reading part.
>
> My usual way of reading S-expression configuration file is to read
> sequentially, one at a time, a list whose first element is an atom.
> Atoms, empty lists and lists beginning with a list are considered as
> comments and silently dropped. "(tcp-connect …)" is meant to be one of
> these, processed by TCP_Info's client, which will hand over only the
> "…" part to TCP_Info.Read (or other initialization subprogram). So
> just like TCP_Info's client processes something like "(what-ever-
> config …) (tcp-connect …) (other-config …)", TCP_Info.Read will
> process only "(host foo.example) (port 80)".
>
> So TCP_Info's client, after having read "tcp-connect" atom, will call
> Move_Next on the Sexp_Stream and pass it to TCP_Info.Read. Then
> TCP_Info.Read proceeds with:
>
> loop
> case Current_Atom_Type(sstream) is
> when S_None => return; -- TCP_Info configuration is over
> when S_Atom => null; -- silent atom drop
> when S_List =>
> Move_Lower(sstream);
> Get_Atom(sstream, atom);
> -- make command of type String from atom
> -- if Get_Atom was successful
> Move_Next(sstream);
> if command = "host" then
> -- Get_Atom and turn it into host string
> elif command = "port" then
> -- Get_Atom and turn it into port number
> else
> -- complain about unrecognized command
> end if;
> Move_Upper(sstream);
> end case;
> end loop;
>
> TCP_Info's client S-expression parsing would be very similar, except
> if command = … would be followed by a call to TCP_Info.Read rather
> than a Get_Atom.
>
> So where are the problems with my Sexp_Stream without in memory
> object? What am I missing?
The "problem" is that, without admitting it, you have reintroduced a
full S-Expression parser. Most of it is hidden in the Sexp_Stream
implementation, but it has to be there. Otherwise, how can the
Move_Lower, Advance, and Move_Upper operations work, keeping track of
how many levels deep you are at all times?
Note also that your TCP_Info.Read looks quite similar to mine, except
that mine takes an S-Expression as the input, rather than a stream.
Afterwards, it traverses the S-Expression using pretty much the same
algorithm as yours. The S-Expression itself comes from the stream. So,
the only difference between your concept and my implementation is that
I expose the S-Expression memory tree and you don't.
The reason why I prefer to expose the S-Expression is because, in the
general (arbitrarily complex) case, you cannot traverse an S-
Expresssion linearly; you need to traverse it as what it really is, a
tree. A stream suggests linear traversal only.
[...]
>> TCP_Info : constant String := "(tcp-connect (host foo.bar) (port 80))";
>> TCP_Info_Structured := constant To_TCP_Info (To_Sexp (TCP_Info));
>
> That's an interesting idea, which conceptually boils down to serialize
> by hand the S-expression into a String, in order to unserialize it as
> an in-memory object, in order to serialize back into a Stream.
>
> Proofreading my post, the above might sound sarcastic though actually
> it is not. It's a twist I haven't thought of, but it might indeed turn
> out to be the simplest practical way of doing it.
Right. I was not being sarcastic either. The Cons (), To_Atom () and
Append () operations are needed only when creating arbitrary and
dynamic S-Expressions. For simple cases where most of the expression
is hardcoded, the textual representation of the S-Expression is much
more compact, readable and maintainable than the Ada procedural
representation. In fact, you could also conceivably write something
like:
TCP_Info_Sexp : S_Expression := To_Sexp ("(tcp-info (host *) (port
*))");
and programmatically change the values of the atoms containing the
actual data. Once you have the in-memory S-Expression, there is no
limit to what you can do with it. You can *change* the S-Expression as
you traverse it, deleting, replacing or adding nodes as you wish. You
cannot do that with a Sexp_Stream.
> Actually for a very long time I used to write S-expressions to file
> using only string facilities and a special sx_print_atom() function to
> handle escaping of unsafe data. By then I would have handled
> TCP_Info.Write with the following C fragment (sorry I don't know yet
> how to turn it into Ada, but I'm sure equivalent as simple exists):
>
> fprintf(outfile, "(tcp-connect\n\t(host ");
> sx_print_atom(outfile, host);
> fprintf(outfile, ")\n\t(port %d)\n)\n", port);
Sure, that can also be done just as easily in Ada. You can write S-
Expressions as easily as any blob or string; it is reading them back
and understanding their structure that is tricky.
--
Ludovic Brenta.
next prev parent reply other threads:[~2010-08-12 12:46 UTC|newest]
Thread overview: 252+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-01 12:17 S-expression I/O in Ada Natacha Kerensikova
2010-08-01 12:53 ` Dmitry A. Kazakov
2010-08-01 17:35 ` Natacha Kerensikova
2010-08-01 18:49 ` Dmitry A. Kazakov
2010-08-01 20:06 ` Natacha Kerensikova
2010-08-01 21:13 ` Dmitry A. Kazakov
2010-08-02 7:17 ` Georg Bauhaus
2010-08-02 7:58 ` Dmitry A. Kazakov
2010-08-07 7:23 ` Natacha Kerensikova
2010-08-07 8:39 ` Dmitry A. Kazakov
2010-08-07 12:56 ` Natacha Kerensikova
2010-08-07 14:23 ` Dmitry A. Kazakov
2010-08-08 12:23 ` Natacha Kerensikova
2010-08-08 13:01 ` Dmitry A. Kazakov
2010-08-08 13:49 ` Natacha Kerensikova
2010-08-08 15:15 ` Dmitry A. Kazakov
2010-08-09 9:55 ` Natacha Kerensikova
2010-08-09 10:56 ` Dmitry A. Kazakov
2010-08-10 8:56 ` Natacha Kerensikova
2010-08-10 10:17 ` Georg Bauhaus
2010-08-10 10:36 ` Dmitry A. Kazakov
2010-08-10 12:06 ` Natacha Kerensikova
2010-08-10 15:46 ` Dmitry A. Kazakov
2010-08-10 21:22 ` Simon Wright
2010-08-11 7:37 ` Dmitry A. Kazakov
2010-08-11 17:32 ` Simon Wright
2010-08-11 17:53 ` Dmitry A. Kazakov
2010-08-11 9:43 ` Natacha Kerensikova
2010-08-11 10:37 ` Dmitry A. Kazakov
2010-08-11 11:38 ` Natacha Kerensikova
2010-08-11 12:58 ` Robert A Duff
2010-08-11 15:30 ` Natacha Kerensikova
2010-08-11 23:39 ` Randy Brukardt
2010-08-12 1:31 ` Robert A Duff
2010-08-12 8:53 ` Natacha Porté
2010-08-12 9:22 ` Georg Bauhaus
2010-08-13 9:43 ` Natacha Kerensikova
2010-08-10 21:56 ` Randy Brukardt
2010-08-09 15:40 ` Simon Wright
2010-08-09 16:35 ` Robert A Duff
2010-08-10 0:51 ` Randy Brukardt
2010-08-10 1:00 ` Jeffrey Carter
2010-08-10 21:36 ` Randy Brukardt
2010-08-10 22:24 ` Jeffrey Carter
2010-08-10 12:50 ` Robert A Duff
2010-08-10 22:06 ` Randy Brukardt
2010-08-09 18:37 ` Natacha Kerensikova
2010-08-09 19:10 ` Robert A Duff
2010-08-08 14:08 ` Duke Normandin
2010-08-08 15:34 ` Robert A Duff
2010-08-08 18:24 ` Dmitry A. Kazakov
2010-08-08 20:03 ` Robert A Duff
2010-08-08 20:39 ` Dmitry A. Kazakov
2010-08-08 21:08 ` Robert A Duff
2010-08-09 6:50 ` Dmitry A. Kazakov
2010-08-09 13:48 ` Robert A Duff
2010-08-09 14:38 ` Dmitry A. Kazakov
2010-08-09 15:14 ` Georg Bauhaus
2010-08-09 16:11 ` Dmitry A. Kazakov
2010-08-09 16:46 ` Georg Bauhaus
2010-08-09 17:05 ` Robert A Duff
2010-08-09 18:29 ` Georg Bauhaus
2010-08-09 19:18 ` Robert A Duff
2010-08-10 8:21 ` Georg Bauhaus
2010-08-09 20:40 ` Dmitry A. Kazakov
2010-08-09 22:21 ` Georg Bauhaus
2010-08-10 7:07 ` Dmitry A. Kazakov
2010-08-09 16:47 ` Robert A Duff
2010-08-09 19:59 ` Dmitry A. Kazakov
2010-08-09 21:34 ` Robert A Duff
2010-08-09 22:29 ` Jeffrey Carter
2010-08-10 7:48 ` Dmitry A. Kazakov
2010-08-09 21:54 ` _FrnchFrgg_
2010-08-09 22:32 ` Georg Bauhaus
2010-08-10 7:16 ` Dmitry A. Kazakov
2010-08-10 11:06 ` _FrnchFrgg_
2010-08-10 11:19 ` Dmitry A. Kazakov
2010-08-10 23:04 ` _FrnchFrgg_
2010-08-11 14:10 ` Dmitry A. Kazakov
2010-08-11 17:51 ` Structural unification (pattern matching) in Ada [was: Re: S-expression I/O in Ada] _FrnchFrgg_
2010-08-11 18:06 ` Dmitry A. Kazakov
2010-08-11 19:43 ` Robert A Duff
2010-08-11 20:26 ` (see below)
2010-08-11 21:21 ` Structural unification (pattern matching) in Ada Simon Wright
2010-08-12 12:43 ` Structural unification (pattern matching) in Ada [was: Re: S-expression I/O in Ada] _FrnchFrgg_
2010-08-10 1:06 ` S-expression I/O in Ada Randy Brukardt
2010-08-09 16:50 ` Robert A Duff
2010-08-09 18:32 ` Natacha Kerensikova
2010-08-09 19:06 ` Jeffrey Carter
2010-08-09 19:24 ` Robert A Duff
2010-08-09 19:35 ` (see below)
2010-08-09 17:00 ` Robert A Duff
2010-08-09 20:27 ` Dmitry A. Kazakov
2010-08-09 21:30 ` Robert A Duff
2010-08-10 1:17 ` Randy Brukardt
2010-08-10 6:48 ` Dmitry A. Kazakov
2010-08-10 21:42 ` Randy Brukardt
2010-08-11 8:02 ` Dmitry A. Kazakov
2010-08-11 23:18 ` Randy Brukardt
2010-08-12 6:20 ` Dmitry A. Kazakov
2010-08-12 20:56 ` Randy Brukardt
2010-08-13 6:56 ` Dmitry A. Kazakov
2010-08-14 0:52 ` Randy Brukardt
2010-08-09 18:55 ` Jeffrey Carter
2010-08-09 18:20 ` Natacha Kerensikova
2010-08-09 19:19 ` Robert A Duff
2010-08-07 15:38 ` Jeffrey Carter
2010-08-07 17:01 ` Natacha Kerensikova
2010-08-08 6:52 ` Jeffrey Carter
2010-08-08 13:11 ` Natacha Kerensikova
2010-08-08 15:24 ` Robert A Duff
2010-08-09 18:00 ` Natacha Kerensikova
2010-08-09 18:09 ` Robert A Duff
2010-08-08 20:34 ` Jeffrey Carter
2010-08-09 18:10 ` Natacha Kerensikova
2010-08-08 10:26 ` Simon Wright
2010-08-08 11:44 ` Dmitry A. Kazakov
2010-08-08 11:48 ` Dmitry A. Kazakov
2010-08-08 14:05 ` Natacha Kerensikova
2010-08-08 20:11 ` Jeffrey Carter
2010-08-14 1:02 ` Yannick Duchêne (Hibou57)
2010-08-14 9:53 ` Georg Bauhaus
2010-08-14 11:32 ` Natacha Kerensikova
2010-08-01 22:03 ` Simon Wright
2010-08-02 17:08 ` Pascal Obry
2010-08-02 19:08 ` Simon Wright
2010-08-01 16:01 ` Ludovic Brenta
2010-08-09 18:49 ` Ludovic Brenta
2010-08-09 19:59 ` Natacha Kerensikova
2010-08-10 0:11 ` Ludovic Brenta
2010-08-10 0:57 ` Jeffrey Carter
2010-08-10 6:47 ` Natacha Kerensikova
2010-08-10 18:13 ` Jeffrey Carter
2010-08-12 9:26 ` Natacha Kerensikova
2010-08-12 10:55 ` Ludovic Brenta
2010-08-12 12:16 ` Natacha Kerensikova
2010-08-12 12:46 ` Ludovic Brenta [this message]
2010-08-12 13:23 ` Natacha Kerensikova
2010-08-12 16:19 ` Ludovic Brenta
2010-08-12 17:17 ` Natacha Kerensikova
2010-08-12 18:51 ` Jeffrey Carter
2010-08-13 9:32 ` Natacha Kerensikova
2010-08-13 15:52 ` Ludovic Brenta
2010-08-13 22:53 ` Jeffrey R. Carter
2010-08-14 11:10 ` Natacha Kerensikova
2010-08-10 15:48 ` Ludovic Brenta
2010-08-10 15:59 ` Georg Bauhaus
2010-08-12 7:53 ` Ludovic Brenta
2010-08-12 18:55 ` Jeffrey Carter
2010-08-12 19:59 ` Ludovic Brenta
2010-08-12 20:23 ` Natacha Kerensikova
2010-08-12 20:45 ` Ludovic Brenta
2010-08-13 8:24 ` Natacha Kerensikova
2010-08-13 9:08 ` Ludovic Brenta
2010-08-14 10:27 ` Natacha Kerensikova
2010-08-14 11:11 ` Ludovic Brenta
2010-08-14 12:17 ` Natasha Kerensikova
2010-08-14 13:13 ` Ludovic Brenta
2010-08-14 13:33 ` Yannick Duchêne (Hibou57)
2010-08-12 22:25 ` Jeffrey R. Carter
2010-08-13 9:10 ` Natacha Kerensikova
2010-08-13 9:51 ` Dmitry A. Kazakov
2010-08-14 10:36 ` Natacha Kerensikova
2010-08-14 10:57 ` Dmitry A. Kazakov
2010-08-13 19:23 ` Jeffrey Carter
2010-08-13 19:42 ` Dmitry A. Kazakov
2010-08-13 20:44 ` Yannick Duchêne (Hibou57)
2010-08-14 0:57 ` Randy Brukardt
2010-08-14 10:47 ` Natacha Kerensikova
2010-08-13 19:36 ` Simon Wright
2010-08-12 20:11 ` Natacha Kerensikova
2010-08-12 20:22 ` Ludovic Brenta
2010-08-01 18:25 ` Jeffrey Carter
2010-08-01 19:43 ` Natacha Kerensikova
2010-08-01 19:53 ` Ludovic Brenta
2010-08-01 20:00 ` Dmitry A. Kazakov
2010-08-01 20:03 ` Jeffrey Carter
2010-08-01 20:34 ` Georg Bauhaus
2010-08-01 20:44 ` Georg Bauhaus
2010-08-01 21:01 ` anon
2010-08-12 23:26 ` Shark8
2010-08-13 2:31 ` Shark8
2010-08-13 8:56 ` Natacha Kerensikova
2010-08-13 10:30 ` Georg Bauhaus
2010-08-13 15:58 ` Shark8
2010-08-13 21:48 ` Shark8
2010-08-14 11:02 ` Natacha Kerensikova
2010-08-17 17:01 ` Natasha Kerensikova
2010-08-17 19:00 ` Jeffrey Carter
2010-08-18 10:49 ` Natasha Kerensikova
2010-08-18 11:14 ` Ludovic Brenta
2010-08-18 11:59 ` Natasha Kerensikova
2010-08-18 12:31 ` Ludovic Brenta
2010-08-18 13:16 ` J-P. Rosen
2010-08-18 13:55 ` Natasha Kerensikova
2010-08-18 14:40 ` J-P. Rosen
2010-08-20 20:50 ` Yannick Duchêne (Hibou57)
2010-08-18 15:07 ` Ludovic Brenta
2010-08-19 7:42 ` Natasha Kerensikova
2010-08-18 12:51 ` Georg Bauhaus
2010-08-18 13:24 ` Natasha Kerensikova
2010-08-18 14:40 ` Georg Bauhaus
2010-08-18 23:50 ` Randy Brukardt
2010-08-18 11:22 ` Georg Bauhaus
2010-08-18 12:02 ` Natasha Kerensikova
2010-08-20 21:04 ` Yannick Duchêne (Hibou57)
2010-08-22 10:21 ` Natasha Kerensikova
2010-08-22 10:28 ` Simon Wright
2010-08-22 17:13 ` Jeffrey Carter
2010-08-22 14:06 ` Dmitry A. Kazakov
2010-08-21 19:36 ` Yannick Duchêne (Hibou57)
2010-08-18 18:08 ` Jeffrey Carter
2010-08-19 8:09 ` Natasha Kerensikova
2010-08-19 10:16 ` Natasha Kerensikova
2010-08-19 10:42 ` Dmitry A. Kazakov
2010-08-22 10:24 ` Natasha Kerensikova
2010-08-22 14:10 ` Dmitry A. Kazakov
2010-08-19 18:07 ` Jeffrey Carter
2010-08-22 10:43 ` Natasha Kerensikova
2010-08-22 17:17 ` Jeffrey Carter
2010-08-19 17:59 ` Jeffrey Carter
2010-08-22 10:45 ` Natasha Kerensikova
2010-08-22 17:20 ` Jeffrey Carter
2010-08-24 11:41 ` Natasha Kerensikova
2010-08-25 1:56 ` Jeffrey Carter
2010-08-25 12:18 ` Natasha Kerensikova
2010-08-25 14:07 ` Jeffrey Carter
2010-08-25 8:06 ` Georg Bauhaus
2010-08-25 13:27 ` Natasha Kerensikova
2010-08-25 18:55 ` Simon Wright
2010-08-25 19:19 ` Georg Bauhaus
2010-08-25 19:23 ` Georg Bauhaus
2010-08-25 22:38 ` Simon Wright
2010-08-25 23:55 ` Georg Bauhaus
2010-08-27 13:19 ` Natasha Kerensikova
2010-08-27 14:57 ` Georg Bauhaus
2010-08-29 10:45 ` Natasha Kerensikova
2010-08-29 13:10 ` Simon Wright
2010-08-29 14:21 ` Natasha Kerensikova
2010-08-29 14:30 ` Niklas Holsti
2010-08-29 13:23 ` Robert A Duff
2010-08-29 13:57 ` Jeffrey Carter
2010-08-29 14:18 ` Britt Snodgrass
2010-08-29 14:29 ` Natasha Kerensikova
2010-08-29 15:12 ` Robert A Duff
2010-09-03 21:52 ` Randy Brukardt
2010-08-29 13:56 ` Jeffrey Carter
2010-08-29 14:34 ` Natasha Kerensikova
2010-08-29 14:55 ` Dmitry A. Kazakov
2010-08-29 15:25 ` Robert A Duff
2010-08-29 18:50 ` Georg Bauhaus
2010-08-29 21:43 ` Simon Wright
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox