mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
bpo-33306: Improve SyntaxError messages for unbalanced parentheses. (GH-6516)
This commit is contained in:
parent
bdabb0737c
commit
94cf308ee2
5 changed files with 47 additions and 7 deletions
|
|
@ -1842,12 +1842,44 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end)
|
|||
case '(':
|
||||
case '[':
|
||||
case '{':
|
||||
#ifndef PGEN
|
||||
if (tok->level >= MAXLEVEL) {
|
||||
return syntaxerror(tok, "too many nested parentheses");
|
||||
}
|
||||
tok->parenstack[tok->level] = c;
|
||||
tok->parenlinenostack[tok->level] = tok->lineno;
|
||||
#endif
|
||||
tok->level++;
|
||||
break;
|
||||
case ')':
|
||||
case ']':
|
||||
case '}':
|
||||
#ifndef PGEN
|
||||
if (!tok->level) {
|
||||
return syntaxerror(tok, "unmatched '%c'", c);
|
||||
}
|
||||
#endif
|
||||
tok->level--;
|
||||
#ifndef PGEN
|
||||
int opening = tok->parenstack[tok->level];
|
||||
if (!((opening == '(' && c == ')') ||
|
||||
(opening == '[' && c == ']') ||
|
||||
(opening == '{' && c == '}')))
|
||||
{
|
||||
if (tok->parenlinenostack[tok->level] != tok->lineno) {
|
||||
return syntaxerror(tok,
|
||||
"closing parenthesis '%c' does not match "
|
||||
"opening parenthesis '%c' on line %d",
|
||||
c, opening, tok->parenlinenostack[tok->level]);
|
||||
}
|
||||
else {
|
||||
return syntaxerror(tok,
|
||||
"closing parenthesis '%c' does not match "
|
||||
"opening parenthesis '%c'",
|
||||
c, opening);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ extern "C" {
|
|||
#include "token.h" /* For token types */
|
||||
|
||||
#define MAXINDENT 100 /* Max indentation level */
|
||||
#define MAXLEVEL 200 /* Max parentheses level */
|
||||
|
||||
enum decoding_state {
|
||||
STATE_INIT,
|
||||
|
|
@ -39,14 +40,16 @@ struct tok_state {
|
|||
int lineno; /* Current line number */
|
||||
int level; /* () [] {} Parentheses nesting level */
|
||||
/* Used to allow free continuations inside them */
|
||||
/* Stuff for checking on different tab sizes */
|
||||
#ifndef PGEN
|
||||
char parenstack[MAXLEVEL];
|
||||
int parenlinenostack[MAXLEVEL];
|
||||
/* pgen doesn't have access to Python codecs, it cannot decode the input
|
||||
filename. The bytes filename might be kept, but it is only used by
|
||||
indenterror() and it is not really needed: pgen only compiles one file
|
||||
(Grammar/Grammar). */
|
||||
PyObject *filename;
|
||||
#endif
|
||||
/* Stuff for checking on different tab sizes */
|
||||
int altindstack[MAXINDENT]; /* Stack of alternate indents */
|
||||
/* Stuff for PEP 0263 */
|
||||
enum decoding_state decoding_state;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue