-
Notifications
You must be signed in to change notification settings - Fork 4
Rough draft of Section 3.5 conditionals: #if, #elif, etc. #61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Apparently, Gary does not know how to do a squash commit. |
From email sent to the team, which may be useful for reviewers: This PR covers only the directives in the #if family. As these directives are highly interdependent, I didn’t write a separate section on each directive. Instead, there is a single omnibus illustrative syntax that includes all the directives, and the order and quantity in which they can appear. As with the other directives, there is a subsection on the “static semantics”, the rules that must be followed in the form the directives take. It covers loosely the proper nesting of conditional directives. There is also the customary subsection on “evaluation semantics”: what happens when we act on the directives. Nesting syntax and semantics get a bit complicated. There is some text about that, but it is not as formal as I would like. (I may have to wait until the syntax paper to spell it out in detail.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My initial rough review of the rough draft ;-)
if10: Whitespace must immediately follow the directives tokens | ||
'ifdef', 'ifndef', 'elifdef', and 'elifndef' to separate them | ||
from the ID tokens. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This property is roughly true for (nearly?) every preprocessing directive, not even just those in this section. Stating it here for only three makes them seem like an exception. (I say roughly because what's actually required is a token boundary, which might or might not include whitespace)
I think what we actually mean here is that standard directives are only recognized as such if the token immediately following the #
introducing a directive line exactly matches one of the standard directive names. If it does not match for any reason (e.g. due to lack of whitespace) then the directive does not conform to one of the standard directives and is instead parsed as a processor-dependent directive.
We should probably directly state something to this effect in section 3.0 and then delete this rule.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Section 2.3 is titled "Significance of whitespace" - would this fit there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought I replied that Section 2.3 seems like an excellent place for it. I will generate a pull request for section 2 for this. See PR #64, up for review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try some phrasing like "I think what we actually mean here is that standard directives are only recognized as such if the token immediately following the # introducing a directive line exactly matches one of the standard directive names."
if35. As shown in the illustrative syntax, there should be no | ||
unmatched #endif directives. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This property can be directly derived from the pseudo-grammar above, so repeating it here is redundant. Worse, we only state one such property but omit others, for example:
- there should be no
<if-head>
without a matching#endif
, - there should be no
<if-elif>
without a matching<if-head>
and#endif
, - there should be no
#else
without a matching<if-head>
and#endif
,
which makes this one seem like an outlier. We should either list all such analogous grammatical properties or none.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm OK with letting the grammar speak for itself here, as long as we believe J3 as a whole won't feel like it's under-specified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove if35.
ix30. If the controlling expression in a #if evaluates to a nonzero | ||
value, the <lines> immediately following the #if participate in | ||
preprocessing. They are subject to preprocessing expansion, | ||
substitution, and evaluation of processing directives in the | ||
<lines>. | ||
|
||
ix40. Further preprocessing when #if controlling expression evaluates | ||
to a nonzero value proceeds. Subsequent #elif and #else | ||
directives at the same level of nesting are skipped, and do not | ||
participate in preprocessing except to be examined for proper | ||
nesting of conditional directives. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unhappy with the structure of how we describe the controlled <lines>
here and in the subsequent rules.
In particular, the definition of phrases like " immediately following the #if" and " immediately following the #elif" is too ambiguous, especially if those <lines>
themselves contain directives (and possibly nested conditionals).
I think we should instead use the grammar non-terminals to help make this more precise. For example:
ix30. If the controlling expression in a #if evaluates to a nonzero | |
value, the <lines> immediately following the #if participate in | |
preprocessing. They are subject to preprocessing expansion, | |
substitution, and evaluation of processing directives in the | |
<lines>. | |
ix40. Further preprocessing when #if controlling expression evaluates | |
to a nonzero value proceeds. Subsequent #elif and #else | |
directives at the same level of nesting are skipped, and do not | |
participate in preprocessing except to be examined for proper | |
nesting of conditional directives. | |
ix30. If the controlling expression in an <if-head> construct evaluates to a nonzero | |
value, then the <lines> contained within that <if-head> construct participate in | |
preprocessing. They are subject to preprocessing expansion, | |
substitution, and evaluation of processing directives in those | |
<lines>. | |
ix40. Further preprocessing when an <if-head> controlling expression evaluates | |
to a nonzero value proceeds. Subsequent <if-elif> and <if-else> | |
constructs at the same level of nesting are skipped, and the <lines> | |
contained within those constructs do not participate in preprocessing | |
except to be examined for proper nesting of conditional directives. |
and similarly for the next four rules.
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like these updates to the phrasing. I am OK committing the phrasing for this one as suggested, and then updating the PR with new commits to add changes for the remaining rules.
Better yet, Dan could make the suggestions for the other rules, and then get credit for the contribution. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will make these changes. And others, regarding use of [ ]
for optional things, and -list for lists.
See F2023 §4.1.3 for rules we should use.
Co-authored-by: Dan Bonachea <dobonachea@lbl.gov>
Co-authored-by: Dan Bonachea <dobonachea@lbl.gov>
Co-authored-by: Dan Bonachea <dobonachea@lbl.gov>
respectively. | ||
|
||
ix15. The token-lists in #if and #elif are processed as described in | ||
the section "Macro recognition and expansion". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As noted in the meeting, we also need to clarify whether macro expansion occurs within an #elif
directive line if we already know that "group" is being skipped
Within these lines, no token expansion occurs, and no Fortran | ||
comment lines nor source lines are made available for subsequent | ||
processing by the processor. Preprocessing continues with any |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to specifically call out that macros in the body are not evaluated in any way, in addition to the lack of expansion and source lines? I'm thinking of things like #error
, #warning
, and #pragma
which aren't really about token expansion or source lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. We should be clear that in the skipped lines,
- Nested conditional directives are recognized but no evaluated
- No other directives are evaluated
- No macro expansion occurs
- No directive lines, Fortran source lines, or Fortran comment lines are made available for subsequent processing
To Dan's point about nesting, maybe we can omit that first bullet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure that skipped parts act as if they aren't there, and have no effect on the preprocessing.
Initial draft of Section 3.5. Added illustrative syntax, static semantics and evaluation semantics, up to but not including controlling expression evaluation. (That will be an another section.)
I tried to use the terminology from the C 2023 standard, but reviewers will surely find lapses and potential improvements.