Parser Combinators

37 views
Skip to first unread message

Yves Cloutier

unread,
Mar 17, 2018, 5:15:13 AM3/17/18
to pure-lang
Hi there,

I'm just reaching out to see if anyone has done any parser combinators using pure?

I'm following a tutorial from:

https://fsharpforfunandprofit.com/posts/understanding-parser-combinators/

I had started in f#, but I don't know. Although I like F#, I also prefer Pure ;) I just feel Pure just lets me do things quickly without thinking too much about types.


Albert Graef

unread,
Mar 17, 2018, 12:40:19 PM3/17/18
to pure...@googlegroups.com
On Thu, Mar 15, 2018 at 11:15 PM, Yves Cloutier <yves.c...@gmail.com> wrote:
> I'm just reaching out to see if anyone has done any parser combinators using
> pure?

I haven't tried this, but it would be nice to have in Pure!

Albert

--
Dr. Albert Gr"af
Computer Music Research Group, JGU Mainz, Germany
Email: agg...@gmail.com
WWW: https://plus.google.com/+AlbertGraef

Yves Cloutier

unread,
Mar 17, 2018, 4:04:32 PM3/17/18
to pure-lang
Hi Albert,

I've started playing with this but having a hard time just getting the basics going.

I think I'm not using case expressions properly.  Not sure if these are analogous to ML type pattern matching and tuple matching.

For example:

// Parser combinators adapted from perl-friends-2017/parsing-fsharp.org

type
Success = true;
type
Failure = false;
//infix 1 <&>;

/*
Match a target char in a string
On success, return the match and the rest of the input.
On failure, simply return the entire input.
*/

pChar target subject
=    
   
if head subject == target
   
then (Success, target, tail subject)
   
else (Failure, subject)
   
;

/*
Match a sequence of parsers
parser1 and parser2 are functions (ex: parser1 = pChar "a"; parser2 = pChar "b")
Subject is a string.
*/
   
pAnd parser1 parser2 subject
=
   
// Try the first parser. If it succeeds, try the other
   
case (parser1 subject) of    
       
(Failure, f )     = (Failure, f);
       
(Success, match1, rest) = case (parser2 rest) of    
           
(Success, match2, rest2) = (Success, match1 + match2, rest2);
           
(Failure, s) = (Failure, s);
           
end;
       
end;

pA
= pChar "a";
pB
= pChar "b";
//<&> p1 p2 = pAnd pA pB;

//And now the big test...
pAnd pA pB
"abcd";

I know there's something wrong with my case expression because:

rule never reduced: Success,match1,rest = case parser2 rest of Failure,s = Failure,s; Success,match2,rest2 = Success,match1+match2,rest2

Albert Graef

unread,
Mar 19, 2018, 7:52:43 AM3/19/18
to pure...@googlegroups.com
Hi Yves,

sorry for the latency, I was busy working on Pd-l2ork and getting Pure
0.67 out of the door.

Your case expressions are all right, but obviously type doesn’t quite
work the way you think it does. ;-) Just use:

nonfix Failure Success;

With that I get:

> pAnd pA pB "abcd";
Success,"ab","cd"

HTH,
Albert
> --
> You received this message because you are subscribed to the Google Groups
> "pure-lang" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to pure-lang+...@googlegroups.com.
> To post to this group, send email to pure...@googlegroups.com.
> Visit this group at https://groups.google.com/group/pure-lang.
> For more options, visit https://groups.google.com/d/optout.

Yves Cloutier

unread,
Mar 19, 2018, 10:01:43 AM3/19/18
to pure-lang
Oh this is great!

Got it. Failure and Success defined as symbols.

Yes I will have to re-read the section about types.  It's one thing that trips me up, a  bit different than what I'm used to.

Ok, I will continue to follow the tutorial steps in the link provided earlier.  But don't be surprised if I ask questions along the way.

Maybe I can post my progress as I go, for others to see.  and be free to point out where things could be more idiomatic or style improved.

Regards

Albert Graef

unread,
Mar 20, 2018, 3:52:40 AM3/20/18
to pure...@googlegroups.com
On Mon, Mar 19, 2018 at 3:01 PM, Yves Cloutier <yves.c...@gmail.com> wrote:
Got it. Failure and Success defined as symbols.

Yeah, you might also have defined a type for them, but why go through all that hassle for simple truth values like this? In fact, you might just have used `true` and `false` instead, they're declared `nonfix` in the prelude as well, so can be matched against.
 
Yes I will have to re-read the section about types.  It's one thing that trips me up, a  bit different than what I'm used to.

Pure is *very* different from statically typed languages there, even from other dynamically-typed languages. Types are basically just unary membership predicates, with some syntactic sugar for added convenience. Pure also has its own flavor of interface types to support Duck typing, but these are rather experimental right now, so you probably shouldn't use them.

Maybe I can post my progress as I go, for others to see.  and be free to point out where things could be more idiomatic or style improved.

Sure, will do!
 
Albert
Reply all
Reply to author
Forward
0 new messages