Skip to content
96 changes: 53 additions & 43 deletions source/preprocessor.tex
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@

\begin{bnf}
\nontermdef{control-line}\br
\terminal{\# include} pp-tokens new-line\br
include-directive\br
pp-import\br
\terminal{\# embed \ } pp-tokens new-line\br
embed-directive\br
\terminal{\# define } identifier replacement-list new-line\br
\terminal{\# define } identifier lparen \opt{identifier-list} \terminal{)} replacement-list new-line\br
\terminal{\# define } identifier lparen \terminal{... )} replacement-list new-line\br
Expand Down Expand Up @@ -132,47 +132,6 @@
preprocessing-token \opt{pp-tokens}
\end{bnf}

\begin{bnf}
\nontermdef{embed-parameter-seq}\br
embed-parameter \opt{embed-parameter-seq}
\end{bnf}

\begin{bnf}
\nontermdef{embed-parameter}\br
embed-standard-parameter\br
embed-prefixed-parameter
\end{bnf}

\begin{bnf}
\nontermdef{embed-standard-parameter}\br
\terminal{limit} \terminal{(} pp-balanced-token-seq \terminal{)}\br
\terminal{prefix} \terminal{(} \opt{pp-balanced-token-seq} \terminal{)}\br
\terminal{suffix} \terminal{(} \opt{pp-balanced-token-seq} \terminal{)}\br
\terminal{if_empty} \terminal{(} \opt{pp-balanced-token-seq} \terminal{)}
\end{bnf}

\begin{bnf}
\nontermdef{embed-prefixed-parameter}\br
identifier :: identifier\br
identifier :: identifier \terminal{(} \opt{pp-balanced-token-seq} \terminal{)}
\end{bnf}

\begin{bnf}
\nontermdef{pp-balanced-token-seq}\br
pp-balanced-token \opt{pp-balanced-token-seq}
\end{bnf}

\begin{bnf}
\nontermdef{pp-balanced-token}\br
\terminal{(} \opt{pp-balanced-token-seq} \terminal{)}\br
\terminal{[} \opt{pp-balanced-token-seq} \terminal{]}\br
\terminal{\{} \opt{pp-balanced-token-seq} \terminal{\}}\br
\textnormal{any} pp-token \textnormal{except:}\br
\bnfindent\textnormal{parenthesis (\unicode{0028}{left parenthesis} and \unicode{0029}{right parenthesis}),}\br
\bnfindent\textnormal{bracket (\unicode{005b}{left square bracket} and \unicode{005d}{right square bracket}), or}\br
\bnfindent\textnormal{brace (\unicode{007b}{left curly bracket} and \unicode{007d}{right curly bracket}).}
\end{bnf}

\begin{bnf}
\nontermdef{new-line}\br
\descr{the new-line character}
Expand Down Expand Up @@ -685,6 +644,11 @@
\indextext{inclusion!source file|see{preprocessing directive, source-file inclusion}}%
\indextext{\idxcode{\#include}}%

\begin{bnf}
\nontermdef{include-directive}\br
\terminal{\# include} pp-tokens new-line\br
\end{bnf}

\pnum
A \defnadj{header}{search} for a sequence of characters
searches a sequence of places for a header
Expand Down Expand Up @@ -838,6 +802,52 @@
\indextext{preprocessing directive!embed a resource}
\indextext{\idxcode{\#embed}}%

\begin{bnf}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This gets us a "hanging paragraph" in ISO parlance (text directly in a subsection that also has further sub-subsections).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I based the diff on related existing code. There's for example a recent commit that did the same thing, I believe:

commit 2c473cc8744fc5b2077349add2283826061ce881
Author: Jens Maurer <Jens.Maurer@gmx.net>
Date:   2025-11-09 20:46:24 +0100

    P3868R1 Allow #line before module declarations
    
    Fixes NB US 55-102 (C++26 CD).
    
    Editorial note:
    * Retained position of #line alternative within control-line.

diff --git a/source/preprocessor.tex b/source/preprocessor.tex
index 487c0360..e449e830 100644
--- a/source/preprocessor.tex
+++ b/source/preprocessor.tex
@@ -16,11 +16,11 @@
     module-file
 \end{bnf}
 
 \begin{bnf}
 \nontermdef{module-file}\br
-    \opt{pp-global-module-fragment} pp-module \opt{group} \opt{pp-private-module-fragment}
+    \opt{line-directives} \opt{pp-global-module-fragment} pp-module \opt{group} \opt{pp-private-module-fragment}
 \end{bnf}
 
 \begin{bnf}
 \nontermdef{pp-global-module-fragment}\br
     \keyword{module} \terminal{;} new-line \opt{group}
@@ -53,17 +53,22 @@
     \terminal{\# define } identifier replacement-list new-line\br
     \terminal{\# define } identifier lparen \opt{identifier-list} \terminal{)} replacement-list new-line\br
     \terminal{\# define } identifier lparen \terminal{... )} replacement-list new-line\br
     \terminal{\# define } identifier lparen identifier-list \terminal{, ... )} replacement-list new-line\br
     \terminal{\# undef \ } identifier new-line\br
-    \terminal{\# line \ \ } pp-tokens new-line\br
+    line-directive\br
     \terminal{\# error \ } \opt{pp-tokens} new-line\br
     \terminal{\# warning} \opt{pp-tokens} new-line\br
     \terminal{\# pragma } \opt{pp-tokens} new-line\br
     \terminal{\# }new-line
 \end{bnf}
 
+\begin{bnf}
+\nontermdef{line-directives}\br
+    line-directive \opt{line-directives}
+\end{bnf}
+
 \begin{bnf}
 \nontermdef{if-section}\br
     if-group \opt{elif-groups} \opt{else-group} endif-line
 \end{bnf}
 
@@ -2060,10 +2065,15 @@ a macro name.
 
 \rSec1[cpp.line]{Line control}%
 \indextext{preprocessing directive!line control}%
 \indextext{\idxcode{\#line}|see{preprocessing directive, line control}}
 
+\begin{bnf}
+\nontermdef{line-directive}\br
+    \terminal{\# line} pp-tokens new-line
+\end{bnf}
+
 \pnum
 The \grammarterm{string-literal} of a
 \tcode{\#line}
 directive, if present,
 shall be a character string literal.

Am I missing something?

Copy link
Copy Markdown
Author

@alejandro-colomar alejandro-colomar May 13, 2026

Choose a reason for hiding this comment

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

Oh, now I see. Embed has subsections, while the others don't. What do you suggest? I don't know what should be done here. Is there any part of the standard that I could imitate for this?

Maybe put it in General (cpp.embed.gen)?

\nontermdef{embed-directive}\br
\terminal{\# embed \ } pp-tokens new-line\br
\end{bnf}

\begin{bnf}
\nontermdef{embed-parameter-seq}\br
embed-parameter \opt{embed-parameter-seq}
\end{bnf}

\begin{bnf}
\nontermdef{embed-parameter}\br
embed-standard-parameter\br
embed-prefixed-parameter
\end{bnf}

\begin{bnf}
\nontermdef{embed-standard-parameter}\br
\terminal{limit} \terminal{(} pp-balanced-token-seq \terminal{)}\br
\terminal{prefix} \terminal{(} \opt{pp-balanced-token-seq} \terminal{)}\br
\terminal{suffix} \terminal{(} \opt{pp-balanced-token-seq} \terminal{)}\br
\terminal{if_empty} \terminal{(} \opt{pp-balanced-token-seq} \terminal{)}
\end{bnf}

\begin{bnf}
\nontermdef{embed-prefixed-parameter}\br
identifier :: identifier\br
identifier :: identifier \terminal{(} \opt{pp-balanced-token-seq} \terminal{)}
\end{bnf}

\begin{bnf}
\nontermdef{pp-balanced-token-seq}\br
pp-balanced-token \opt{pp-balanced-token-seq}
\end{bnf}

\begin{bnf}
\nontermdef{pp-balanced-token}\br
\terminal{(} \opt{pp-balanced-token-seq} \terminal{)}\br
\terminal{[} \opt{pp-balanced-token-seq} \terminal{]}\br
\terminal{\{} \opt{pp-balanced-token-seq} \terminal{\}}\br
\textnormal{any} pp-token \textnormal{except:}\br
\bnfindent\textnormal{parenthesis (\unicode{0028}{left parenthesis} and \unicode{0029}{right parenthesis}),}\br
\bnfindent\textnormal{bracket (\unicode{005b}{left square bracket} and \unicode{005d}{right square bracket}), or}\br
\bnfindent\textnormal{brace (\unicode{007b}{left curly bracket} and \unicode{007d}{right curly bracket}).}
\end{bnf}

\rSec2[cpp.embed.gen]{General}

\pnum
Expand Down