declaration/expression
Ellery Newcomer
ellery-newcomer at utulsa.edu
Tue Jun 23 17:35:13 PDT 2009
Jarrett Billingsley wrote:
> On Tue, Jun 23, 2009 at 1:00 AM, Ellery
> Newcomer<ellery-newcomer at utulsa.edu> wrote:
>> Sorry for not posting this in learn, but I'd also like to hear the
>> Language Designer's input on this one.
>>
>> How does dmd resolve the declaration/expression ambiguity?
>>
>> My first instinct would be to try the declaration, and if it doesn't
>> work because the type doesn't exist or something like that then try the
>> expression, or vice versa. But that could easily lead to undefined and
>> unexpected behavior. what if both are valid?
>
> You're right; if a statement begins with an identifier, the compiler
> requires arbitrary lookahead to determine whether it's looking at an
> expression or a declaration. There's a good bit of duplicated code in
> DMD dedicated to parsing declarations. IIRC there's one version of
> the parsing that just returns whether or not it's "probably" a
> declaration, and another version that does the exact same thing but
> which actually builds the AST. Kind of icky.
Heh. I saw that. I also saw a toExpression function in various
declaration structs. Didn't look deeply into it though.
>
> But that being said, I don't think there are actually any ambiguities
> in the grammar when it comes to this. Neither of the "problem" lines
> in your example code could possibly be interpreted as declarations,
> and I don't think I can come up with any actually ambiguous code.
Wrong. Both are perfectly valid declarations (and did you miss my note?
the compiler *IS* interpreting the second as a declaration).
Okay, consider the rule declarator, which is (or should, if the grammar
wants to correctly reflect what the compiler is doing) defined like so
Declarator:
BasicType2opt Identifier DeclaratorSuffixesopt
BasicType2opt ( Declarator ) DeclaratorSuffixesopt
This is what allows D to accept C-style (forgot about those, didn't ya?)
declarations, and it's mostly what I'm referring to. Watch:
int(i); //compiles exactly the same as 'int i;'
int(*i)(int[]); //compiles the same as 'int function(int[]) i;'
So when I give something like
T(t);
t(*i)(i[]); //changed it a little, since 'int (i[])(int[])'
// is semantically invalid
I intend a declaration and an expression. I get the opposite.
Fortunately, neither compiles, due to semantic errors.
To restate my question, if I'm a parser and I see
Identifier ( Identifier ) ;
which do I interpret it as?
Type ( NewSymbol ) ;
FunctionName ( Argument ) ;
If I see
Identifier . Identifier ( * Identifier ) ;
what do I resolve it as?
And it just goes downhill from there.
More information about the Digitalmars-d
mailing list