There are several kinds of answers to this question, all of which might be relevant.
The first question is about efficiency and a distinction between compiled and interpreted languages. The basic intuition is correct, that the details of syntax don't affect generated code. Parsers usually generate an abstract syntax tree (be that explicitly or implicitly), be it for compilers or interpreters. Once the AST is in place, the details of syntax used to generate the AST are irrelevant.
The next question is whether requiring an explicit keyword assists in parsing or not. The simple answer is that it's not necessary, but can be helpful. To understand why it's not necessary, you have to know what a "lookahead set" is for a parser. The lookahead set is a set of tokens for each parsing state that would be correct grammar if they were to appear next in the token stream. Parser generators such as bison
model this lookahead set explicitly. Recursive descent parsers also have a lookahead set, but they are often do not appear explicitly in a table.
Now consider a language that, as proposed in the question, uses the following syntax for exceptions:
block: "{" statement_list "}" ;
statement: block ;
statement: block "catch" block ;
statement: //... other kinds of statements
With this syntax, a block can either be adorned with an exception block or not. The question about ambiguity is whether, after having seen a block
, whether the catch
keyword is ambiguous. Assuming that the catch
keyword is unique, it's completely unambiguous that the parser is going to recognize an exception-adorned statement.
Now I said that it's helpful to have to have an explicit try
keyword for the parser. In what way is it helpful? It constrains the lookahead set for certain parser states. The lookahead set after try
itself is the single token {
. The lookahead set after the matching close brace is the single keyword catch
. A table-driven parser doesn't care about this, but it makes a hand-written recursive descent parser a bit easier to write. More importantly, though, it improves error handling in the parser. If a syntax error occurs in the first block, having a try
keyword means that error recovery can look for a catch
token as a fence post at which to re-establish a known parser state, possible exactly because it's the single member of a lookahead set.
The last question about a try
keyword have to do with language design. Simply put, having explicit keywords in front of blocks makes the code easier to read. Humans still have to parse the code by eye, even if they don't use computer algorithms to do it. Reducing the size of the lookahead set in the formal grammar also reduces the possibilities of what a section of code might mean when first glanced at. This improves the clarity of the code.