Reputation: 2101
In the C++ draft standard in:
There are mentions of these terms import-keyword
, module-keyword
and, export-keyword
.
In the grammer section I'm not really sure how its possible that as per A.1 General
"the grammar described here accepts a superset of valid C++ constructs."
It seems like the grammer for these isn't defined in this appendix.
It may be addressed here:
4 In all three forms of pp-import, the import and export (if it exists) preprocessing tokens are replaced by the import-keyword and export-keyword preprocessing tokens respectively.
But I don't really know what that means in terms of grammer... What does that mean?
Some of the relevant grammer is here (hopefully I can help somebody get the nessary information without having to go all over the standard).
preprocessing-token:
header-name
import-keyword
module-keyword
export-keyword
identifier
pp-number
character-literal
user-defined-character-literal
string-literal
user-defined-string-literal
preprocessing-op-or-punc
each non-whitespace character that cannot be one of the above
keyword:
any identifier listed in Table 5
import-keyword
module-keyword
export-keyword
module-import-declaration:
import-keyword module-name attribute-specifier-seqopt ;
import-keyword module-partition attribute-specifier-seqopt ;
import-keyword header-name attribute-specifier-seqopt ;
control-line:
# include pp-tokens new-line pp-import
# define identifier replacement-list new-line
# define identifier lparen identifier-listopt ) replacement-list new-line
# define identifier lparen ... ) replacement-list new-line
pp-import:
exportopt import header-name pp-tokensopt ; new-line
exportopt import header-name-tokens pp-tokensopt ; new-line
exportopt import pp-tokens ; new-line
Upvotes: 2
Views: 1205
Reputation: 473926
You have all of the pieces there; you're just not looking at it correctly. Probably because of the term "keyword".
So let's start with pp-import
is not part of the grammar. This is not really C++ grammar per-se; it starts with "pp" because it's part of the preprocessor. The preprocessor is a thing that happens before the rest of the C++ grammar is applied to the text.
So pp-import
is a preprocessor directive, much like a macro definition (as is module-file
and its derivatives). Preprocessor directives usually govern the sequence of tokens generated for C++, and the module preprocessor directives are no different.
Section [cpp.import] defines what pp-import
looks like and what tokens it generates. So before preprocessing, you would have a sequence of text that looks like this: import "some_module.name"
. When the preprocessor recognizes this text as pp-import
, it will then generate the token sequence, import-keyword "some_module.name"
.
import-keyword
is the name of a specific token, just like if
or struct
. But unlike most such tokens, this token does not have a textual analog. That is, if
is the keyword generated when the compiler sees the text "if" in your code. That's not the case for import-keyword
. This token is only generated by the C++ preprocessor, and only from pp-import
preprocessing directives.
So the preprocessing directive pp-import
basically replaces the "import" text with the import-keyword
token. And the main C++ grammar recognizes the import-keyword
token, even though you can't write the text for that token.
But... why? Why all of this rigamarole of preprocessing directives and keywords that you can't type? Why not just make import
and module
work like any other keyword?
There are two reasons.
The words "module" and "import" are very frequently used as identifiers. By having the preprocessor convert module headers and import directives to use the non-human-writable tokens module-keyword
and import-keyword
, any uses of "module" and "import" outside of those directives allow them to just be identifiers. And thus, C++20 doesn't break tons and tons of code.
Or would you rather have to write co_module
;)
In a modular build system, you need a way to look at a file and quickly know what module it defines and which ones it imports. And you would rather not have to write a whole C++ parser just to do that, let alone take the time to run it on the entire text (which will be difficult, since you'll need to import all of those modules to make sense of it). By making module statements preprocessor directives first instead of just regular C++ grammar, you can simply use a C++ preprocessor to extract them all.
Upvotes: 5