Semicolons are separators in Algol 60, Algol W, Simula 67,
Algol 68, and Pascal, also Pop-2, Pop-11, Prolog, Goedel,
Mercury, Strand88, Erlang, F# (for an unfortunate reason)
and (technically) Haskell. They are terminators in PL/I,
BSL, Hal-S, CHILL, C,
Objective C, C++, Objective C++, Ada, Java, JavaScript, …
In (modern) Fortran I suppose semicolon is a separator and
end-of-logical-line a terminator, just to confound things.
I am not sure how to quantify “most programming languages”.
Most code programmers are likely to meet these days
(I mean, how much code is written in Ur or Disciple?)
uses semicolons as terminators, because of all the language
designers who decided to imitate C.
Consider if (x == 1) {y = 2;}
The semicolon is not optional. There is no empty
statement between “;” and “}”. The semicolon is an
intrinsic part of the statement “y = 2;”. The
construct “y = 2” in C is NOT a statement. It is an
expression, and not a statement. So in C
if (x == 1) {y = 2}
is not “optimised”, it’s illegal.
Now Erlang does not have statements at all,
and does not admit empty expressions. So
the classification between separators and terminators
is easy: After , is another
or
- required? is a separator.
- forbidden? is a terminator.
Hence , ; | are separators and . is a terminator in Erlang.