Date: Fri, 2 Apr 2021 23:06:40 +0800 From: konsolebox <konsole...@gmail.com> Message-ID: <cajnmqwzy2v4cxnm1ai4addhj1dxcqo67dj3pk-uemn6ihsn...@mail.gmail.com>
| > The right question would be why '} else' works. | | This inconsistency should be fixed and prevent people from | using it wrong. `}; else` should work Yes. | but not `} else` No, that should work too. The "then" part of an if statement (which is what the '}' is the last element of in that example, obviously, takes a list if_clause : If compound_list Then compound_list else_part Fi and the list (compound_list in posix speak) can be compound_list : linebreak term where linebreak is an optional newline (but is before the term anyway so isn't relevant here as we're looking at the ending, not the beginning) and term can be term : and_or and and-or can be and_or : pipeline and pipeline can be pipeline : pipe_sequence and pipe_sequence can be pipe_sequence : command and command can be command : compound_command and compound_command can be compound_command : brace_group and brace_group is brace_group : Lbrace compound_list Rbrace ; Observe that following that sequence, there is no separator (';' etc) required between the Rbrace ('}') that terminates the brace_group which is the compound_command which is the command which is the pipe_sequence which is the pipeline which is the and_or which is the term which is the last thing in the compound_list after which "else" follows immediately. Of course, all the "can be" rules above have alternatives, other things are possible, in particular, the full rule for compound_list is compound_list : linebreak term | linebreak term separator ; so it is obvious (very obvious) that a separator is allowed after the term, but not required. | just like how `{ :; } :` doesn't. That is an entirely different thing. ':' isn't a reserved word, so the reserved word rule isn't relevant, and sequential commands (like the group, and the second ':' in that example) need to be separated by some kind of separator (';' '&' or newline). And from your other message: | That's not a rule but a special compromise. No, it is a rule, it is required to allow the 'else' in the example above to be a reserved word, otherwise it would just be a normal word, and that would be a syntax error. | [[ ]] and (( )) are a form of reserved words themselves Those are bash specials, and I am fairly sure that (( and )) will be operators, not reserved words (they cannot really be the latter, as ( and ) are operators) and I suspect that [[ and ]] might be as well, but there I'm not sure. operators and reserved words are quite different things. Operators (unquoted) are recognised as themselves wherever they appear. | just like () and {} '(' and ')' are operators. '{' and '}' are reserved words. | as they can be used multi-line but That has nothing to do with anything. Anywhere where the grammar allows linebreak or separator (maybe more) can be used multi-line. Anwhere those things are not in the grammar, line breaks (not counting \newline or quoted newlines) are not permitted. | but they aren't allowed to be adjacent to else et al without a semicolon. Nonsense. | practically just commands with first-class parsing that consistently | have to end with a semicolon No, they don't (even if you extend semicolon to include ampersand and newline). | if followed by another reserved word or command if followed by another command yes, as the separator is just that, a separator, it separates different commands, it is not a terminator (unlike the ';' in C expression statements for example). Where reserved words are allowed entirely depends upon what the grammar allows. And as above, "} else {" is a perfectly valid sequence as part of an "if" statement. kre