[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re[2]: Empty rule spoiling error reporting
From: |
hz kto |
Subject: |
Re[2]: Empty rule spoiling error reporting |
Date: |
Tue, 10 Aug 2004 02:33:35 +0400 |
I found a relatively well working solution to this without the grammar rewrite.
During a reduction I check in yyr2[] whether the rule is empty, and if it is, I
increment a counter.
Counter gets reset on a non-empty reduction, after error, and on a successful
shift.
When an error happens I check for possible tokens, then see if my counter is
>0. If it is, then look at the previous state on the stack, check for possible
tokens again and add them to ones that I already found. Keep moving back and
checking until counter is back to zero.
This way I might find few tokens twice, but it is easy to ignore the duplicates.
So far I haven't found any caveats with this method, if you see any, please let
me know.
Thanks,
-----Original Message-----
From: address@hidden [mailto:address@hidden On Behalf Of Tim Van Holder
Sent: Wednesday, August 04, 2004 11:13 PM
To: hz kto
Cc: address@hidden; Hans Aberg
Subject: Re: Empty rule spoiling error reporting
hz kto wrote:
>>>My grammar contains a lot of optional rules like this
>>>
>>>rule1 : token3 {...}
>>> | token2 {...}
>>> | opt_something1 token1 {...}
>>>
>>>
>>>When in certain context parser does not see token1,2,3 nor anything
>>>non-empty from opt_something1, it matches an empty rule and then,
>>>when it starts searching for tokens that could follow next, it only
>>>finds token1 since it already in the state corresponding to
>>>opt_something1.
>
> I just want to report more possible tokens. As it stands now I report
> only one instead of several in these cases.
Well then I'm afraid you'll have to refactor your rules:
rule1
: token1 { ... }
| something1 token1 { ... }
| token2 { ... }
| token3 { ... }
;
Now the parser should be able to list more possible tokens
if a bad token is seen at the start of rule1.
Note that this requires a lot of work if you have all your opt_ rules in the
form:
opt_foo
: /* empty */
| foo_format_1
| foo_format_2
| foo_format_3
;
I strongly recommend using only trivial opt_ rules from the get go:
opt_foo
: /* empty */
| foo
;
foo
: foo_format_1
| foo_format_2
| foo_format_3
;
This uses more rules but makes it much easier to work with. Similarly for mul_
an plus_ rules (to handle */+ repetition):
mul_foo
: /* empty */
| plus_foo
;
plus_foo
: foo
| plus_foo foo
;
_______________________________________________
address@hidden http://lists.gnu.org/mailman/listinfo/help-bison