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