www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - Documented Grammar mistakes?

reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
I have been looking at the documented grammar recently, and I noticed a 
few things that look like they may be typos.

One is that PrimaryExpression has a rule for StringLiteral, which is 
defined as:

StringLiteral:
    WysiwygString
    AlternateWysiwygString
    DoubleQuotedString
    EscapeSequence
    HexString

I may be wrong, but it seems that PrimaryExpression should use something 
like StringLiterals, e.g.:

StringLiterals:
    StringLiteral
    StringLiterals StringLiteral

Since the following compiles:

printf("test" `test` r"" \n);

Lower down, should SliceExpression is defined as:

SliceExpression:
    PostfixExpression [ AssignExpression .. AssignExpression ]

Which does not seem to allow for "variable[]" - and that is also a valid 
(unless I'm confused) slice expression, right?

Just above that, PostfixExpression has this rule:

PostfixExpression ( ArgumentList )

But does not also have:

PostfixExpression ( )

Which would seem necessary unless ArgumentList is meant to have a 
"nothing" rule.

NewExpression, duplicated below, also seems to suffer from a few 
problems.  First I'll copy it over:

NewExpression:
    new BasicType Stars [ AssignExpression ] Declarator
    new BasicType Stars ( ArgumentList )
    new BasicType Stars
    new ( ArgumentList ) BasicType Stars [ AssignExpression ] Declarator
    new ( ArgumentList ) BasicType Stars ( ArgumentList )
    new ( ArgumentList ) BasicType Stars

The first problem is the pesky "Declarators" there.  I really think 
that's a typo, or I'm completely missing something.  Quite likely both.

Also somewhat trivial is those ArgumentLists again: unless it's meant to 
be nothing, it seems additional rules are necessary for each of the 
permutations where ArgumentList isn't there.  Likely something like this 
would simplify things:

NewArguments:
    new ( ArgumentList )
    new ( )
    new

Less trivial is that while BasicType Stars seems dandy, many other valid 
forms seem to exist, like:

int*[]*[] test = new int*[]*[0];
int*[1]*[] test = new int*[1]*[0];
int*[]** test = new int*[]*;

If I understand right, the last [] pair must contain a valid expression, 
and then stars.

And, while doing that, I found that dmd accepts:

C** c = new C*(1);

Which (afaict) does nothing, and C doesn't even have a constructor that 
takes an int.  But maybe this is valid, and I don't understand why...?

FunctionLiterals also have a few ( ParameterList ) without having empty 
parens allowed.

On the Declarations page, you'll see:

Decl:
    StorageClass Decl
    BasicType Declarators ;
    BasicType Declarator FunctionBody

That seems ambiguous to me, since all of the storage classes seem to 
also be attributes, so you get Declaration vs. Attribute DeclDefBlock 
(where DeclDefBlock can be a DeclDef, and hence a Declaration.)  But I'm 
new to grammars, so forgive me if I show that with the above comments.

BasicType2 and DeclaratorSuffix also miss parameter-less rules.

ParameterList, which is defined as:

ParameterList:
    Parameter
    Parameter , ParameterList
    ...

Is missing a rule for the new typesafe form, that is:

    Parameter ...

Then, referenced on that page are ArrayInitializer and 
StructInitializer, neither of which seem to be defined on any page.  I 
believe they should be:

ArrayInitializer:
    [ ArrayMemberInitializations ]
    [ ]

ArrayMemberInitializations:
    ArrayMemberInitialization
    ArrayMemberInitialization ,
    ArrayMemberInitialization , ArrayMemberInitializations

ArrayMemberInitialization:
    AssignExpression
    AssignExpression : AssignExpression

StructInitializer:
    { }
    { StructMemberInitializers }

StructMemberInitializers:
    StructMemberInitializer
    StructMemberInitializer ,
    StructMemberInitializer , StructMemberInitializers

StructMemberInitializer:
    AssignExpression
    Identifier : AssignExpression

Which *seems* to be what the compiler supports.

This is getting pretty long, so I'll just name two others...

AttributeElseSpecifier: where is this used?

EnumMember should use AssignExpression instead of Expression, since 
EnumMembers allows for commas.

Anyway, again as said above, I'm no expert on compilers or language 
grammars, so if I'm completely off base, just tell me.

Thanks,
-[Unknown]
Oct 11 2005
next sibling parent "Unknown W. Brackets" <unknown simplemachines.org> writes:
Additionally, contracts seem to be entirely missing in the grammar, as 
is FunctionBody.  I believe the missing rules are or could be:

FunctionBody:
    BlockStatement
    ContractStatement

ContractStatement:
    BodyStatement
    InStatement BodyStatement
    OutStatement BodyStatement
    InStatement OutStatement BodyStatement
    OutStatement InStatement BodyStatement

InStatement:
    in BlockStatement

OutStatement:
    out BlockStatement
    out ( Identifier ) BlockStatement

BodyStatement:
    body BlockStatement

Where ContractStatement could be added to Statement's rules (when 
supported, I suppose.)  This is assuming a lone body statement would be 
allowed, which is the current behavior.

Following from this, all of the grammar on the class.html page is wrong. 
  For example, this:

Constructor:
    this ( ParameterList ) BlockStatement

Should be:

Constructor:
    this ( ParameterList ) FunctionBody

Or, at least I presume so.  This happens many times, for Constructor, 
Destructor, StaticConstructor, StaticDestructor, ClassInvariant, 
UnitTest, ClassAllocator, and ClassDeallocator.  In other words, every 
BlockStatement on that page.

In module.html, DeclDef uses "Unittest" instead of "UnitTest" which is 
(I think) the correct spelling - or, at least, one of them is.

StructAllocator and StructDeallocator are also missing from struct.html. 
  I imagine they're the same as the ClassAllocator and ClassDeallocator, 
respectively.

 From what I was messing with, ConditionalDeclaration isn't very 
friendly with AttributeSpecifier, because of Attribute DeclDefBlock 
(much like the problem with StorageClasses.)  This is only the case when 
AttributeElseSpecifier is added alongside AttributeSpecifier (which 
isn't how it is, as current, of course.)

That's all I've run across so far (or at least, all I can recall now.)

-[Unknown]
Oct 13 2005
prev sibling parent "Walter Bright" <newshound digitalmars.com> writes:
"Unknown W. Brackets" <unknown simplemachines.org> wrote in message
news:dii53h$i5n$1 digitaldaemon.com...

Thanks for all these corrections.

 And, while doing that, I found that dmd accepts:

 C** c = new C*(1);

 Which (afaict) does nothing, and C doesn't even have a constructor that
 takes an int.  But maybe this is valid, and I don't understand why...?
It's a bug, and will no longer be accepted <g>.
Oct 20 2005