c: don't emit an error message when the scanner returns YYERRCODE

* data/skeletons/yacc.c (yyparse): When the scanner returns YYERRCODE,
go directly to error recovery (yyerrlab1).
However, don't keep the error token as lookahead, that token is too
special.
* data/skeletons/lalr1.cc: Likewise.

* examples/c/bistromathic/parse.y (yylex): Use that feature to report
nicely invalid characters.
* examples/c/bistromathic/bistromathic.test: Check that.
* examples/test: Neutralize gratuitous differences such as rule
position.

* tests/calc.at: Check that case in C only.
The other case seem to be working, but that's an illusion that the
next commit will address (in fact, they can enter endless loops, and
report the error several times anyway).
This commit is contained in:
Akim Demaille
2020-04-15 07:38:46 +02:00
parent 60366b152b
commit 58e79539fc
6 changed files with 214 additions and 22 deletions

View File

@@ -82,7 +82,11 @@ run 0 '> 1 / 0
> ''
err: 1.1-5: error: division by zero'
# Error recovery.
## ---------------- ##
## Error recovery. ##
## ---------------- ##
cat >input <<EOF
((1 ++ 2) ** 3)
(1 ++ 2) + (3 ** 4)
@@ -96,14 +100,124 @@ err: 1.6: syntax error: expected - or ( or number or function or variable before
err: 2.5: syntax error: expected - or ( or number or function or variable before +
err: 2.16: syntax error: expected - or ( or number or function or variable before *'
# This is really stupid: we just discarded % and did not enter error recovery.
# The rule "( error )" should work even if there are no tokens between "(" and ")".
cat >input <<EOF
()
EOF
run 0 '> ()
666
> ''
err: 1.2: syntax error: expected - or ( or number or function or variable before )'
cat >input <<EOF
100% + 10
EOF
run 0 '> 100% + 10
110
> ''
err: 1.4: error: invalid character'
err: 1.4: syntax error: invalid character: %'
# Traces. This allows to check the location of the error. If we
# forget to map YYERRCODE to YYUNDEF, error recovery enters an endless
# loop with this input.
cat >input <<EOF
(+_)
EOF
run 0 '> (+_)
666
> ''
err: Starting parse
err: Entering state 0
err: Stack now 0
err: Reading a token
err: Next token is token ( (1.1: )
err: Shifting token ( (1.1: )
err: Entering state 2
err: Stack now 0 2
err: Return for a new token:
err: Reading a token
err: Next token is token + (1.2: )
err: LAC: initial context established for +
err: LAC: checking lookahead +: Err
err: LAC: checking lookahead end of file: Err
err: LAC: checking lookahead +: Err
err: LAC: checking lookahead -: S1
err: LAC: checking lookahead *: Err
err: LAC: checking lookahead /: Err
err: LAC: checking lookahead ^: Err
err: LAC: checking lookahead (: S2
err: LAC: checking lookahead ): Err
err: LAC: checking lookahead =: Err
err: LAC: checking lookahead exit: Err
err: LAC: checking lookahead number: S4
err: LAC: checking lookahead function: S5
err: LAC: checking lookahead variable: S6
err: LAC: checking lookahead NEG: Err
err: 1.2: syntax error: expected - or ( or number or function or variable before +
err: LAC: initial context discarded due to error recovery
err: Shifting token error (1.2: )
err: Entering state 10
err: Stack now 0 2 10
err: Next token is token + (1.2: )
err: LAC: initial context established for +
err: LAC: checking lookahead +: Err
err: Error: discarding token + (1.2: )
err: Error: popping token error (1.2: )
err: Stack now 0 2
err: LAC: initial context discarded due to error recovery
err: Shifting token error (1.2: )
err: Entering state 10
err: Stack now 0 2 10
err: Return for a new token:
err: 1.3: syntax error: invalid character: _
err: Reading a token
err: Error: popping token error (1.2: )
err: Stack now 0 2
err: Shifting token error (1.2-3: )
err: Entering state 10
err: Stack now 0 2 10
err: Next token is token invalid token (1.3: )
err: LAC: initial context established for invalid token
err: LAC: checking lookahead invalid token: Always Err
err: Error: discarding token invalid token (1.3: )
err: Error: popping token error (1.2-3: )
err: Stack now 0 2
err: LAC: initial context discarded due to error recovery
err: Shifting token error (1.2-3: )
err: Entering state 10
err: Stack now 0 2 10
err: Return for a new token:
err: Reading a token
err: Next token is token ) (1.4: )
err: Shifting token ) (1.4: )
err: Entering state 20
err: Stack now 0 2 10 20
err: Reducing stack by rule 15 (line 151):
err: $1 = token ( (1.1: )
err: $2 = token error (1.2-3: )
err: $3 = token ) (1.4: )
err: -> $$ = nterm exp (1.1-4: 666)
err: Entering state 7
err: Stack now 0 7
err: Return for a new token:
err: Reading a token
err: Now at end of input.
err: LAC: initial context established for end of file
err: LAC: checking lookahead end of file: R2 G8 S19
err: Reducing stack by rule 2 (line 126):
err: $1 = nterm exp (1.1-4: 666)
err: -> $$ = nterm input (1.1-4: )
err: Entering state 8
err: Stack now 0 8
err: Now at end of input.
err: Shifting token end of file (1.5: )
err: LAC: initial context discarded due to shift
err: Entering state 19
err: Stack now 0 8 19
err: Stack now 0 8 19
err: Cleanup: popping token end of file (1.5: )
err: Cleanup: popping nterm input (1.1-4: )' -p
## ------------ ##