At 2002-06-29 14:43, Wolfgang Jeltsch wrote:
To simplify things a bit, let's take a simpler Parser type which doesn't use monad state transformers but simple state transformers instead. This makes the type ParserState simpler. You can think of a parser state as an infinite list of substate-token pairs now. The tokens denote the input stream. The substates may be used to encapsulate parser states of a subordinate parsing process. When a token is read, the corresponding token-substate pair is discarded.
Sounds very complicated. Wouldn't a simple stream transformer work? newtype MyParser baseMonad token output = MkMyParser (baseMonad token -> baseMonad output);
(>>=): sequencing of parsers return: returning values fail: generation of always failing parsers mzero: always failing parser mplus: parsing using alternative parsers fmap: applying a function to the result of a parser (>>>): providing high-level tokens and parsing using these tokens identity: reading a single token pure: reading a single token and applying a function to it
I think I can do all of those for MyParser. There's a one-token look-ahead variant: newtype MyLookaheadParser m t a = MkMyLookaheadParser (m t -> Maybe t -> m (Maybe t,a));
(I don't allow finite lists here to make some things a bit easier an more elegant. You can easily produce an infinite list from a finite one by applying something like (++ repeat Nothing) . map Just to the finite list.)
Wouldn't it be easier to allow finite token lists and have reading past the last token be the same as mzero? -- Ashley Yakeley, Seattle WA
On Friday, 2002-11-29, 14:12, CET, Ashley Yakeley wrote:
At 2002-06-29 14:43, Wolfgang Jeltsch wrote:
To simplify things a bit, let's take a simpler Parser type which doesn't use monad state transformers but simple state transformers instead. This makes the type ParserState simpler. You can think of a parser state as an infinite list of substate-token pairs now. The tokens denote the input stream. The substates may be used to encapsulate parser states of a subordinate parsing process. When a token is read, the corresponding token-substate pair is discarded.
Sounds very complicated. Wouldn't a simple stream transformer work?
newtype MyParser baseMonad token output = MkMyParser (baseMonad token -> baseMonad output);
Hello Ashley, I cannot see how this relatively simple representation can be used to describe certain parsers. If I would use Identity for baseMonad, I would have a type for simple parsers. MyParser Identity would essentially be token -> output. Which function of this type should be used to describe, for instance, (a) a parser reading no tokens and returning () (b) a parser reading two tokens and returning the pair of these tokens?
[...]
(I don't allow finite lists here to make some things a bit easier an more elegant. You can easily produce an infinite list from a finite one by applying something like (++ repeat Nothing) . map Just to the finite list.)
Wouldn't it be easier to allow finite token lists and have reading past the last token be the same as mzero?
I consider it better to use infinite lists in the core parser module. I'm able to provide the functionality, you suggest here, on top of this core module, and, in fact, I do so (see Seaweed.Core.Parsing.Utilities.convertTokenList). This approch has (maybe among others) these two advantages: 1. baseMonad doesn't generally have to be an instance of MonadPlus. 2. The core module can concentrate on the (rather difficult) core mechanisms and leave the job of returning mzero at the end of the stream to another module. Wolfgang P.S.: The Seaweed CVS repository can be examined via http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/seaweed/.
participants (2)
-
Ashley Yakeley -
Wolfgang Jeltsch