summaryrefslogtreecommitdiff
path: root/NEWS
diff options
context:
space:
mode:
authorAkim Demaille <akim.demaille@gmail.com>2020-06-28 16:09:13 +0200
committerAkim Demaille <akim.demaille@gmail.com>2020-06-29 19:36:41 +0200
commit330552ea499ca474f65967160e9d4e50265f9631 (patch)
treecbfb334fdae9bdfa4a0348a48b2f050f78e4b7f3 /NEWS
parent7c609859ee3fd7c40c7685df7b811a50a4071ace (diff)
downloadbison-330552ea499ca474f65967160e9d4e50265f9631.tar.gz
yacc.c: push: don't clear the parser state when accepting/rejecting
Currently when a push parser finishes its parsing (i.e., it did not return YYPUSH_MORE), it also clears its state. It is therefore impossible to see if it had parse errors. In the context of autocompletion, because error recovery might have fired, the parser is actually already in a different state. For instance on `(1 + + <TAB>` in the bistromathic, because there's a `exp: "(" error ")"` recovery rule, `1 + +` tokens have already been popped, replaced by `error`, and autocompletions think we are ready for the closing ")". So here, we would like to see if there was a syntax error, yet `yynerrs` was cleared. In the case of a successful parse, we still have a problem: if error recovery succeeded, we won't know it, since, again, `yynerrs` is clearer. It seems much more natural to leave the parser state available for analysis when there is a failure. To reuse the parser, we should either: 1. provide an explicit means to reinitialize a parser state for future parses. 2. automatically reset the parser state when it is used in a new parse. Option 2 requires to check whether we need to reinitialize the parser each time we call `yypush_parse`, i.e., each time we give a new token. This seems expensive compared to Option 1, but benchmarks revealed no difference. Option 1 is incompatible with the documentation ("After `yypush_parse` returns a status other than `YYPUSH_MORE`, the parser instance `yyps` may be reused for a new parse."). So Option 2 wins, reusing the private `yynew` member to record that a parse was finished, and therefore that the state must reset in the next call to `yypull_parse`. While at it, this implementation now reuses the previously enlarged stacks from one parse to another. * data/skeletons/yacc.c (yypstate_new): Set up the stacks in their initial configurations (setting their bottom to the stack array), and use yypstate_clear to reset them (moving their top to their bottom). (yypstate_delete): Adjust. (yypush_parse): At the beginning, clear yypstate if needed, and at the end, record when yypstate needs to be clearer. * examples/c/bistromathic/parse.y (expected_tokens): Do not propose autocompletion when there are parse errors. * examples/c/bistromathic/bistromathic.test: Check that case.
Diffstat (limited to 'NEWS')
-rw-r--r--NEWS16
1 files changed, 16 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index a715694c..9e1c5076 100644
--- a/NEWS
+++ b/NEWS
@@ -42,6 +42,22 @@ GNU Bison NEWS
filename_type -> api.filename.type
package -> api.package
+*** Push parser state
+
+** Backward incompatible changes
+
+*** Push parsers no longer clear their state when parsing is finished
+
+ Previously push-parsers cleared their state when parsing was finished (on
+ success and on failure). This made it impossible to check if there were
+ parse errors, since `yynerrs` was also reset. This can be especially
+ troublesome when used in autocompletion, since a parser with error
+ recovery would suggest (irrelevant) expected tokens even if there were
+ failure.
+
+ Now the parser state can be examined when parsing is finished. The parser
+ state is reset when starting a new parse.
+
** Bug fixes
*** Include the generated header (yacc.c)