diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index 2ebb271d..4528a191 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -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; } diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index d60f3777..902ba228 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -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); diff --git a/hlsl/hlslScanContext.h b/hlsl/hlslScanContext.h index df0d2bc6..04f24383 100755 --- a/hlsl/hlslScanContext.h +++ b/hlsl/hlslScanContext.h @@ -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)