www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Proposed rewrite of statement syntax

The D grammar, as given in the spec, has a number of holes, typos, 
inconsistencies with implementation and bits that simply ought to be 
different.  One place where these problems occur quite a bit is in the 
statement grammar.  I hereby propose the following grammar to replace 
it, thereby fixing some of these problems and introducing one or two 
checks for coding absurdities in the process.

Statement:
         BasicStatement
         BlockStatement
         Declaration
         ScopeStatement

BasicStatement:
         LabelledStatement
         ExpressionStatement
         IfStatement
         WhileStatement
         DoWhileStatement
         ForStatement
         ForeachStatement
         SwitchStatement
         CaseStatement
         DefaultStatement
         ContinueStatement
         BreakStatement
         ReturnStatement
         GotoStatement
         WithStatement
         SynchronizeStatement
         TryStatement
         ThrowStatement
         VolatileStatement
         AsmStatement
         PragmaStatement
         CCStatement

IfStatement:
         'if' '(' IfCondition ')' ControlledStatement
         'if' '(' IfCondition ')' ControlledStatement else 
ControlledStatement

IfCondition:
         Expression
         'auto' Identifier '=' Expression
         Declarator '=' Expression

WhileStatement:
         'while' '(' Expression ')' ControlledStatement

DoStatement:
         'do' ControlledStatement while '(' Expression ')' ';'

ForStatement:
         'for' '(' Initialize ';' Test ';' Increment ')' ControlledStatement

ForeachStatement:
         'foreach' '(' ForeachTypeList ';' Expression ')' 
ControlledStatement

WithStatement:
         'with' '(' Expression ')' ControlledStatement
         'with' '(' Symbol ')' ControlledStatement
         'with' '(' TemplateInstance ')' ControlledStatement

SynchronizeStatement:
         'synchronized' ControlledStatement
         'synchronized' '(' Expression ')' ControlledStatement

ScopeStatement:
         'scope' '(' 'exit' ')' ControlledStatement
         'scope' '(' 'success' ')' ControlledStatement
         'scope' '(' 'failure' ')' ControlledStatement

TryStatement:
         try ControlledStatement Catches
         try ControlledStatement Catches FinallyStatement
         try ControlledStatement FinallyStatement

Catches:
         LastCatch
         Catch
         Catch Catches

LastCatch:
         catch BlockStatement

Catch:
         catch '(' CatchParameter ')' ControlledStatement

FinallyStatement:
         finally ControlledStatement

PragmaStatement:
         Pragma ';'
         Pragma CCedStatement

ControlledStatement:
         BasicStatement
         BlockStatement

BlockStatement:
         '{' '}'
         '{' StatementList '}'

CCStatement:
         CompileCondition CCedStatement
         CompileCondition CCedStatement else CCedStatement

CCedStatement:
         BasicStatement
         Declaration
         ScopeStatement
         CCedBlockStatement

CCedBlockStatement:
         '{' '}'
         '{' StatementList '}'

StatementList:
         Statement
         Statement StatementList


The idea:

- The syntax distinguishes between control statements and conditional 
compilation statements.  BlockStatement and CCedBlockStatement are 
syntactically the same, but differ semantically in that BlockStatement 
opens a new scope and CCedBlockStatement doesn't.

- The current spec of DeclarationStatement is far from complete.  We 
might as well get rid of it and just use Declaration (defined in 
declaration.html).  It's what DMD seems to do anyway.

- Because a Declaration isn't a valid form of ControlledStatement, the 
highly debated question of whether a control statement opens a new scope 
even without {...} becomes mostly irrelevant.  It doesn't make sense to 
allow a declaration here anyway.  This also eliminates the confusing 
ambiguity between a SynchronizeStatement and a nested function with the 
synchronized attribute.

I say _mostly_ irrelevant because there are cases such as this:

     if (qwert) static if (yuiop) {
         int asdfg;
         ...
     }
     writefln(asdfg);

The {...} applies to the static if and therefore doesn't introduce a 
scope.  However, it wouldn't make sense if the compile-time legality of 
the statement after the IfStatement depends at runtime on the value of 
qwert.  It follows that control statements must still be defined to 
create a scope even if they don't have {...} attached.


Notice also:

- ConditionalStatement and Condition (currently defined in version.html) 
have been renamed to the more descriptive CCStatement (conditional 
compilation statement) and CompileCondition.

- WithStatement and TryStatement are defined in the current spec to take 
only BlockStatement bodies, but the compiler accepts anything here 
(except in LastCatch).  Meanwhile, I've made them use ControlledStatement.

- PragmaStatement, previously undefined, now has a definition.  Of 
course, a given pragma may or may not introduce a new scope.  Generally, 
if a particular pragma (recognised by the compiler) creates a scope, 
then the compiler should disallow a naked declaration as the body - this 
could be implemented either during parsing or during semantic analysis.

- ThenStatement and ElseStatement are unnecessary aliases and have been 
removed.

- I have used several nonterminals in the above BNF without defining 
them.  These will retain their current meanings, whether currently 
defined on statement.html or elsewhere.


A few further points:

- I thought about building the solution to the dangling else problem 
directly into the BNF.  But with the number of cases to consider, I now 
realise it would probably be simpler to expect the parser to resolve the 
conflict via a disambiguation rule.

- The current spec can't make up its mind whether it's LabelledStatement 
or LabeledStatement.  Indeed, the spec is dotted with both American and 
British spellings.  Which is it supposed to be written in?

- The BNF grammars on module.html and class.html could also do with some 
cleaning up.  But I'll have a go at that another day (unless someone 
else gets there first).

-- 
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/M d- s:-  C++  a->--- UB  P+ L E  W++  N+++ o K-  w++  O? M V? PS- 
PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y
------END GEEK CODE BLOCK------

My e-mail is valid but not my primary mailbox.  Please keep replies on 
the 'group where everyone may benefit.
Sep 06 2006