Commit 02064be7 by alokp@chromium.org

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 git-svn-id: https://angleproject.googlecode.com/svn/trunk@2190 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 368610cc
...@@ -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();
......
...@@ -1215,19 +1215,19 @@ YY_RULE_SETUP ...@@ -1215,19 +1215,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
...@@ -1247,71 +1247,71 @@ YY_RULE_SETUP ...@@ -1247,71 +1247,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
...@@ -1622,11 +1622,11 @@ YY_RULE_SETUP ...@@ -1622,11 +1622,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
...@@ -1634,7 +1634,7 @@ YY_RULE_SETUP ...@@ -1634,7 +1634,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
...@@ -1642,15 +1642,15 @@ YY_RULE_SETUP ...@@ -1642,15 +1642,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.
/* A Bison parser, made by GNU Bison 2.4.2. */ /* A Bison parser, made by GNU Bison 2.5. */
/* Skeleton interface for Bison's Yacc-like parsers in C /* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
Foundation, Inc.
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
......
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