Hurray for context-free grammars! sigh...
I started implementing support for GL_NV_fragment_program_option
to
the Mesa shader assembler. I quickly discovered that the grammar for
this extension is broken in a pretty fundamental way. They didn't
bother to make new keywords, such as LONG
, SHORT
, or the condition
names (e.g., LT
) reserved. This means that a Bison parser has to
treat the places where these non-reserved reserved words occur as
identifiers. That by itself is annoying, but I can work around it.
The real problem is with the KIL
instruction. In
GL_ARB_fragment_program
the KIL
instruction takes a swizzled
source register as its parameter. The current fragment is discarded
if the value of that register is less than zero.
GL_NV_fragment_program_option
adds a second form that takes a
swizzled condition code as a parameter. As a result, the following
shader is ambiguous:
!!ARBfp1.0
OPTION NV_fragment_program;
TEMP GT;
MOVC GT, fragment.texcoord[0];
KIL GT.xxxx;
MOV result.color, fragment.texcoord[1];
END
What does the KIL
do? Does it discard the fragment if X component
of GT
is less than zero, or does it discard the fragment if the X
component of GT
is greater than zero?
Strong work guys!
My temptation is to add a new token to the lexer called
USED_IDENTIFIER
. When the lexer encounters something that it would
currently consider to be an IDENTIFIER
, it will check the symbol
table. If the symbol is already there, it will return
USED_IDENTIFIER
instead. Then the places that want to use source
registers will match USED_IDENTIFIER
instead of IDENTIFIER
.
However, this complicates error reporting. I don't think I would be
able to generate error messages like "undefined variable foo".
Instead you'd get some gook like "syntax error, unexpected IDENTIFIER
,
expecting RESULT
or USED_IDENTIFIER
". Meh.
The big question is whether or not this will match the behavior of Nvidia's assembler. Of course, with an odd, ambiguous corner case like this, it's possible the behavior of Nvidia's assembler has changed over the years.