Skip to content

Commit 5d7b4cf

Browse files
committed
gh-125588: Teach the python PEG generator the new f-string tokens
1 parent bee112a commit 5d7b4cf

File tree

5 files changed

+50
-2
lines changed

5 files changed

+50
-2
lines changed

Lib/test/test_peg_generator/test_pegen.py

+8
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,14 @@ def test_python_expr(self) -> None:
506506
val = eval(code)
507507
self.assertEqual(val, 3.0)
508508

509+
def test_f_string_in_action(self) -> None:
510+
grammar = """
511+
start: n=NAME NEWLINE? $ { f"name -> {n.string}" }
512+
"""
513+
parser_class = make_parser(grammar)
514+
node = parse_string("a", parser_class)
515+
self.assertEqual(node.strip(), "name -> a")
516+
509517
def test_nullable(self) -> None:
510518
grammar_source = """
511519
start: sign NUMBER

Tools/peg_generator/pegen/grammar_parser.py

+16-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/peg_generator/pegen/metagrammar.gram

+3
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ target_atom[str]:
126126
| NAME { name.string }
127127
| NUMBER { number.string }
128128
| STRING { string.string }
129+
| FSTRING_START { fstring_start.string }
130+
| FSTRING_MIDDLE { fstring_middle.string }
131+
| FSTRING_END { fstring_end.string }
129132
| "?" { "?" }
130133
| ":" { ":" }
131134
| !"}" !"]" OP { op.string }

Tools/peg_generator/pegen/parser.py

+21
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,27 @@ def string(self) -> Optional[tokenize.TokenInfo]:
205205
return self._tokenizer.getnext()
206206
return None
207207

208+
@memoize
209+
def fstring_start(self) -> Optional[tokenize.TokenInfo]:
210+
tok = self._tokenizer.peek()
211+
if tok.type == token.FSTRING_START:
212+
return self._tokenizer.getnext()
213+
return None
214+
215+
@memoize
216+
def fstring_middle(self) -> Optional[tokenize.TokenInfo]:
217+
tok = self._tokenizer.peek()
218+
if tok.type == token.FSTRING_MIDDLE:
219+
return self._tokenizer.getnext()
220+
return None
221+
222+
@memoize
223+
def fstring_end(self) -> Optional[tokenize.TokenInfo]:
224+
tok = self._tokenizer.peek()
225+
if tok.type == token.FSTRING_END:
226+
return self._tokenizer.getnext()
227+
return None
228+
208229
@memoize
209230
def op(self) -> Optional[tokenize.TokenInfo]:
210231
tok = self._tokenizer.peek()

Tools/peg_generator/pegen/python_generator.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ def visit_NameLeaf(self, node: NameLeaf) -> Tuple[Optional[str], str]:
9999
name = node.value
100100
if name == "SOFT_KEYWORD":
101101
return "soft_keyword", "self.soft_keyword()"
102-
if name in ("NAME", "NUMBER", "STRING", "OP", "TYPE_COMMENT"):
102+
if name in ("NAME", "NUMBER", "STRING", "OP", "TYPE_COMMENT",
103+
"FSTRING_END", "FSTRING_MIDDLE", "FSTRING_START"):
103104
name = name.lower()
104105
return name, f"self.{name}()"
105106
if name in ("NEWLINE", "DEDENT", "INDENT", "ENDMARKER"):

0 commit comments

Comments
 (0)