Skip to content

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

gklimowicz
Copy link
Member

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.

@gklimowicz
Copy link
Member Author

Apparently, Gary does not know how to do a squash commit.

@gklimowicz
Copy link
Member Author

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.)

Copy link
Collaborator

@bonachea bonachea left a 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 ;-)

Comment on lines +453 to +455
if10: Whitespace must immediately follow the directives tokens
'ifdef', 'ifndef', 'elifdef', and 'elifndef' to separate them
from the ID tokens.
Copy link
Collaborator

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.

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?

Copy link
Member Author

@gklimowicz gklimowicz May 7, 2025

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.

Copy link
Member Author

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."

Comment on lines +470 to +471
if35. As shown in the illustrative syntax, there should be no
unmatched #endif directives.
Copy link
Collaborator

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:

  1. there should be no <if-head> without a matching #endif,
  2. there should be no <if-elif> without a matching <if-head> and #endif,
  3. 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.

Copy link
Member Author

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove if35.

Comment on lines +504 to +514
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.
Copy link
Collaborator

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:

Suggested change
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?

Copy link
Member Author

@gklimowicz gklimowicz May 7, 2025

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. :-)

Copy link
Member Author

@gklimowicz gklimowicz May 12, 2025

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.

respectively.

ix15. The token-lists in #if and #elif are processed as described in
the section "Macro recognition and expansion".
Copy link
Collaborator

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

Comment on lines +519 to +521
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
Copy link
Collaborator

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.

Copy link
Member Author

@gklimowicz gklimowicz May 7, 2025

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.

Copy link
Member Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants