@@ -929,7 +929,7 @@ fstring_middle[expr_ty]:
929929fstring_replacement_field[expr_ty]:
930930 | '{' a=annotated_rhs debug_expr='='? conversion=[fstring_conversion] format=[fstring_full_format_spec] rbrace='}' {
931931 _PyPegen_formatted_value(p, a, debug_expr, conversion, format, rbrace, EXTRA) }
932- | invalid_replacement_field
932+ | invalid_fstring_replacement_field
933933fstring_conversion[ResultTokenWithMetadata*]:
934934 | conv_token="!" conv=NAME { _PyPegen_check_fstring_conversion(p, conv_token, conv) }
935935fstring_full_format_spec[ResultTokenWithMetadata*]:
@@ -940,10 +940,19 @@ fstring_format_spec[expr_ty]:
940940fstring[expr_ty]:
941941 | a=FSTRING_START b=fstring_middle* c=FSTRING_END { _PyPegen_joined_str(p, a, (asdl_expr_seq*)b, c) }
942942
943+ tstring_format_spec_replacement_field[expr_ty]:
944+ | '{' a=annotated_rhs debug_expr='='? conversion=[fstring_conversion] format=[tstring_full_format_spec] rbrace='}' {
945+ _PyPegen_formatted_value(p, a, debug_expr, conversion, format, rbrace, EXTRA) }
946+ | invalid_tstring_replacement_field
947+ tstring_format_spec[expr_ty]:
948+ | t=FSTRING_MIDDLE { _PyPegen_decoded_constant_from_token(p, t) }
949+ | tstring_format_spec_replacement_field
950+ tstring_full_format_spec[ResultTokenWithMetadata*]:
951+ | colon=':' spec=tstring_format_spec* { _PyPegen_setup_full_format_spec(p, colon, (asdl_expr_seq *) spec, EXTRA) }
943952tstring_replacement_field[expr_ty]:
944- | '{' a=annotated_rhs debug_expr='='? conversion=[fstring_conversion] format=[fstring_full_format_spec ] rbrace='}' {
953+ | '{' a=annotated_rhs debug_expr='='? conversion=[fstring_conversion] format=[tstring_full_format_spec ] rbrace='}' {
945954 _PyPegen_interpolation(p, a, debug_expr, conversion, format, rbrace, EXTRA) }
946- | invalid_replacement_field
955+ | invalid_tstring_replacement_field
947956tstring_middle[expr_ty]:
948957 | tstring_replacement_field
949958 | t=FSTRING_MIDDLE { _PyPegen_constant_from_token(p, t) }
@@ -1458,39 +1467,49 @@ invalid_starred_expression_unpacking:
14581467invalid_starred_expression:
14591468 | '*' { RAISE_SYNTAX_ERROR("Invalid star expression") }
14601469
1461- invalid_replacement_field:
1462- | '{' a='=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "%c-string: valid expression required before '='",
1463- TOK_GET_MODE(p->tok)->tstring ? 't' : 'f') }
1464- | '{' a='!' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "%c-string: valid expression required before '!'",
1465- TOK_GET_MODE(p->tok)->tstring ? 't' : 'f') }
1466- | '{' a=':' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "%c-string: valid expression required before ':'",
1467- TOK_GET_MODE(p->tok)->tstring ? 't' : 'f') }
1468- | '{' a='}' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "%c-string: valid expression required before '}'",
1469- TOK_GET_MODE(p->tok)->tstring ? 't' : 'f') }
1470- | '{' !annotated_rhs { RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("%c-string: expecting a valid expression after '{'",
1471- TOK_GET_MODE(p->tok)->tstring ? 't' : 'f')}
1470+ invalid_fstring_replacement_field:
1471+ | '{' a='=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before '='") }
1472+ | '{' a='!' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before '!'") }
1473+ | '{' a=':' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before ':'") }
1474+ | '{' a='}' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before '}'") }
1475+ | '{' !annotated_rhs { RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: expecting a valid expression after '{'") }
14721476 | '{' annotated_rhs !('=' | '!' | ':' | '}') {
1473- PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("%c-string: expecting '=', or '!', or ':', or '}'",
1474- TOK_GET_MODE(p->tok)->tstring ? 't' : 'f') }
1477+ PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: expecting '=', or '!', or ':', or '}'") }
14751478 | '{' annotated_rhs '=' !('!' | ':' | '}') {
1476- PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("%c-string: expecting '!', or ':', or '}'",
1477- TOK_GET_MODE(p->tok)->tstring ? 't' : 'f') }
1478- | '{' annotated_rhs '='? invalid_conversion_character
1479+ PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: expecting '!', or ':', or '}'") }
1480+ | '{' annotated_rhs '='? invalid_fstring_conversion_character
14791481 | '{' annotated_rhs '='? ['!' NAME] !(':' | '}') {
1480- PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("%c-string: expecting ':' or '}'",
1481- TOK_GET_MODE(p->tok)->tstring ? 't' : 'f') }
1482+ PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: expecting ':' or '}'") }
14821483 | '{' annotated_rhs '='? ['!' NAME] ':' fstring_format_spec* !'}' {
1483- PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("%c-string: expecting '}', or format specs",
1484- TOK_GET_MODE(p->tok)->tstring ? 't' : 'f') }
1484+ PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: expecting '}', or format specs") }
14851485 | '{' annotated_rhs '='? ['!' NAME] !'}' {
1486- PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("%c-string: expecting '}'",
1487- TOK_GET_MODE(p->tok)->tstring ? 't' : 'f') }
1486+ PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: expecting '}'") }
1487+
1488+ invalid_fstring_conversion_character:
1489+ | '!' &(':' | '}') { RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: missing conversion character") }
1490+ | '!' !NAME { RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: invalid conversion character") }
1491+
1492+ invalid_tstring_replacement_field:
1493+ | '{' a='=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "t-string: valid expression required before '='") }
1494+ | '{' a='!' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "t-string: valid expression required before '!'") }
1495+ | '{' a=':' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "t-string: valid expression required before ':'") }
1496+ | '{' a='}' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "t-string: valid expression required before '}'") }
1497+ | '{' !annotated_rhs { RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("t-string: expecting a valid expression after '{'") }
1498+ | '{' annotated_rhs !('=' | '!' | ':' | '}') {
1499+ PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("t-string: expecting '=', or '!', or ':', or '}'") }
1500+ | '{' annotated_rhs '=' !('!' | ':' | '}') {
1501+ PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("t-string: expecting '!', or ':', or '}'") }
1502+ | '{' annotated_rhs '='? invalid_tstring_conversion_character
1503+ | '{' annotated_rhs '='? ['!' NAME] !(':' | '}') {
1504+ PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("t-string: expecting ':' or '}'") }
1505+ | '{' annotated_rhs '='? ['!' NAME] ':' fstring_format_spec* !'}' {
1506+ PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("t-string: expecting '}', or format specs") }
1507+ | '{' annotated_rhs '='? ['!' NAME] !'}' {
1508+ PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("t-string: expecting '}'") }
14881509
1489- invalid_conversion_character:
1490- | '!' &(':' | '}') { RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("%c-string: missing conversion character",
1491- TOK_GET_MODE(p->tok)->tstring ? 't' : 'f') }
1492- | '!' !NAME { RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("%c-string: invalid conversion character",
1493- TOK_GET_MODE(p->tok)->tstring ? 't' : 'f') }
1510+ invalid_tstring_conversion_character:
1511+ | '!' &(':' | '}') { RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("t-string: missing conversion character") }
1512+ | '!' !NAME { RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("t-string: invalid conversion character") }
14941513
14951514invalid_arithmetic:
14961515 | sum ('+'|'-'|'*'|'/'|'%'|'//'|'@') a='not' b=inversion { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "'not' after an operator must be parenthesized") }
0 commit comments