HLSL: Simplify appearances a bit to make easier to read.
This commit is contained in:
parent
5f934b039a
commit
078d7f24bd
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user