Robust distinction between IDENTIFIER and TYPE_NAME tokens.

To distinguish the tokens we used to track the lexer context, which is fragile. This patch implements a better way - combine the two tokens into a common parser rule and let the parser context decide if the declaration is valid, which it already does by checking the naming conflicts. TEST=WebGL conformance tests. Review URL: https://codereview.appspot.com/8797044 Conflicts: src/compiler/glslang_tab.cpp src/compiler/glslang_tab.h git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@2229 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 7b999bd2
...@@ -33,10 +33,8 @@ struct TParseContext { ...@@ -33,10 +33,8 @@ struct TParseContext {
compileOptions(options), compileOptions(options),
sourcePath(sourcePath), sourcePath(sourcePath),
treeRoot(0), treeRoot(0),
lexAfterType(false),
loopNestingLevel(0), loopNestingLevel(0),
structNestingLevel(0), structNestingLevel(0),
inTypeParen(false),
currentFunctionType(NULL), currentFunctionType(NULL),
functionReturnsValue(false), functionReturnsValue(false),
checksPrecisionErrors(checksPrecErrors), checksPrecisionErrors(checksPrecErrors),
...@@ -51,10 +49,8 @@ struct TParseContext { ...@@ -51,10 +49,8 @@ struct TParseContext {
int compileOptions; int compileOptions;
const char* sourcePath; // Path of source file or NULL. const char* sourcePath; // Path of source file or NULL.
TIntermNode* treeRoot; // root of parse tree being created TIntermNode* treeRoot; // root of parse tree being created
bool lexAfterType; // true if we've recognized a type, so can only be looking for an identifier
int loopNestingLevel; // 0 if outside all loops int loopNestingLevel; // 0 if outside all loops
int structNestingLevel; // incremented while parsing a struct declaration int structNestingLevel; // incremented while parsing a struct declaration
bool inTypeParen; // true if in parentheses, looking only for an identifier
const TType* currentFunctionType; // the return type of the function that's currently being parsed const TType* currentFunctionType; // the return type of the function that's currently being parsed
bool functionReturnsValue; // true if a non-void function has a return bool functionReturnsValue; // true if a non-void function has a return
bool checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit. bool checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit.
......
...@@ -98,36 +98,36 @@ O [0-7] ...@@ -98,36 +98,36 @@ O [0-7]
"out" { return OUT_QUAL; } "out" { return OUT_QUAL; }
"inout" { return INOUT_QUAL; } "inout" { return INOUT_QUAL; }
"float" { context->lexAfterType = true; return FLOAT_TYPE; } "float" { return FLOAT_TYPE; }
"int" { context->lexAfterType = true; return INT_TYPE; } "int" { return INT_TYPE; }
"void" { context->lexAfterType = true; return VOID_TYPE; } "void" { return VOID_TYPE; }
"bool" { context->lexAfterType = true; return BOOL_TYPE; } "bool" { return BOOL_TYPE; }
"true" { yylval->lex.b = true; return BOOLCONSTANT; } "true" { yylval->lex.b = true; return BOOLCONSTANT; }
"false" { yylval->lex.b = false; return BOOLCONSTANT; } "false" { yylval->lex.b = false; return BOOLCONSTANT; }
"discard" { return DISCARD; } "discard" { return DISCARD; }
"return" { return RETURN; } "return" { return RETURN; }
"mat2" { context->lexAfterType = true; return MATRIX2; } "mat2" { return MATRIX2; }
"mat3" { context->lexAfterType = true; return MATRIX3; } "mat3" { return MATRIX3; }
"mat4" { context->lexAfterType = true; return MATRIX4; } "mat4" { return MATRIX4; }
"vec2" { context->lexAfterType = true; return VEC2; } "vec2" { return VEC2; }
"vec3" { context->lexAfterType = true; return VEC3; } "vec3" { return VEC3; }
"vec4" { context->lexAfterType = true; return VEC4; } "vec4" { return VEC4; }
"ivec2" { context->lexAfterType = true; return IVEC2; } "ivec2" { return IVEC2; }
"ivec3" { context->lexAfterType = true; return IVEC3; } "ivec3" { return IVEC3; }
"ivec4" { context->lexAfterType = true; return IVEC4; } "ivec4" { return IVEC4; }
"bvec2" { context->lexAfterType = true; return BVEC2; } "bvec2" { return BVEC2; }
"bvec3" { context->lexAfterType = true; return BVEC3; } "bvec3" { return BVEC3; }
"bvec4" { context->lexAfterType = true; return BVEC4; } "bvec4" { return BVEC4; }
"sampler2D" { context->lexAfterType = true; return SAMPLER2D; } "sampler2D" { return SAMPLER2D; }
"samplerCube" { context->lexAfterType = true; return SAMPLERCUBE; } "samplerCube" { return SAMPLERCUBE; }
"samplerExternalOES" { context->lexAfterType = true; return SAMPLER_EXTERNAL_OES; } "samplerExternalOES" { return SAMPLER_EXTERNAL_OES; }
"sampler2DRect" { context->lexAfterType = true; return SAMPLER2DRECT; } "sampler2DRect" { return SAMPLER2DRECT; }
"struct" { context->lexAfterType = true; return STRUCT; } "struct" { return STRUCT; }
"asm" { return reserved_word(yyscanner); } "asm" { return reserved_word(yyscanner); }
...@@ -222,14 +222,14 @@ O [0-7] ...@@ -222,14 +222,14 @@ O [0-7]
"!=" { return NE_OP; } "!=" { return NE_OP; }
"<<" { return LEFT_OP; } "<<" { return LEFT_OP; }
">>" { return RIGHT_OP; } ">>" { return RIGHT_OP; }
";" { context->lexAfterType = false; return SEMICOLON; } ";" { return SEMICOLON; }
("{"|"<%") { context->lexAfterType = false; return LEFT_BRACE; } ("{"|"<%") { return LEFT_BRACE; }
("}"|"%>") { return RIGHT_BRACE; } ("}"|"%>") { return RIGHT_BRACE; }
"," { if (context->inTypeParen) context->lexAfterType = false; return COMMA; } "," { return COMMA; }
":" { return COLON; } ":" { return COLON; }
"=" { context->lexAfterType = false; return EQUAL; } "=" { return EQUAL; }
"(" { context->lexAfterType = false; context->inTypeParen = true; return LEFT_PAREN; } "(" { return LEFT_PAREN; }
")" { context->inTypeParen = false; return RIGHT_PAREN; } ")" { return RIGHT_PAREN; }
("["|"<:") { return LEFT_BRACKET; } ("["|"<:") { return LEFT_BRACKET; }
("]"|":>") { return RIGHT_BRACKET; } ("]"|":>") { return RIGHT_BRACKET; }
"." { BEGIN(FIELDS); return DOT; } "." { BEGIN(FIELDS); return DOT; }
...@@ -280,12 +280,10 @@ int check_type(yyscan_t yyscanner) { ...@@ -280,12 +280,10 @@ int check_type(yyscan_t yyscanner) {
int token = IDENTIFIER; int token = IDENTIFIER;
TSymbol* symbol = yyextra->symbolTable.find(yytext); TSymbol* symbol = yyextra->symbolTable.find(yytext);
if (yyextra->lexAfterType == false && symbol && symbol->isVariable()) { if (symbol && symbol->isVariable()) {
TVariable* variable = static_cast<TVariable*>(symbol); TVariable* variable = static_cast<TVariable*>(symbol);
if (variable->isUserType()) { if (variable->isUserType())
yyextra->lexAfterType = true;
token = TYPE_NAME; token = TYPE_NAME;
}
} }
yylval->lex.symbol = symbol; yylval->lex.symbol = symbol;
return token; return token;
......
...@@ -127,6 +127,7 @@ extern void yyerror(TParseContext* context, const char* reason); ...@@ -127,6 +127,7 @@ extern void yyerror(TParseContext* context, const char* reason);
%token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT %token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT
%token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION %token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION
%type <lex> identifier
%type <interm> assignment_operator unary_operator %type <interm> assignment_operator unary_operator
%type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression %type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression
%type <interm.intermTypedNode> expression integer_expression assignment_expression %type <interm.intermTypedNode> expression integer_expression assignment_expression
...@@ -164,6 +165,10 @@ extern void yyerror(TParseContext* context, const char* reason); ...@@ -164,6 +165,10 @@ extern void yyerror(TParseContext* context, const char* reason);
%start translation_unit %start translation_unit
%% %%
identifier
: IDENTIFIER
| TYPE_NAME
variable_identifier variable_identifier
: IDENTIFIER { : IDENTIFIER {
// The symbol table search was done in the lexical phase // The symbol table search was done in the lexical phase
...@@ -1102,7 +1107,7 @@ function_header ...@@ -1102,7 +1107,7 @@ function_header
parameter_declarator parameter_declarator
// Type + name // Type + name
: type_specifier IDENTIFIER { : type_specifier identifier {
if ($1.type == EbtVoid) { if ($1.type == EbtVoid) {
context->error($2.line, "illegal use of type 'void'", $2.string->c_str()); context->error($2.line, "illegal use of type 'void'", $2.string->c_str());
context->recover(); context->recover();
...@@ -1113,7 +1118,7 @@ parameter_declarator ...@@ -1113,7 +1118,7 @@ parameter_declarator
$$.line = $2.line; $$.line = $2.line;
$$.param = param; $$.param = param;
} }
| type_specifier IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET { | type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
// Check that we can make an array out of this type // Check that we can make an array out of this type
if (context->arrayTypeErrorCheck($3.line, $1)) if (context->arrayTypeErrorCheck($3.line, $1))
context->recover(); context->recover();
...@@ -1197,7 +1202,7 @@ init_declarator_list ...@@ -1197,7 +1202,7 @@ init_declarator_list
: single_declaration { : single_declaration {
$$ = $1; $$ = $1;
} }
| init_declarator_list COMMA IDENTIFIER { | init_declarator_list COMMA identifier {
if ($1.type.type == EbtInvariant && !$3.symbol) if ($1.type.type == EbtInvariant && !$3.symbol)
{ {
context->error($3.line, "undeclared identifier declared as invariant", $3.string->c_str()); context->error($3.line, "undeclared identifier declared as invariant", $3.string->c_str());
...@@ -1219,7 +1224,7 @@ init_declarator_list ...@@ -1219,7 +1224,7 @@ init_declarator_list
if (symbol && variable) if (symbol && variable)
symbol->setId(variable->getUniqueId()); symbol->setId(variable->getUniqueId());
} }
| init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET { | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET {
if (context->structQualifierErrorCheck($3.line, $1.type)) if (context->structQualifierErrorCheck($3.line, $1.type))
context->recover(); context->recover();
...@@ -1237,7 +1242,7 @@ init_declarator_list ...@@ -1237,7 +1242,7 @@ init_declarator_list
context->recover(); context->recover();
} }
} }
| init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET { | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
if (context->structQualifierErrorCheck($3.line, $1.type)) if (context->structQualifierErrorCheck($3.line, $1.type))
context->recover(); context->recover();
...@@ -1261,7 +1266,7 @@ init_declarator_list ...@@ -1261,7 +1266,7 @@ init_declarator_list
$$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *$3.string, type, $3.line), $3.line); $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *$3.string, type, $3.line), $3.line);
} }
} }
| init_declarator_list COMMA IDENTIFIER EQUAL initializer { | init_declarator_list COMMA identifier EQUAL initializer {
if (context->structQualifierErrorCheck($3.line, $1.type)) if (context->structQualifierErrorCheck($3.line, $1.type))
context->recover(); context->recover();
...@@ -1288,7 +1293,7 @@ single_declaration ...@@ -1288,7 +1293,7 @@ single_declaration
$$.type = $1; $$.type = $1;
$$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType($1), $1.line), $1.line); $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType($1), $1.line), $1.line);
} }
| fully_specified_type IDENTIFIER { | fully_specified_type identifier {
TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line); TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line);
$$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line); $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
...@@ -1306,7 +1311,7 @@ single_declaration ...@@ -1306,7 +1311,7 @@ single_declaration
if (variable && symbol) if (variable && symbol)
symbol->setId(variable->getUniqueId()); symbol->setId(variable->getUniqueId());
} }
| fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET { | fully_specified_type identifier LEFT_BRACKET RIGHT_BRACKET {
context->error($2.line, "unsized array declarations not supported", $2.string->c_str()); context->error($2.line, "unsized array declarations not supported", $2.string->c_str());
context->recover(); context->recover();
...@@ -1314,7 +1319,7 @@ single_declaration ...@@ -1314,7 +1319,7 @@ single_declaration
$$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line); $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line);
$$.type = $1; $$.type = $1;
} }
| fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET { | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
TType type = TType($1); TType type = TType($1);
int size; int size;
if (context->arraySizeErrorCheck($2.line, $4, size)) if (context->arraySizeErrorCheck($2.line, $4, size))
...@@ -1346,7 +1351,7 @@ single_declaration ...@@ -1346,7 +1351,7 @@ single_declaration
symbol->setId(variable->getUniqueId()); symbol->setId(variable->getUniqueId());
} }
} }
| fully_specified_type IDENTIFIER EQUAL initializer { | fully_specified_type identifier EQUAL initializer {
if (context->structQualifierErrorCheck($2.line, $1)) if (context->structQualifierErrorCheck($2.line, $1))
context->recover(); context->recover();
...@@ -1697,7 +1702,7 @@ type_specifier_nonarray ...@@ -1697,7 +1702,7 @@ type_specifier_nonarray
; ;
struct_specifier struct_specifier
: STRUCT IDENTIFIER LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { : STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
if (context->reservedErrorCheck($2.line, *$2.string)) if (context->reservedErrorCheck($2.line, *$2.string))
context->recover(); context->recover();
...@@ -1784,7 +1789,7 @@ struct_declarator_list ...@@ -1784,7 +1789,7 @@ struct_declarator_list
; ;
struct_declarator struct_declarator
: IDENTIFIER { : identifier {
if (context->reservedErrorCheck($1.line, *$1.string)) if (context->reservedErrorCheck($1.line, *$1.string))
context->recover(); context->recover();
...@@ -1792,7 +1797,7 @@ struct_declarator ...@@ -1792,7 +1797,7 @@ struct_declarator
$$.line = $1.line; $$.line = $1.line;
$$.type->setFieldName(*$1.string); $$.type->setFieldName(*$1.string);
} }
| IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET { | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
if (context->reservedErrorCheck($1.line, *$1.string)) if (context->reservedErrorCheck($1.line, *$1.string))
context->recover(); context->recover();
...@@ -1907,7 +1912,7 @@ condition ...@@ -1907,7 +1912,7 @@ condition
if (context->boolErrorCheck($1->getLine(), $1)) if (context->boolErrorCheck($1->getLine(), $1))
context->recover(); context->recover();
} }
| fully_specified_type IDENTIFIER EQUAL initializer { | fully_specified_type identifier EQUAL initializer {
TIntermNode* intermNode; TIntermNode* intermNode;
if (context->structQualifierErrorCheck($2.line, $1)) if (context->structQualifierErrorCheck($2.line, $1))
context->recover(); context->recover();
......
...@@ -1214,19 +1214,19 @@ YY_RULE_SETUP ...@@ -1214,19 +1214,19 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 20: case 20:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return FLOAT_TYPE; } { return FLOAT_TYPE; }
YY_BREAK YY_BREAK
case 21: case 21:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return INT_TYPE; } { return INT_TYPE; }
YY_BREAK YY_BREAK
case 22: case 22:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return VOID_TYPE; } { return VOID_TYPE; }
YY_BREAK YY_BREAK
case 23: case 23:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return BOOL_TYPE; } { return BOOL_TYPE; }
YY_BREAK YY_BREAK
case 24: case 24:
YY_RULE_SETUP YY_RULE_SETUP
...@@ -1246,71 +1246,71 @@ YY_RULE_SETUP ...@@ -1246,71 +1246,71 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 28: case 28:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return MATRIX2; } { return MATRIX2; }
YY_BREAK YY_BREAK
case 29: case 29:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return MATRIX3; } { return MATRIX3; }
YY_BREAK YY_BREAK
case 30: case 30:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return MATRIX4; } { return MATRIX4; }
YY_BREAK YY_BREAK
case 31: case 31:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return VEC2; } { return VEC2; }
YY_BREAK YY_BREAK
case 32: case 32:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return VEC3; } { return VEC3; }
YY_BREAK YY_BREAK
case 33: case 33:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return VEC4; } { return VEC4; }
YY_BREAK YY_BREAK
case 34: case 34:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return IVEC2; } { return IVEC2; }
YY_BREAK YY_BREAK
case 35: case 35:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return IVEC3; } { return IVEC3; }
YY_BREAK YY_BREAK
case 36: case 36:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return IVEC4; } { return IVEC4; }
YY_BREAK YY_BREAK
case 37: case 37:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return BVEC2; } { return BVEC2; }
YY_BREAK YY_BREAK
case 38: case 38:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return BVEC3; } { return BVEC3; }
YY_BREAK YY_BREAK
case 39: case 39:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return BVEC4; } { return BVEC4; }
YY_BREAK YY_BREAK
case 40: case 40:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return SAMPLER2D; } { return SAMPLER2D; }
YY_BREAK YY_BREAK
case 41: case 41:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return SAMPLERCUBE; } { return SAMPLERCUBE; }
YY_BREAK YY_BREAK
case 42: case 42:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return SAMPLER_EXTERNAL_OES; } { return SAMPLER_EXTERNAL_OES; }
YY_BREAK YY_BREAK
case 43: case 43:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return SAMPLER2DRECT; } { return SAMPLER2DRECT; }
YY_BREAK YY_BREAK
case 44: case 44:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = true; return STRUCT; } { return STRUCT; }
YY_BREAK YY_BREAK
case 45: case 45:
YY_RULE_SETUP YY_RULE_SETUP
...@@ -1621,11 +1621,11 @@ YY_RULE_SETUP ...@@ -1621,11 +1621,11 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 121: case 121:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = false; return SEMICOLON; } { return SEMICOLON; }
YY_BREAK YY_BREAK
case 122: case 122:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = false; return LEFT_BRACE; } { return LEFT_BRACE; }
YY_BREAK YY_BREAK
case 123: case 123:
YY_RULE_SETUP YY_RULE_SETUP
...@@ -1633,7 +1633,7 @@ YY_RULE_SETUP ...@@ -1633,7 +1633,7 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 124: case 124:
YY_RULE_SETUP YY_RULE_SETUP
{ if (context->inTypeParen) context->lexAfterType = false; return COMMA; } { return COMMA; }
YY_BREAK YY_BREAK
case 125: case 125:
YY_RULE_SETUP YY_RULE_SETUP
...@@ -1641,15 +1641,15 @@ YY_RULE_SETUP ...@@ -1641,15 +1641,15 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 126: case 126:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = false; return EQUAL; } { return EQUAL; }
YY_BREAK YY_BREAK
case 127: case 127:
YY_RULE_SETUP YY_RULE_SETUP
{ context->lexAfterType = false; context->inTypeParen = true; return LEFT_PAREN; } { return LEFT_PAREN; }
YY_BREAK YY_BREAK
case 128: case 128:
YY_RULE_SETUP YY_RULE_SETUP
{ context->inTypeParen = false; return RIGHT_PAREN; } { return RIGHT_PAREN; }
YY_BREAK YY_BREAK
case 129: case 129:
YY_RULE_SETUP YY_RULE_SETUP
...@@ -2934,12 +2934,10 @@ int check_type(yyscan_t yyscanner) { ...@@ -2934,12 +2934,10 @@ int check_type(yyscan_t yyscanner) {
int token = IDENTIFIER; int token = IDENTIFIER;
TSymbol* symbol = yyextra->symbolTable.find(yytext); TSymbol* symbol = yyextra->symbolTable.find(yytext);
if (yyextra->lexAfterType == false && symbol && symbol->isVariable()) { if (symbol && symbol->isVariable()) {
TVariable* variable = static_cast<TVariable*>(symbol); TVariable* variable = static_cast<TVariable*>(symbol);
if (variable->isUserType()) { if (variable->isUserType())
yyextra->lexAfterType = true;
token = TYPE_NAME; token = TYPE_NAME;
}
} }
yylval->lex.symbol = symbol; yylval->lex.symbol = symbol;
return token; return token;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment