In my programming language, AEC, unlike in Ada or VHDL, there is no semicolon after the EndIf token. That is, you can put the semicolon ; after EndIf if you want to, but you do not have to. I often put it so that ClangFormat does not get confused when formatting the code written in my programming language. When programming in VHDL, Ada or Pascal, it bothered me why I needed to put a semi-colon after end if (ADA and VHDL) or end (Pascal). I mean, EndIf by itself means an end of a statement, so why put another sign for ending a statement there? Is it not some kind of a pleonasm? I have asked a Quora question about that, and I received an answer that it is to make recovery from parsing errors easier.

Can you please explain that answer in more details? I have hand-written a parser for my programming language, and I fail to see how it can make error recovery easier. You can see the parser for my programming language here, if it helps.


1 Answer 1


I'm not a maintainer of Ada or VHDL, but I somewhat disagree with the Quora answer. I have a few alternative hypotheses.

First, a couple clarifications.

An expression is any sequence of code that returns a value. A statement can be an expression, but it can also return nothing (such as an assignment in languages that don't return anything).

So in something like Rust, the if in this statement is an expression:

let y = if 12 * 15 > 150 {
} else {

(Original source)

But also in Rust, the if in this statement is the statement itself:

if x == 4 {
    println!("x is four");
} else if x == 3 {
    println!("x is three");
} else {
    println!("x is something else");

Allowing if to be an expression has consequences for parsing.This means that they can be embedded inside other expressions, which means that the end of the if may not be the end of a statement, so you may need some other way to disambiguate it. You see this in the Rust code, where the one that is an expression has a semicolon after, but the statement one does not.

IIRC, in Ada specifically, if statements can be expressions, so it uses semicolons to do this. Yes, this is not for recovery from parsing errors directly, but having the semicolon does help in that situation to let the parser know that that if is done, really done, and it can now reset.

VHDL is harder to figure out, but I have a guess.

First, the use of semicolons has two different flavors across languages. Some use it as a terminator, but some use it as a separator.

If you use the semicolon as a terminator, you expect it to be at the end of every statement for which it is needed. If you use it as a separator, you expect it to only be between statements.

So in a terminator language, you would write:

x = 1;
y = 2;

But in a separator language, you could write:

x = 1;
y = 2

if y = 2 is the last statement in the block.

Rust uses this to its advantage; the last statement in a block becomes an expression if it does not have a semicolon after.

VHDL appears to be a terminator language, but this does not automatically mean that every statement needs a semicolon after.

Two examples of languages that are terminator languages, but that don't need a semicolon after every statement, are C and C++. They need a semicolon after every non-compound statement (including for single statement bodies of if and loops), but they do not need a terminator after compound statements like braced if and loop bodies.

This is purely a preference design decision, but it does have a slight consequence on the parser.

In C and C++, they have to check for two token types to see the end of a statement: right brace and semicolon. VHDL only needs to check for one.

Does it matter? Maybe, maybe not. Only the language designer can decide, and in your case, you decided that it does not matter. This is fine! I think you should feel confident in that decision.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .