[antlr-interest] Tricky vector constructor syntax

Richard Matthias richard at exaflop.org
Tue Jul 19 05:04:16 PDT 2005


>-----Original Message-----
>From: antlr-interest-bounces at antlr.org 
>[mailto:antlr-interest-bounces at antlr.org] On Behalf Of Paul Johnson
>Sent: 19 July 2005 09:51
>To: antlr-interest at antlr.org
>Subject: Re: [antlr-interest] Tricky vector constructor syntax
>
>At first sight, this grammar seems a bit (a lot?) wacky.  
>Bison runs with 122 warnings and 44 reduce/reduce conflicts. 
>The warnings can be fixed with appropriate action code, which 
>has presumably been removed from the grammar. The R/R 
>conflicts arise from:
>
>> typecast
>> 	: '(' typename ')' lvalue				
>> 	| '(' typename ')' constant				
>> 	| '(' typename ')' unarypostfixexpression
>> 
>> unarypostfixexpression
>>						
>> 	| lvalue

>> 	| constant						
>> 	<etc>
>
>In other words, in 'a = (int)b', is 'b' an lvalue/constant or 
>a unarypostfixexpression? Bison selects the typecast by 
>default, but this is badly designed.

Yes. I'd been trying to stick as closely as possible to the given grammar
rather than relying on my understanding of the language to create my own one
from scratch, but when I came to that part I scratched my head for a bit and
then stripped it out and put something more conventional in it's place. This
language doesn't have user-defined types, so typecasts can be detected with
fixed lookahead even without a symbol table.

>Bison fixes your priority problem by explicitly assigning a 
>high priority to vector_initializer:
>
>> vector_initializer
>> 	: '<' expression ',' expression ',' expression '>'	
>%prec INITIALIZER
>> 	| ZERO_VECTOR
>> 	;
>
>where INITIALIZER has the highest operator priority (see the 
>%left/right/nonassoc list). I can't quite get my head around 
>this, but I suspect that if you modify your test from
>
>> vector v = <1,2, 5>6 > > <1,2,3>;
>
>to either 'vector v = <1,2, 5<6 > > <1,2,3>;' or 'vector v = 
><1,2, 5>6 > < <1,2,3>;'
>
>then you'll get a syntax error. I can't immediately see how the '<' 
>relational works at all - does it?

Your first example works, the second gives a parse error. The relational
operators work fine in most well-formed examples because when you get down to
the postfixExpression rule (which contains the vector initializer), there
isn't a '<' or '>' in the immediate lookahead. In the relationalExpression
rule:

relationalExpression
	: shiftExpression 
	  ( options { greedy=true;} : 
          (LEFT_ANGLE^ | LESSTHAN_EQUALS^ | GREATER_EQUALS^ | RIGHT_ANGLE^)
shiftExpression 
         )*
	;

For input "5 < 6", shiftExpression (and decendents) is in both cases
presented with a constant. And because it parses OK on it's own, it also
parses OK as a component of a vector. The following even parses OK:-

vector v = <1, 2, <3,4,5> >;

Even though it isn't valid within the type system. And it parses the
following OK, even though the game's original parser barfs on it for
unspecified reasons:-

vector v = <1,2, <6,7,8> == <6,7,8> >;

The only problem it does have is where a vector initializer is followed by
'<'. As in:-

vector v = <1,2,3> < 6;

>From the debugger I can see that what's happening is that it gets to the
third sub-expression started by the '3', it then sees the '>' as part of the
sub-expression and the following '<' as the start of another vector
initializer which then throws the exception when the '6' is followed by the
';' instead of a ','. 

What I don't understand is why the '>' following the '3' is swallowed as part
of the sub-expression only when there's a following '<' as if you change the
final '<' for any other operator it parses just fine! It's like I understand
how it gets seen as the start of another vector initializer, but not how the
antlr generated code an see it as such at the relationalExpression level.

Only '==' and '!=' are valid operators for acting on vectors. Other operators
seem to be excluded at the type-checking stage by the game's compiler, but I
could cheat a bit and exclude them from mine at the syntax level by passing a
parameter down from relational expression that stops the vector initializer
sub-rule matching '<' via a semantic action when it follows a '>' matched as
part of a relational expression. I think possibly it would be too late by
that stage as the real problem is that what should be the closing '>' of the
main initializer is treated as part of the sub-expression for some reason,
what happens after that just obscures the error.

richard



More information about the antlr-interest mailing list