From: Leslie P. Polzer
Subject: Parser callbacks
Date: 
Message-ID: <1181496216.840402.35770@q66g2000hsg.googlegroups.com>
Another newbie question.

I'd like to implement a parser and execute callbacks whenever a valid
token has been parsed.
Is it very naïve to do this with a hash table or associative array of
tokens and callbacks?
Could closures be of help here?

  Leslie

From: Kent M Pitman
Subject: Re: Parser callbacks
Date: 
Message-ID: <ur6oj374a.fsf@nhplace.com>
"Leslie P. Polzer" <·············@gmx.net> writes:

> Another newbie question.
> 
> I'd like to implement a parser and execute callbacks whenever a
> valid token has been parsed.  Is it very na�ve to do this with a
> hash table or associative array of tokens and callbacks?  Could
> closures be of help here?

This presupposes a particular kind of parser.  There are many kinds.
In some of them, this makes sense, in others not.  Absent such details,
your question sounds a bit like "I'm trying to find a device to help
me cook a potato the way I like it.  Does anyone know if the Model X
potato cooker is good at allowing me to place the rocks where they 
will do the most good?".

You haven't even said what you're parsing and what constitutes a token.
parse-integer, for example, is a builtin and does parsing but gives back
integers.  There is no callback, simply a return value.

Also, while other languages can generally represent symbolic data
easily enough, the thing they don't do is define, at the language
level, a specific somewhat-arbitrarily chosen datatype (like Lisp has
done with symbols and lists) to represent parsed structure.
Consequently, when a parser from another language sees a token, it has
no way of knowing how to anticipate what the caller expected, so it
calls a caller function.  But in Lisp, the representation is pretty
much subject to a "prisoner's dilemma" style solution, and so the
caller probably is already designed to receive symbols because it
imagines (correctly) that this is what parsers willr eturn.  That
simplifies a great many thigns.  The lack of strong-typing in Lisp
also means it's pretty easy for a parser to delay this decision until
it sees the data, and pretty easy for a caller to test that the data
that came back is within a restricted class, if it even cares (since
often, the result will be a valid expression, and it really doesn't
matter if the expression is numeric or list or symbol or whatever).
From: Leslie P. Polzer
Subject: Re: Parser callbacks
Date: 
Message-ID: <1181540710.875714.158610@m36g2000hse.googlegroups.com>
Alright, here's more detail.

The parser needs to parse VT100 escape sequences.

Example input stream:

  here_is_some_text<ESC>[5B

which means: print "here_is_some_text" at the current cursor location
and move down 5 lines.

What I had in mind was to call two callback functions here, say

  print-text (text)
  move-down (nlines)

  Leslie
From: Kent M Pitman
Subject: Re: Parser callbacks
Date: 
Message-ID: <uvedvnh3j.fsf@nhplace.com>
"Leslie P. Polzer" <·············@gmx.net> writes:

> Alright, here's more detail.
> 
> The parser needs to parse VT100 escape sequences.
> 
> Example input stream:
> 
>   here_is_some_text<ESC>[5B
> 
> which means: print "here_is_some_text" at the current cursor location
> and move down 5 lines.
> 
> What I had in mind was to call two callback functions here, say
> 
>   print-text (text)
>   move-down (nlines)

Why is that a parser action?  Parsing [at least in Lisp] is something
that should _yield_ executable code (as an object), not execute that
code.  Those functions are things that do, not things that parse.

What you want is a function that takes the stream you've given (or 
maybe also a string containing such text) and returns

 ((print-text "here_is_some_text")
  (move-down 5))

If what you want is something that simultaneously executes the text,
then it's not a parser.  But note in the case that it returns the
text, there is no "callback".  The stuff you get back might contain
references to functions to call, but you are not being called back in
the traditional sense that most UI or parser callbacks are.

Unless you've just named your functions badly and these names you gave
don't do the parsing but rather just construct lists or other objects
like the ones I suggested.  But that's a very baroque way of doing
things in Lisp, ay least to my taste.

So, I still don't understand what you're trying to do.  I'm curious
though.
From: Leslie P. Polzer
Subject: Re: Parser callbacks
Date: 
Message-ID: <1181550993.498928.4210@p77g2000hsh.googlegroups.com>
On 11 Jun, 08:24, Kent M Pitman <······@nhplace.com> wrote:

> Why is that a parser action?  Parsing [at least in Lisp] is something
> that should _yield_ executable code (as an object), not execute that
> code.  Those functions are things that do, not things that parse.
>
> What you want is a function that takes the stream you've given (or
> maybe also a string containing such text) and returns
>
>  ((print-text "here_is_some_text")
>   (move-down 5))

Neat.  Yes, that's what I want;  I suppose that shows the reason why I
asked
you guys to evaluate, i.e. rip apart, my approach.

I'm just not much into thinking Lisp, yet.


> Unless you've just named your functions badly and these names you gave
> don't do the parsing but rather just construct lists or other objects
> like the ones I suggested.  But that's a very baroque way of doing
> things in Lisp, ay least to my taste.

The functions wouldn't do anything fancy, no.  They'd just carry out
the appropriate action when called.


> So, I still don't understand what you're trying to do.  I'm curious
> though.

I think you understand my problem pretty well.  If you have some
additional
hints, hand them over.

I wonder at what time the parser should return something, given that
the input stream
is continuous and in theory infinite.

  Leslie
From: Vassil Nikolov
Subject: Re: Parser callbacks
Date: 
Message-ID: <ka4pldrjw1.fsf@localhost.localdomain>
On Mon, 11 Jun 2007 01:36:33 -0700, "Leslie P. Polzer" <·············@gmx.net> said:

| ...
| I wonder at what time the parser should return something, given that
| the input stream is continuous and in theory infinite.

  You are implementing a VT-100 emulator?

  I think that the term "parser" is a red herring, then.

  Perhaps you can do it with an analog of the read-eval-print loop,
  where the analog of read would consume only as much as constutes "a
  unit of work", per call, from the input stream, and return a
  suitable lisp datum---say, an s-expression, the analog of eval would
  update the representation of the state of the terminal accordingly,
  and the analog of print would display this new state on the
  appropriate output device.

  Or perhaps see how emacs does it (it implements (at least) two kinds
  of terminals, a glass tty and a tty with an addressable cursor).

  Or perhaps there are better approaches.

  ---Vassil.


-- 
The truly good code is the obviously correct code.
From: ····················@gmail.com
Subject: Re: Parser callbacks
Date: 
Message-ID: <1183477581.103129.169300@o61g2000hsh.googlegroups.com>
On Jun 11, 4:36 am, "Leslie P. Polzer" <·············@gmx.net> wrote:
>
> I wonder at what time the parser should return something, given that
> the input stream
> is continuous and in theory infinite.
>

I'd vote for never: it saves time, enshrines the fundamental principle
of laziness, and keeps you from doing work that may not be necessary.

At this point you may be thinking that some of the work is necessary?

In that case, you apparently haven't appropriate analyzed the
requirements for your parser. I suggest you do that before you decide
how to write it. Form follows function.