Bart <
bc@freeuk.com> wrote:
On 07/12/2024 11:34, Janis Papanagnou wrote:
On 06.12.2024 02:20, Bart wrote:
I used to be puzzled by this too: 'while' can both start a while
statement, and it can delimit a do-while statement. How is that possible?
A keyword (like 'while') is just a lexical token that can be used in
different syntactical contexts.
Is it common to both start and end a statememt with the same keyword?
Technically, 'do' loop ends in a semicolon. Rule is
do secondary-block while ( expression ) ;
with explicit semicolon at the end.
'while' loop do not have any special symbol marking its end.
Grammar for 'while' is
while ( expression ) secondary-block
and it ends where 'secondary-block' ends which may be a semicolon
but may be also a brace.
Concerning "start and end a statememt with the same keyword",
this is clearly common when statement consist of a single
symbol, like empty statement in many langages, including C and
Algol68 (we could split hairs if statment containing no symbols
like empty statement in Pascal starts and ends in the same keyword).
If you look at multi-symbol statements, then 'do' and 'while'
loop are not an example: 'while' loop starts with 'while',
'do' loop starts in 'do' and AFAICS neither 'while' nor 'do'
can end a statement.
(Even with different semantics, if a
language designer thinks this is a good idea for his case.)
You may be less confused with using Pascal;
Now you are demonstrating my point about being treated like a beginner.
And it is exasperating.
This is a point of language design. C's approach works - just. But it
relies on some subtlety. 'while (cond)' both starts a statement, and can
end a statement:
do while(cond) do ; while (cond);
The second 'while' here starts a nested while-loop inside a do-while
loop. Not confusing? It is to me! I couldn't finish my example as I got
lost (but as it happens, this is valid code, partly by luck).
I think it was already noted that this is not a valid C statement.
do while(cond) ; while (cond);
is valid, and indeed may be confusing to humans. But people
would normally write it as
do {
while(cond) ;
} while (cond);
or even
do {
while(cond) {
;
}
} while (cond);
to stress that inner loop is "do nothing" loop. In this form
structure is clear.
If you want human-oriented rule for parsing badly written code,
you may notice that body of a C loop can not be syntactually
empty, you need at least a semicolon. So first 'while'
after 'do' must start an inner loop.
Concerning "subtle", note that changing say '*' to '+' can
signifcantly change parse tree and semantics in almost any
programming language. Most people are not bothered by this
and take care when writing/reading operators. Similarly
C programmers are careful when writing/reading semicolons.
You can design a laguage with more redundancy. For example
one of languages that I use has
if cond then expr1 else expr2 endif
while cond do expr endwhile
repeat expr endrepeat
and similar ('repeat' formally is na infinite loop, but may
contain inside constructs that exit the loop). But redundancy
means that language is more wordy. C designers choose a
compromise, braced C versions still have less non-space
characters than the above and are quite clear. Of course,
some people want to save typing braces, C allows that.
If you skip braces and add meaningful indentation, then
you again get enough redundancy to easily parse this in
your head. Disadvantage of indentation alone is that it
may get out of sync with the code structure, but as noted
'gcc' can warn about this. Some folks have editor macros
that automatically insert braces and/or indent code in similar
situations, then amount of typing is the same.
-- Waldek Hebisch