HLSL: Abstract accepting an identifier.

This commit is contained in:
John Kessenich 2016-03-14 10:46:34 -06:00
parent 078d7f24bd
commit aecd497c96
3 changed files with 47 additions and 33 deletions

View File

@ -93,6 +93,19 @@ bool HlslGrammar::peekTokenClass(EHlslTokenClass tokenClass)
return token.tokenClass == tokenClass; return token.tokenClass == tokenClass;
} }
// Only process the next token if it is an identifier.
// Return true if it was an identifier.
bool HlslGrammar::acceptIdentifier(HlslToken& idToken)
{
if (peekTokenClass(EHTokIdentifier)) {
idToken = token;
advanceToken();
return true;
}
return false;
}
// compilationUnit // compilationUnit
// : list of externalDeclaration // : list of externalDeclaration
// //
@ -137,11 +150,8 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
return false; return false;
// identifier // identifier
if (peekTokenClass(EHTokIdentifier)) { HlslToken idToken;
TSourceLoc declLoc = token.loc; if (acceptIdentifier(idToken)) {
TString* declName = token.string;
advanceToken();
// = expression // = expression
TIntermTyped* expressionNode = nullptr; TIntermTyped* expressionNode = nullptr;
if (acceptTokenClass(EHTokEqual)) { if (acceptTokenClass(EHTokEqual)) {
@ -153,12 +163,12 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
// SEMICOLON // SEMICOLON
if (acceptTokenClass(EHTokSemicolon)) { if (acceptTokenClass(EHTokSemicolon)) {
node = parseContext.declareVariable(declLoc, *declName, type, 0, expressionNode); node = parseContext.declareVariable(idToken.loc, *idToken.string, type, 0, expressionNode);
return true; return true;
} }
// function_parameters // function_parameters
TFunction* function = new TFunction(declName, type); TFunction* function = new TFunction(idToken.string, type);
if (acceptFunctionParameters(*function)) { if (acceptFunctionParameters(*function)) {
// COLON semantic // COLON semantic
acceptSemantic(); acceptSemantic();
@ -345,13 +355,10 @@ bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
return false; return false;
// identifier // identifier
TString name; HlslToken idToken;
if (peekTokenClass(EHTokIdentifier)) { acceptIdentifier(idToken);
name = *token.string;
advanceToken();
}
TParameter param = { token.string, type }; TParameter param = { idToken.string, type };
function.addParameter(param); function.addParameter(param);
return true; return true;
@ -390,9 +397,9 @@ bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& no
bool HlslGrammar::acceptExpression(TIntermTyped*& node) bool HlslGrammar::acceptExpression(TIntermTyped*& node)
{ {
// identifier // identifier
if (peekTokenClass(EHTokIdentifier)) { HlslToken idToken;
TIntermTyped* left = parseContext.handleVariable(token.loc, token.symbol, token.string); if (acceptIdentifier(idToken)) {
advanceToken(); TIntermTyped* left = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string);
// operator? // operator?
TOperator op; TOperator op;
@ -401,9 +408,8 @@ bool HlslGrammar::acceptExpression(TIntermTyped*& node)
TSourceLoc loc = token.loc; TSourceLoc loc = token.loc;
// identifier // identifier
if (peekTokenClass(EHTokIdentifier)) { if (acceptIdentifier(idToken)) {
TIntermTyped* right = parseContext.handleVariable(token.loc, token.symbol, token.string); TIntermTyped* right = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string);
advanceToken();
node = intermediate.addBinaryMath(op, left, right, loc); node = intermediate.addBinaryMath(op, left, right, loc);
return true; return true;
} }
@ -624,10 +630,8 @@ bool HlslGrammar::acceptSemantic()
// COLON // COLON
if (acceptTokenClass(EHTokColon)) { if (acceptTokenClass(EHTokColon)) {
// semantic // semantic
if (peekTokenClass(EHTokIdentifier)) { HlslToken idToken;
TString* semantic = token.string; if (! acceptIdentifier(idToken)) {
advanceToken();
} else {
expected("semantic"); expected("semantic");
return false; return false;
} }

View File

@ -57,7 +57,7 @@ namespace glslang {
void advanceToken(); void advanceToken();
bool acceptTokenClass(EHlslTokenClass); bool acceptTokenClass(EHlslTokenClass);
bool peekTokenClass(EHlslTokenClass); bool peekTokenClass(EHlslTokenClass);
bool lookAheadTokenClass(EHlslTokenClass); bool acceptIdentifier(HlslToken&);
bool acceptCompilationUnit(); bool acceptCompilationUnit();
bool acceptDeclaration(TIntermNode*& node); bool acceptDeclaration(TIntermNode*& node);

View File

@ -34,8 +34,8 @@
// //
// //
// This holds context specific to the GLSL scanner, which // This holds context specific to the HLSL scanner, which
// sits between the preprocessor scanner and parser. // sits between the preprocessor scanner and HLSL parser.
// //
#ifndef HLSLSCANCONTEXT_H_ #ifndef HLSLSCANCONTEXT_H_
@ -49,20 +49,30 @@ namespace glslang {
class TPpContext; class TPpContext;
class TPpToken; class TPpToken;
//
// Everything needed to fully describe a token.
//
struct HlslToken { struct HlslToken {
TSourceLoc loc; HlslToken() : isType(false), string(nullptr), symbol(nullptr) { loc.init(); }
EHlslTokenClass tokenClass; TSourceLoc loc; // location of token in the source
bool isType; EHlslTokenClass tokenClass; // what kind of token it is
union { bool isType; // true if the token represents a user type
glslang::TString *string; union { // what data the token holds
int i; glslang::TString *string; // for identifiers
int i; // for literals
unsigned int u; unsigned int u;
bool b; bool b;
double d; double d;
}; };
glslang::TSymbol* symbol; glslang::TSymbol* symbol; // if a symbol table lookup was done already, this is the result
}; };
//
// The state of scanning and translating raw tokens to slightly richer
// semantics, like knowing if an identifier is an existing symbol, or
// user-defined type.
//
class HlslScanContext { class HlslScanContext {
public: public:
HlslScanContext(TParseContextBase& parseContext, TPpContext& ppContext) HlslScanContext(TParseContextBase& parseContext, TPpContext& ppContext)