bpo-40939: Generate keyword.py using the new parser (GH-20800)

This commit is contained in:
Lysandros Nikolaou 2020-06-11 15:45:15 +03:00 committed by GitHub
parent 33faf5c4f4
commit 9727694f08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 9 deletions

View File

@ -1,11 +1,12 @@
"""Keywords (from "Grammar/Grammar") """Keywords (from "Grammar/python.gram")
This file is automatically generated; please don't muck it up! This file is automatically generated; please don't muck it up!
To update the symbols in this file, 'cd' to the top directory of To update the symbols in this file, 'cd' to the top directory of
the python source tree and run: the python source tree and run:
python3 -m Parser.pgen.keywordgen Grammar/Grammar \ PYTHONPATH=Tools/peg_generator python3 -m pegen.keywordgen \
Grammar/Grammar \
Grammar/Tokens \ Grammar/Tokens \
Lib/keyword.py Lib/keyword.py
@ -18,6 +19,7 @@ kwlist = [
'False', 'False',
'None', 'None',
'True', 'True',
'__new_parser__',
'and', 'and',
'as', 'as',
'assert', 'assert',

View File

@ -1817,6 +1817,7 @@ class Helper:
'False': '', 'False': '',
'None': '', 'None': '',
'True': '', 'True': '',
'__new_parser__': '',
'and': 'BOOLEAN', 'and': 'BOOLEAN',
'as': 'with', 'as': 'with',
'assert': ('assert', ''), 'assert': ('assert', ''),

View File

@ -895,9 +895,10 @@ regen-token:
.PHONY: regen-keyword .PHONY: regen-keyword
regen-keyword: regen-keyword:
# Regenerate Lib/keyword.py from Grammar/Grammar and Grammar/Tokens # Regenerate Lib/keyword.py from Grammar/python.gram and Grammar/Tokens
# using Parser/pgen # using Tools/peg_generator/pegen
PYTHONPATH=$(srcdir) $(PYTHON_FOR_REGEN) -m Parser.pgen.keywordgen $(srcdir)/Grammar/Grammar \ PYTHONPATH=$(srcdir)/Tools/peg_generator $(PYTHON_FOR_REGEN) -m pegen.keywordgen \
$(srcdir)/Grammar/python.gram \
$(srcdir)/Grammar/Tokens \ $(srcdir)/Grammar/Tokens \
$(srcdir)/Lib/keyword.py.new $(srcdir)/Lib/keyword.py.new
$(UPDATE_FILE) $(srcdir)/Lib/keyword.py $(srcdir)/Lib/keyword.py.new $(UPDATE_FILE) $(srcdir)/Lib/keyword.py $(srcdir)/Lib/keyword.py.new

View File

@ -0,0 +1 @@
Use the new PEG parser when generating the stdlib :mod:`keyword` module.

View File

@ -205,8 +205,9 @@
<Exec Command="&quot;$(PythonExe)&quot; $(PySourcePath)Tools\scripts\generate_token.py py &quot;$(PySourcePath)Grammar\Tokens&quot; &quot;$(PySourcePath)Lib\token.py&quot;" /> <Exec Command="&quot;$(PythonExe)&quot; $(PySourcePath)Tools\scripts\generate_token.py py &quot;$(PySourcePath)Grammar\Tokens&quot; &quot;$(PySourcePath)Lib\token.py&quot;" />
</Target> </Target>
<Target Name="_RegenKeywords" AfterTargets="_RegenTokens"> <Target Name="_RegenKeywords" AfterTargets="_RegenTokens">
<!-- Regenerate Lib/keyword.py from Grammar/Grammar and Grammar/Tokens using Parser/pgen--> <!-- Regenerate Lib/keyword.py from Grammar/python.gram and Grammar/Tokens using Tools/peg_generator/pegen-->
<Exec Command="&quot;$(PythonExe)&quot; -m Parser.pgen.keywordgen &quot;$(PySourcePath)Grammar\Grammar&quot; &quot;$(PySourcePath)Grammar\Tokens&quot; &quot;$(IntDir)keyword.py&quot;" /> <SetEnv Name="PYTHONPATH" Prefix="true" Value="$(PySourcePath)Tools\peg_generator\" />
<Exec Command="&quot;$(PythonExe)&quot; -m pegen.keywordgen &quot;$(PySourcePath)Grammar\python.gram&quot; &quot;$(PySourcePath)Grammar\Tokens&quot; &quot;$(IntDir)keyword.py&quot;" />
<Copy SourceFiles="$(IntDir)keyword.py" DestinationFiles="$(PySourcePath)Lib\keyword.py"> <Copy SourceFiles="$(IntDir)keyword.py" DestinationFiles="$(PySourcePath)Lib\keyword.py">
<Output TaskParameter="CopiedFiles" ItemName="_Updated" /> <Output TaskParameter="CopiedFiles" ItemName="_Updated" />
</Copy> </Copy>

View File

@ -0,0 +1,73 @@
"""Generate Lib/keyword.py from the Grammar and Tokens files using pgen"""
import argparse
from .build import build_parser, generate_token_definitions
from .c_generator import CParserGenerator
TEMPLATE = r'''
"""Keywords (from "Grammar/python.gram")
This file is automatically generated; please don't muck it up!
To update the symbols in this file, 'cd' to the top directory of
the python source tree and run:
PYTHONPATH=Tools/peg_generator python3 -m pegen.keywordgen \
Grammar/Grammar \
Grammar/Tokens \
Lib/keyword.py
Alternatively, you can run 'make regen-keyword'.
"""
__all__ = ["iskeyword", "kwlist"]
kwlist = [
{keywords}
]
iskeyword = frozenset(kwlist).__contains__
'''.lstrip()
EXTRA_KEYWORDS = ["async", "await"]
def main():
parser = argparse.ArgumentParser(
description="Generate the Lib/keywords.py file from the grammar."
)
parser.add_argument(
"grammar", type=str, help="The file with the grammar definition in PEG format"
)
parser.add_argument(
"tokens_file",
type=argparse.FileType("r"),
help="The file with the token definitions"
)
parser.add_argument(
"keyword_file",
type=argparse.FileType("w"),
help="The path to write the keyword definitions",
)
args = parser.parse_args()
grammar, _, _ = build_parser(args.grammar)
with args.tokens_file as tok_file:
all_tokens, exact_tok, non_exact_tok = generate_token_definitions(tok_file)
gen: ParserGenerator = CParserGenerator(
grammar, all_tokens, exact_tok, non_exact_tok, file=None
)
gen.collect_todo()
with args.keyword_file as thefile:
all_keywords = sorted(
list(gen.callmakervisitor.keyword_cache.keys()) + EXTRA_KEYWORDS
)
keywords = ",\n ".join(map(repr, all_keywords))
thefile.write(TEMPLATE.format(keywords=keywords))
if __name__ == "__main__":
main()