On 2019-05-07, Daniel Cegiełka <daniel.cegie...@gmail.com> wrote: > Hi, > > I'm going to use Quentin's miniyacc with (for example) bc.y from Plan 9: > https://github.com/9fans/plan9port/blob/master/src/cmd/bc.y > > Of course, I had to modify the code (a bit), but unfortunately I still > get an error when using miniyacc - works correctly with yacc from > OpenBSD and Plan 9. > > I'm getting a message from this place ("production rule too long"): > https://c9x.me/git/miniyacc.git/tree/yacc.c#n1110 > > I tried to increase the value of IdntSz and MaxRhs, but it didn't help > in any way.
It looks like this error is caused when miniyacc encounters a character that it doesn't recognize as a token. nexttk() returns a zero-length TIdnt token, causing an infinite loop, filling up r->rhs. Try the attached patch, which makes it fail on invalid tokens. In the example bc.y you linked, I think the '={' is causing problems, and is from an obsolete yacc syntax: Some implementations recognize "={" as equivalent to '{' because it appears in historical documentation. This construction was recognized and documented as obsolete as long ago as 1978, in the referenced Yacc: Yet Another Compiler-Compiler. This volume of POSIX.1-2017 chose to leave it as obsolete and omit it. I also ran into this problem on some other grammar files containing comments. One other issue I noticed is miniyacc doesn't seem to handle escape sequences in literals (i.e. '\n'). After working around those issues, I get a different error $n has no type (on line 171) I think this is due to the usage of $2 referring to a token (EQOP in this case) rather than a non-terminal. I haven't investigated this further.
From 2c333b66bcbf4278bd5d080a6722aad704160905 Mon Sep 17 00:00:00 2001 From: Michael Forney <mfor...@mforney.org> Date: Wed, 8 May 2019 01:14:57 -0700 Subject: [PATCH] Fail on invalid token Reading a zero-length TIdnt token causes infinite loops or other failures. --- yacc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/yacc.c b/yacc.c index 01f054e..8ea5137 100644 --- a/yacc.c +++ b/yacc.c @@ -837,6 +837,8 @@ nexttk() die("identifier too long"); c = fgetc(fin); } + if (p == idnt) + die("unknown token"); *p = 0; if (strcmp(idnt, "%")==0) if (c=='{') -- 2.20.1