HLSL: Simplify appearances a bit to make easier to read.

This commit is contained in:
John Kessenich 2016-03-14 10:02:11 -06:00
parent 5f934b039a
commit 078d7f24bd
2 changed files with 89 additions and 65 deletions

View File

@ -42,7 +42,7 @@
// recognized its rule // recognized its rule
// //
// As much as possible, only grammar recognition should happen in this file, // As much as possible, only grammar recognition should happen in this file,
// with all other work being farmed out to hlslParseHelper.cpp, which it turn // with all other work being farmed out to hlslParseHelper.cpp, which in turn
// will build the AST. // will build the AST.
// //
// The next token, yet to be "accepted" is always sitting in 'token'. // The next token, yet to be "accepted" is always sitting in 'token'.
@ -71,7 +71,7 @@ void HlslGrammar::expected(const char* syntax)
// Load 'token' with the next token in the stream of tokens. // Load 'token' with the next token in the stream of tokens.
void HlslGrammar::advanceToken() void HlslGrammar::advanceToken()
{ {
scanContext.tokenize(token); scanner.tokenize(token);
} }
// Return true and advance to the next token if the current token is the // Return true and advance to the next token if the current token is the
@ -86,6 +86,13 @@ bool HlslGrammar::acceptTokenClass(EHlslTokenClass tokenClass)
return false; return false;
} }
// Return true, without advancing to the next token, if the current token is
// the expected (passed in) token class.
bool HlslGrammar::peekTokenClass(EHlslTokenClass tokenClass)
{
return token.tokenClass == tokenClass;
}
// compilationUnit // compilationUnit
// : list of externalDeclaration // : list of externalDeclaration
// //
@ -100,22 +107,22 @@ bool HlslGrammar::acceptCompilationUnit()
return false; return false;
// hook it up // hook it up
unitNode = parseContext.intermediate.growAggregate(unitNode, declarationNode); unitNode = intermediate.growAggregate(unitNode, declarationNode);
} }
// set root of AST // set root of AST
parseContext.intermediate.setTreeRoot(unitNode); intermediate.setTreeRoot(unitNode);
return true; return true;
} }
// declaration // declaration
// : ; // : SEMICOLON
// : fully_specified_type ; // : fully_specified_type SEMICOLON
// | fully_specified_type identifier ; // | fully_specified_type identifier SEMICOLON
// | fully_specified_type identifier = expression ; // | fully_specified_type identifier = expression SEMICOLON
// | fully_specified_type identifier function_parameters ; // function prototype // | fully_specified_type identifier function_parameters SEMICOLON // function prototype
// | fully_specified_type identifier function_parameters : semantic compound_statement // function definition // | fully_specified_type identifier function_parameters COLON semantic compound_statement // function definition
// //
// 'node' could get created if the declaration creates code, like an initializer // 'node' could get created if the declaration creates code, like an initializer
// or a function body. // or a function body.
@ -130,7 +137,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
return false; return false;
// identifier // identifier
if (token.tokenClass == EHTokIdentifier) { if (peekTokenClass(EHTokIdentifier)) {
TSourceLoc declLoc = token.loc; TSourceLoc declLoc = token.loc;
TString* declName = token.string; TString* declName = token.string;
advanceToken(); advanceToken();
@ -144,7 +151,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
} }
} }
// ; // SEMICOLON
if (acceptTokenClass(EHTokSemicolon)) { if (acceptTokenClass(EHTokSemicolon)) {
node = parseContext.declareVariable(declLoc, *declName, type, 0, expressionNode); node = parseContext.declareVariable(declLoc, *declName, type, 0, expressionNode);
return true; return true;
@ -153,22 +160,14 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
// function_parameters // function_parameters
TFunction* function = new TFunction(declName, type); TFunction* function = new TFunction(declName, type);
if (acceptFunctionParameters(*function)) { if (acceptFunctionParameters(*function)) {
// : // COLON semantic
if (acceptTokenClass(EHTokColon)) { acceptSemantic();
// semantic
if (token.tokenClass == EHTokIdentifier) {
TString* semantic = token.string;
advanceToken();
} else {
expected("semantic");
return false;
}
}
// compound_statement // compound_statement
if (token.tokenClass == EHTokLeftBrace) if (peekTokenClass(EHTokLeftBrace))
return acceptFunctionDefinition(*function, node); return acceptFunctionDefinition(*function, node);
// ; // SEMICOLON
if (acceptTokenClass(EHTokSemicolon)) if (acceptTokenClass(EHTokSemicolon))
return true; return true;
@ -176,7 +175,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
} }
} }
// ; [ no identifier, just ; ] // SEMICOLON
if (acceptTokenClass(EHTokSemicolon)) if (acceptTokenClass(EHTokSemicolon))
return true; return true;
@ -307,11 +306,11 @@ bool HlslGrammar::acceptType(TType& type)
} }
// function_parameters // function_parameters
// : ( parameter_declaration , parameter_declaration ... ) // : LEFT_PAREN parameter_declaration COMMA parameter_declaration ... RIGHT_PAREN
// //
bool HlslGrammar::acceptFunctionParameters(TFunction& function) bool HlslGrammar::acceptFunctionParameters(TFunction& function)
{ {
// ( // LEFT_PAREN
if (! acceptTokenClass(EHTokLeftParen)) if (! acceptTokenClass(EHTokLeftParen))
return false; return false;
@ -320,12 +319,12 @@ bool HlslGrammar::acceptFunctionParameters(TFunction& function)
if (! acceptParameterDeclaration(function)) if (! acceptParameterDeclaration(function))
break; break;
// , // COMMA
if (! acceptTokenClass(EHTokComma)) if (! acceptTokenClass(EHTokComma))
break; break;
} while (true); } while (true);
// ) // RIGHT_PAREN
if (! acceptTokenClass(EHTokRightParen)) { if (! acceptTokenClass(EHTokRightParen)) {
expected("right parenthesis"); expected("right parenthesis");
return false; return false;
@ -347,7 +346,7 @@ bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
// identifier // identifier
TString name; TString name;
if (token.tokenClass == EHTokIdentifier) { if (peekTokenClass(EHTokIdentifier)) {
name = *token.string; name = *token.string;
advanceToken(); advanceToken();
} }
@ -370,8 +369,8 @@ bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& no
// compound_statement // compound_statement
TIntermAggregate* functionBody = nullptr; TIntermAggregate* functionBody = nullptr;
if (acceptCompoundStatement(functionBody)) { if (acceptCompoundStatement(functionBody)) {
node = parseContext.intermediate.growAggregate(node, functionBody); node = intermediate.growAggregate(node, functionBody);
parseContext.intermediate.setAggregateOperator(node, EOpFunction, functionDeclarator->getType(), token.loc); intermediate.setAggregateOperator(node, EOpFunction, functionDeclarator->getType(), token.loc);
node->getAsAggregate()->setName(functionDeclarator->getMangledName().c_str()); node->getAsAggregate()->setName(functionDeclarator->getMangledName().c_str());
parseContext.symbolTable.pop(nullptr); parseContext.symbolTable.pop(nullptr);
@ -383,15 +382,15 @@ bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& no
// expression // expression
// : identifier // : identifier
// | identifier operator identifier // to be generalized to all expressions // | identifier operator identifier // todo: generalize to all expressions
// | ( expression ) // | LEFT_PAREN expression RIGHT_PAREN
// | type(...) // constructor // | constructor
// | literal // | literal
// //
bool HlslGrammar::acceptExpression(TIntermTyped*& node) bool HlslGrammar::acceptExpression(TIntermTyped*& node)
{ {
// identifier // identifier
if (token.tokenClass == EHTokIdentifier) { if (peekTokenClass(EHTokIdentifier)) {
TIntermTyped* left = parseContext.handleVariable(token.loc, token.symbol, token.string); TIntermTyped* left = parseContext.handleVariable(token.loc, token.symbol, token.string);
advanceToken(); advanceToken();
@ -402,17 +401,17 @@ bool HlslGrammar::acceptExpression(TIntermTyped*& node)
TSourceLoc loc = token.loc; TSourceLoc loc = token.loc;
// identifier // identifier
if (token.tokenClass == EHTokIdentifier) { if (peekTokenClass(EHTokIdentifier)) {
TIntermTyped* right = parseContext.handleVariable(token.loc, token.symbol, token.string); TIntermTyped* right = parseContext.handleVariable(token.loc, token.symbol, token.string);
advanceToken(); advanceToken();
node = parseContext.intermediate.addBinaryMath(op, left, right, loc); node = intermediate.addBinaryMath(op, left, right, loc);
return true; return true;
} }
return false; return false;
} }
// ( expression ) // LEFT_PAREN expression RIGHT_PAREN
if (acceptTokenClass(EHTokLeftParen)) { if (acceptTokenClass(EHTokLeftParen)) {
if (! acceptExpression(node)) { if (! acceptExpression(node)) {
expected("expression"); expected("expression");
@ -430,7 +429,7 @@ bool HlslGrammar::acceptExpression(TIntermTyped*& node)
if (acceptLiteral(node)) if (acceptLiteral(node))
return true; return true;
// type(...) // constructor // constructor
if (acceptConstructor(node)) if (acceptConstructor(node))
return true; return true;
@ -438,7 +437,7 @@ bool HlslGrammar::acceptExpression(TIntermTyped*& node)
} }
// constructor // constructor
// : type arguments // : type argument_list
// //
bool HlslGrammar::acceptConstructor(TIntermTyped*& node) bool HlslGrammar::acceptConstructor(TIntermTyped*& node)
{ {
@ -466,14 +465,14 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node)
} }
// arguments // arguments
// : ( expression , expression, ... ) // : LEFT_PAREN expression COMMA expression COMMA ... RIGHT_PAREN
// //
// The arguments are pushed onto the 'function' argument list and // The arguments are pushed onto the 'function' argument list and
// onto the 'arguments' aggregate. // onto the 'arguments' aggregate.
// //
bool HlslGrammar::acceptArguments(TFunction* function, TIntermAggregate*& arguments) bool HlslGrammar::acceptArguments(TFunction* function, TIntermAggregate*& arguments)
{ {
// ( // LEFT_PAREN
if (! acceptTokenClass(EHTokLeftParen)) if (! acceptTokenClass(EHTokLeftParen))
return false; return false;
@ -486,12 +485,12 @@ bool HlslGrammar::acceptArguments(TFunction* function, TIntermAggregate*& argume
// hook it up // hook it up
parseContext.handleFunctionArgument(function, arguments, arg); parseContext.handleFunctionArgument(function, arguments, arg);
// , // COMMA
if (! acceptTokenClass(EHTokComma)) if (! acceptTokenClass(EHTokComma))
break; break;
} while (true); } while (true);
// ) // RIGHT_PAREN
if (! acceptTokenClass(EHTokRightParen)) { if (! acceptTokenClass(EHTokRightParen)) {
expected("right parenthesis"); expected("right parenthesis");
return false; return false;
@ -504,16 +503,16 @@ bool HlslGrammar::acceptLiteral(TIntermTyped*& node)
{ {
switch (token.tokenClass) { switch (token.tokenClass) {
case EHTokIntConstant: case EHTokIntConstant:
node = parseContext.intermediate.addConstantUnion(token.i, token.loc, true); node = intermediate.addConstantUnion(token.i, token.loc, true);
break; break;
case EHTokFloatConstant: case EHTokFloatConstant:
node = parseContext.intermediate.addConstantUnion(token.d, EbtFloat, token.loc, true); node = intermediate.addConstantUnion(token.d, EbtFloat, token.loc, true);
break; break;
case EHTokDoubleConstant: case EHTokDoubleConstant:
node = parseContext.intermediate.addConstantUnion(token.d, EbtDouble, token.loc, true); node = intermediate.addConstantUnion(token.d, EbtDouble, token.loc, true);
break; break;
case EHTokBoolConstant: case EHTokBoolConstant:
node = parseContext.intermediate.addConstantUnion(token.b, token.loc, true); node = intermediate.addConstantUnion(token.b, token.loc, true);
break; break;
default: default:
@ -526,7 +525,7 @@ bool HlslGrammar::acceptLiteral(TIntermTyped*& node)
} }
// operator // operator
// : + | - | * | / | ... // : PLUS | DASH | STAR | SLASH | ...
bool HlslGrammar::acceptOperator(TOperator& op) bool HlslGrammar::acceptOperator(TOperator& op)
{ {
switch (token.tokenClass) { switch (token.tokenClass) {
@ -567,7 +566,7 @@ bool HlslGrammar::acceptCompoundStatement(TIntermAggregate*& compoundStatement)
TIntermNode* statement = nullptr; TIntermNode* statement = nullptr;
while (acceptStatement(statement)) { while (acceptStatement(statement)) {
// hook it up // hook it up
compoundStatement = parseContext.intermediate.growAggregate(compoundStatement, statement); compoundStatement = intermediate.growAggregate(compoundStatement, statement);
} }
compoundStatement->setOperator(EOpSequence); compoundStatement->setOperator(EOpSequence);
@ -577,9 +576,9 @@ bool HlslGrammar::acceptCompoundStatement(TIntermAggregate*& compoundStatement)
// statement // statement
// : compound_statement // : compound_statement
// | return ; // | return SEMICOLON
// | return expression ; // | return expression SEMICOLON
// | expression ; // | expression SEMICOLON
// //
bool HlslGrammar::acceptStatement(TIntermNode*& statement) bool HlslGrammar::acceptStatement(TIntermNode*& statement)
{ {
@ -590,17 +589,17 @@ bool HlslGrammar::acceptStatement(TIntermNode*& statement)
return true; return true;
} }
// return // RETURN
if (acceptTokenClass(EHTokReturn)) { if (acceptTokenClass(EHTokReturn)) {
// expression // expression
TIntermTyped* node; TIntermTyped* node;
if (acceptExpression(node)) { if (acceptExpression(node)) {
// hook it up // hook it up
statement = parseContext.intermediate.addBranch(EOpReturn, node, token.loc); statement = intermediate.addBranch(EOpReturn, node, token.loc);
} else } else
statement = parseContext.intermediate.addBranch(EOpReturn, token.loc); statement = intermediate.addBranch(EOpReturn, token.loc);
// ; // SEMICOLON
if (! acceptTokenClass(EHTokSemicolon)) if (! acceptTokenClass(EHTokSemicolon))
return false; return false;
@ -612,11 +611,29 @@ bool HlslGrammar::acceptStatement(TIntermNode*& statement)
if (acceptExpression(node)) if (acceptExpression(node))
statement = node; statement = node;
// ; // SEMICOLON
if (! acceptTokenClass(EHTokSemicolon)) if (! acceptTokenClass(EHTokSemicolon))
return false; return false;
return true; return true;
} }
// COLON semantic
bool HlslGrammar::acceptSemantic()
{
// COLON
if (acceptTokenClass(EHTokColon)) {
// semantic
if (peekTokenClass(EHTokIdentifier)) {
TString* semantic = token.string;
advanceToken();
} else {
expected("semantic");
return false;
}
}
return true;
}
} // end namespace glslang } // end namespace glslang

View File

@ -41,10 +41,13 @@
namespace glslang { namespace glslang {
// Should just be the grammar aspect of HLSL.
// Described in more detail in hlslGrammar.cpp.
class HlslGrammar { class HlslGrammar {
public: public:
HlslGrammar(HlslScanContext& scanContext, HlslParseContext& parseContext) HlslGrammar(HlslScanContext& scanner, HlslParseContext& parseContext)
: scanContext(scanContext), parseContext(parseContext) { } : scanner(scanner), parseContext(parseContext), intermediate(parseContext.intermediate) { }
virtual ~HlslGrammar() { } virtual ~HlslGrammar() { }
bool parse(); bool parse();
@ -53,6 +56,8 @@ namespace glslang {
void expected(const char*); void expected(const char*);
void advanceToken(); void advanceToken();
bool acceptTokenClass(EHlslTokenClass); bool acceptTokenClass(EHlslTokenClass);
bool peekTokenClass(EHlslTokenClass);
bool lookAheadTokenClass(EHlslTokenClass);
bool acceptCompilationUnit(); bool acceptCompilationUnit();
bool acceptDeclaration(TIntermNode*& node); bool acceptDeclaration(TIntermNode*& node);
@ -69,11 +74,13 @@ namespace glslang {
bool acceptOperator(TOperator& op); bool acceptOperator(TOperator& op);
bool acceptCompoundStatement(TIntermAggregate*&); bool acceptCompoundStatement(TIntermAggregate*&);
bool acceptStatement(TIntermNode*&); bool acceptStatement(TIntermNode*&);
bool acceptSemantic();
HlslScanContext& scanContext; HlslScanContext& scanner; // lexical scanner, to get next token
HlslParseContext& parseContext; HlslParseContext& parseContext; // state of parsing and helper functions for building the intermediate
TIntermediate& intermediate; // the final product, the intermediate representation, includes the AST
HlslToken token; HlslToken token; // the current token we are processing
}; };
} // end namespace glslang } // end namespace glslang