On Mon, 7 Nov 2016 18:14:22 +1100, Jack Andrews <effb...@gmail.com>
wrote:
> I'm new to PEGs (but I've been parsing for a while)

Welcome!

> and I don't
> understand why this..
> 
> E->XYE|ZE|
> 
> ...doesn't parse "1+1-2" the way I expect (it fails):
> 
> i've tried using PackCC and I now in leg (it's more likely you know
> leg than pcc)

I can't comment on PackCC, but the problem with your leg grammar is
that you've defined YY_INPUT incorrectly. It needs to set r to the
result. Also, the macro outputs the next character, instead of the
current one. Finally, your start rule attempts to match '\n',
which is presumably a leftover from an earlier version.

Here's a patch that fixes all 3 problems, and results in success.

--- a/g.peg
+++ b/g.peg
@@ -1,9 +1,9 @@
 #leg g.peg -o g.c && cc g.c -o g && ./g
 %{
 char*in="1+1-2";
-#define YY_INPUT(b,r,m) *in?*(b)=*in++,putchar(*in),1:0
+#define YY_INPUT(b,r,m) r=*in?*(b)=*in++,putchar(*b),1:0;
 %}
-S=E '\n';
+S=E !.;
 E=x:X y:Y z:E {printf("%c%c%c\n",x,y,z);$$='E';}
  |x:Z y:E     {printf("%c%c\n",x,y);$$='E';}
  |''          {printf("''");$$='E';}

You might also be interested in pacc_, which was inspired by peg/leg,
but has the advantage of writing a packrat parser, not a recursive
descent one. I tend to think it has nicer syntax too, but as pacc's
author I would say that, wouldn't I? :)

.. _pacc: https://paccrat.org/

To help you judge for yourself, here's your grammar converted to pacc:

# pacc g.pacc && gcc -o g g.c && ./g
{
  int pacc_wrap(const char *, char *, size_t, int *);

  int main(void) {
    char *in = "1+1-2";
    int result;
    if (pacc_wrap("arg", in, strlen(in), &result))
      printf("parsed with value %d\n", result);
  }
}

Expr = d:Digit o:Op e:Expr { printf("%c%c%c\n", d, o, e), 'E' }
     | b:Both e:Expr { printf("%c%c\n", b, e), 'E' }
     | { printf("''"), 'E' }

Both = Digit | Op

Digit = [0-9] { ref_0(ref()) }

Op = [+-] { ref_0(ref()) }

Regards,

Toby.

_______________________________________________
PEG mailing list
PEG@lists.csail.mit.edu
https://lists.csail.mit.edu/mailman/listinfo/peg

Reply via email to