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

View File

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

View File

@ -34,8 +34,8 @@
//
//
// This holds context specific to the GLSL scanner, which
// sits between the preprocessor scanner and parser.
// This holds context specific to the HLSL scanner, which
// sits between the preprocessor scanner and HLSL parser.
//
#ifndef HLSLSCANCONTEXT_H_
@ -49,20 +49,30 @@ namespace glslang {
class TPpContext;
class TPpToken;
//
// Everything needed to fully describe a token.
//
struct HlslToken {
TSourceLoc loc;
EHlslTokenClass tokenClass;
bool isType;
union {
glslang::TString *string;
int i;
HlslToken() : isType(false), string(nullptr), symbol(nullptr) { loc.init(); }
TSourceLoc loc; // location of token in the source
EHlslTokenClass tokenClass; // what kind of token it is
bool isType; // true if the token represents a user type
union { // what data the token holds
glslang::TString *string; // for identifiers
int i; // for literals
unsigned int u;
bool b;
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 {
public:
HlslScanContext(TParseContextBase& parseContext, TPpContext& ppContext)