HLSL: Add (almost) full expression grammar: Binary, unary (pre/post-fix), assign, ...

This commit is contained in:
John Kessenich 2016-05-03 23:17:20 -06:00
parent 9c86c6ab5b
commit 34fb036a9c
10 changed files with 550 additions and 99 deletions

View File

@ -2,23 +2,41 @@ hlsl.frag
Shader version: 100
gl_FragCoord origin is upper left
0:? Sequence
0:1 move second child to first child (temp 4-component vector of float)
0:1 'AmbientColor' (temp 4-component vector of float)
0:? Constant:
0:? 1.000000
0:? 0.500000
0:? 0.000000
0:? 1.000000
0:8 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
0:12 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
0:5 Function Parameters:
0:5 'input' (temp 4-component vector of float)
0:? Sequence
0:6 Branch: Return with expression
0:6 add (temp 4-component vector of float)
0:6 'input' (temp 4-component vector of float)
0:6 'AmbientColor' (temp 4-component vector of float)
0:7 Branch: Return with expression
0:7 add (temp 4-component vector of float)
0:7 component-wise multiply (temp 4-component vector of float)
0:7 'input' (temp 4-component vector of float)
0:7 'input' (temp 4-component vector of float)
0:7 component-wise multiply (temp 4-component vector of float)
0:7 'input' (temp 4-component vector of float)
0:7 'input' (temp 4-component vector of float)
0:8 Branch: Return with expression
0:8 add (temp 4-component vector of float)
0:8 add (temp 4-component vector of float)
0:8 'input' (temp 4-component vector of float)
0:8 component-wise multiply (temp 4-component vector of float)
0:8 'input' (temp 4-component vector of float)
0:8 'input' (temp 4-component vector of float)
0:8 'input' (temp 4-component vector of float)
0:9 Branch: Return with expression
0:9 component-wise multiply (temp 4-component vector of float)
0:9 Pre-Increment (temp 4-component vector of float)
0:9 'input' (temp 4-component vector of float)
0:9 Negate value (temp 4-component vector of float)
0:9 Negate value (temp 4-component vector of float)
0:9 Pre-Decrement (temp 4-component vector of float)
0:9 'input' (temp 4-component vector of float)
0:10 Branch: Return with expression
0:10 add (temp 4-component vector of float)
0:10 Post-Increment (temp 4-component vector of float)
0:10 'input' (temp 4-component vector of float)
0:10 Pre-Increment (temp 4-component vector of float)
0:10 'input' (temp 4-component vector of float)
0:? Linker Objects
0:? 'AmbientColor' (temp 4-component vector of float)
Linked fragment stage:
@ -27,27 +45,45 @@ Linked fragment stage:
Shader version: 100
gl_FragCoord origin is upper left
0:? Sequence
0:1 move second child to first child (temp 4-component vector of float)
0:1 'AmbientColor' (temp 4-component vector of float)
0:? Constant:
0:? 1.000000
0:? 0.500000
0:? 0.000000
0:? 1.000000
0:8 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
0:12 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
0:5 Function Parameters:
0:5 'input' (temp 4-component vector of float)
0:? Sequence
0:6 Branch: Return with expression
0:6 add (temp 4-component vector of float)
0:6 'input' (temp 4-component vector of float)
0:6 'AmbientColor' (temp 4-component vector of float)
0:7 Branch: Return with expression
0:7 add (temp 4-component vector of float)
0:7 component-wise multiply (temp 4-component vector of float)
0:7 'input' (temp 4-component vector of float)
0:7 'input' (temp 4-component vector of float)
0:7 component-wise multiply (temp 4-component vector of float)
0:7 'input' (temp 4-component vector of float)
0:7 'input' (temp 4-component vector of float)
0:8 Branch: Return with expression
0:8 add (temp 4-component vector of float)
0:8 add (temp 4-component vector of float)
0:8 'input' (temp 4-component vector of float)
0:8 component-wise multiply (temp 4-component vector of float)
0:8 'input' (temp 4-component vector of float)
0:8 'input' (temp 4-component vector of float)
0:8 'input' (temp 4-component vector of float)
0:9 Branch: Return with expression
0:9 component-wise multiply (temp 4-component vector of float)
0:9 Pre-Increment (temp 4-component vector of float)
0:9 'input' (temp 4-component vector of float)
0:9 Negate value (temp 4-component vector of float)
0:9 Negate value (temp 4-component vector of float)
0:9 Pre-Decrement (temp 4-component vector of float)
0:9 'input' (temp 4-component vector of float)
0:10 Branch: Return with expression
0:10 add (temp 4-component vector of float)
0:10 Post-Increment (temp 4-component vector of float)
0:10 'input' (temp 4-component vector of float)
0:10 Pre-Increment (temp 4-component vector of float)
0:10 'input' (temp 4-component vector of float)
0:? Linker Objects
0:? 'AmbientColor' (temp 4-component vector of float)
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 15
// Id's are bound by 45
Capability Shader
1: ExtInstImport "GLSL.std.450"
@ -57,18 +93,21 @@ gl_FragCoord origin is upper left
Source HLSL 100
Name 4 "PixelShaderFunction"
Name 9 "input"
Name 11 "AmbientColor"
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypePointer Function 7(fvec4)
27: 6(float) Constant 1065353216
4(PixelShaderFunction): 2 Function None 3
5: Label
9(input): 8(ptr) Variable Function
11(AmbientColor): 8(ptr) Variable Function
10: 7(fvec4) Load 9(input)
12: 7(fvec4) Load 11(AmbientColor)
13: 7(fvec4) FAdd 10 12
ReturnValue 13
11: 7(fvec4) Load 9(input)
12: 7(fvec4) FMul 10 11
13: 7(fvec4) Load 9(input)
14: 7(fvec4) Load 9(input)
15: 7(fvec4) FMul 13 14
16: 7(fvec4) FAdd 12 15
ReturnValue 16
FunctionEnd

View File

@ -1,7 +1,11 @@
float4 AmbientColor = float4(1, 0.5, 0, 1);
//float4 AmbientColor = float4(1, 0.5, 0, 1);
//float AmbientIntensity = 0.1;
float4 PixelShaderFunction(float4 input) : COLOR0
{
return input /* * AmbientIntensity */ + AmbientColor;
// return input * AmbientIntensity + AmbientColor;
return input * input + input * input;
return input + input * input + input;
return ++input * -+-+--input;
return input++ + ++input;
}

View File

@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 2.8)
set(SOURCES
hlslParseHelper.cpp
hlslScanContext.cpp
hlslOpMap.cpp
hlslTokenStream.cpp
hlslGrammar.cpp)
@ -10,6 +11,7 @@ set(HEADERS
hlslParseHelper.h
hlslTokens.h
hlslScanContext.h
hlslOpMap.h
hlslTokenStream.h
hlslGrammar.h)

View File

@ -129,7 +129,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
if (acceptIdentifier(idToken)) {
// = expression
TIntermTyped* expressionNode = nullptr;
if (acceptTokenClass(EHTokEqual)) {
if (acceptTokenClass(EHTokAssign)) {
if (! acceptExpression(expressionNode)) {
expected("initializer");
return false;
@ -362,36 +362,171 @@ bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& no
return false;
}
// The top-level full expression recognizer.
//
// expression
// : identifier
// | identifier operator identifier // todo: generalize to all expressions
// | LEFT_PAREN expression RIGHT_PAREN
// | constructor
// | literal
// : assignment_expression COMMA assignment_expression COMMA assignment_expression ...
//
bool HlslGrammar::acceptExpression(TIntermTyped*& node)
{
// identifier
HlslToken idToken;
if (acceptIdentifier(idToken)) {
TIntermTyped* left = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string);
// assignment_expression
if (! acceptAssignmentExpression(node))
return false;
// operator?
TOperator op;
if (! acceptOperator(op))
return true;
if (! peekTokenClass(EHTokComma))
return true;
do {
// ... COMMA
TSourceLoc loc = token.loc;
advanceToken();
// identifier
if (acceptIdentifier(idToken)) {
TIntermTyped* right = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string);
node = intermediate.addBinaryMath(op, left, right, loc);
return true;
// ... assignment_expression
TIntermTyped* rightNode = nullptr;
if (! acceptAssignmentExpression(rightNode)) {
expected("assignment expression");
return false;
}
node = intermediate.addComma(node, rightNode, loc);
if (! peekTokenClass(EHTokComma))
return true;
} while (true);
}
// Accept an assignment expression, where assignment operations
// associate right-to-left. This is, it is implicit, for example
//
// a op (b op (c op d))
//
// assigment_expression
// : binary_expression op binary_expression op binary_expression ...
//
bool HlslGrammar::acceptAssignmentExpression(TIntermTyped*& node)
{
if (! acceptBinaryExpression(node, PlLogicalOr))
return false;
TOperator assignOp = HlslOpMap::assignment(peek());
if (assignOp == EOpNull)
return true;
// ... op
TSourceLoc loc = token.loc;
advanceToken();
// ... binary_expression
// But, done by recursing this function, which automatically
// gets the right-to-left associativity.
TIntermTyped* rightNode = nullptr;
if (! acceptAssignmentExpression(rightNode)) {
expected("assignment expression");
return false;
}
node = intermediate.addAssign(assignOp, node, rightNode, loc);
if (! peekTokenClass(EHTokComma))
return true;
return true;
}
// Accept a binary expression, for binary operations that
// associate left-to-right. This is, it is implicit, for example
//
// ((a op b) op c) op d
//
// binary_expression
// : expression op expression op expression ...
//
// where 'expression' is the next higher level in precedence.
//
bool HlslGrammar::acceptBinaryExpression(TIntermTyped*& node, PrecedenceLevel precedenceLevel)
{
if (precedenceLevel > PlMul)
return acceptUnaryExpression(node);
// assignment_expression
if (! acceptBinaryExpression(node, (PrecedenceLevel)(precedenceLevel + 1)))
return false;
TOperator op = HlslOpMap::binary(peek());
PrecedenceLevel tokenLevel = HlslOpMap::precedenceLevel(op);
if (tokenLevel < precedenceLevel)
return true;
do {
// ... op
TSourceLoc loc = token.loc;
advanceToken();
// ... expression
TIntermTyped* rightNode = nullptr;
if (! acceptBinaryExpression(rightNode, (PrecedenceLevel)(precedenceLevel + 1))) {
expected("expression");
return false;
}
node = intermediate.addBinaryMath(op, node, rightNode, loc);
if (! peekTokenClass(EHTokComma))
return true;
} while (true);
}
// unary_expression
// : + unary_expression
// | - unary_expression
// | ! unary_expression
// | ~ unary_expression
// | ++ unary_expression
// | -- unary_expression
// | postfix_expression
//
bool HlslGrammar::acceptUnaryExpression(TIntermTyped*& node)
{
TOperator unaryOp = HlslOpMap::preUnary(peek());
// postfix_expression
if (unaryOp == EOpNull)
return acceptPostfixExpression(node);
// op unary_expression
TSourceLoc loc = token.loc;
advanceToken();
if (! acceptUnaryExpression(node))
return false;
// + is a no-op
if (unaryOp == EOpAdd)
return true;
node = intermediate.addUnaryMath(unaryOp, node, loc);
return node != nullptr;
}
// postfix_expression
// : LEFT_PAREN expression RIGHT_PAREN
// | literal
// | constructor
// | identifier
// | function_call
// | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET
// | postfix_expression DOT IDENTIFIER
// | postfix_expression INC_OP
// | postfix_expression DEC_OP
//
bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node)
{
// Not implemented as self-recursive:
// The logical "right recursion" is done with an loop at the end
// idToken will pick up either a variable or a function name in a function call
HlslToken idToken;
// LEFT_PAREN expression RIGHT_PAREN
if (acceptTokenClass(EHTokLeftParen)) {
if (! acceptExpression(node)) {
@ -402,19 +537,62 @@ bool HlslGrammar::acceptExpression(TIntermTyped*& node)
expected("right parenthesis");
return false;
}
return true;
} else if (acceptLiteral(node)) {
// literal (nothing else to do yet), go on to the
} else if (acceptConstructor(node)) {
// constructor (nothing else to do yet)
} else if (acceptIdentifier(idToken)) {
// identifier or function_call name
if (! peekTokenClass(EHTokLeftParen)) {
node = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string);
} else if (acceptFunctionCall(idToken, node)) {
// function_call (nothing else to do yet)
} else {
expected("function call arguments");
return false;
}
}
// literal
if (acceptLiteral(node))
return true;
do {
TSourceLoc loc = token.loc;
TOperator postOp = HlslOpMap::postUnary(peek());
// constructor
if (acceptConstructor(node))
return true;
// Consume only a valid post-unary operator, otherwise we are done.
switch (postOp) {
case EOpIndexDirectStruct:
case EOpIndexIndirect:
case EOpPostIncrement:
case EOpPostDecrement:
advanceToken();
break;
default:
return true;
}
return false;
// We have a valid post-unary operator, process it.
switch (postOp) {
case EOpIndexDirectStruct:
// todo
break;
case EOpIndexIndirect:
{
TIntermTyped* indexNode = nullptr;
if (! acceptExpression(indexNode) ||
! peekTokenClass(EHTokRightBracket)) {
expected("expression followed by ']'");
return false;
}
// todo: node = intermediate.addBinaryMath(
}
case EOpPostIncrement:
case EOpPostDecrement:
node = intermediate.addUnaryMath(postOp, node, loc);
break;
default:
assert(0);
break;
}
} while (true);
}
// constructor
@ -445,6 +623,17 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node)
return false;
}
// The function_call identifier was already recognized, and passed in as idToken.
//
// function_call
// : [idToken] arguments
//
bool HlslGrammar::acceptFunctionCall(HlslToken idToken, TIntermTyped*&)
{
// todo
return false;
}
// arguments
// : LEFT_PAREN expression COMMA expression COMMA ... RIGHT_PAREN
//
@ -505,41 +694,12 @@ bool HlslGrammar::acceptLiteral(TIntermTyped*& node)
return true;
}
// operator
// : PLUS | DASH | STAR | SLASH | ...
bool HlslGrammar::acceptOperator(TOperator& op)
{
switch (token.tokenClass) {
case EHTokEqual:
op = EOpAssign;
break;
case EHTokPlus:
op = EOpAdd;
break;
case EHTokDash:
op = EOpSub;
break;
case EHTokStar:
op = EOpMul;
break;
case EHTokSlash:
op = EOpDiv;
break;
default:
return false;
}
advanceToken();
return true;
}
// compound_statement
// : { statement statement ... }
// : LEFT_CURLY statement statement ... RIGHT_CURLY
//
bool HlslGrammar::acceptCompoundStatement(TIntermAggregate*& compoundStatement)
{
// {
// LEFT_CURLY
if (! acceptTokenClass(EHTokLeftBrace))
return false;
@ -549,9 +709,10 @@ bool HlslGrammar::acceptCompoundStatement(TIntermAggregate*& compoundStatement)
// hook it up
compoundStatement = intermediate.growAggregate(compoundStatement, statement);
}
compoundStatement->setOperator(EOpSequence);
if (compoundStatement)
compoundStatement->setOperator(EOpSequence);
// }
// RIGHT_CURLY
return acceptTokenClass(EHTokRightBrace);
}

View File

@ -37,6 +37,7 @@
#define HLSLGRAMMAR_H_
#include "hlslParseHelper.h"
#include "hlslOpMap.h"
#include "hlslTokenStream.h"
namespace glslang {
@ -64,10 +65,14 @@ namespace glslang {
bool acceptParameterDeclaration(TFunction&);
bool acceptFunctionDefinition(TFunction&, TIntermNode*&);
bool acceptExpression(TIntermTyped*&);
bool acceptAssignmentExpression(TIntermTyped*&);
bool acceptBinaryExpression(TIntermTyped*&, PrecedenceLevel);
bool acceptUnaryExpression(TIntermTyped*&);
bool acceptPostfixExpression(TIntermTyped*&);
bool acceptConstructor(TIntermTyped*&);
bool acceptFunctionCall(HlslToken, TIntermTyped*&);
bool acceptArguments(TFunction*, TIntermAggregate*&);
bool acceptLiteral(TIntermTyped*&);
bool acceptOperator(TOperator& op);
bool acceptCompoundStatement(TIntermAggregate*&);
bool acceptStatement(TIntermNode*&);
bool acceptSemantic();

171
hlsl/hlslOpMap.cpp Executable file
View File

@ -0,0 +1,171 @@
//
//Copyright (C) 2016 Google, Inc.
//
//All rights reserved.
//
//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions
//are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of Google, Inc., nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
//POSSIBILITY OF SUCH DAMAGE.
//
// Map from physical token form (e.g. '-') to logical operator
// form (e.g., binary subtract or unary negate).
#include "hlslOpMap.h"
namespace glslang {
// Map parsing tokens that could be assignments into assignment operators.
TOperator HlslOpMap::assignment(EHlslTokenClass op)
{
switch (op) {
case EHTokAssign: return EOpAssign;
case EHTokMulAssign: return EOpMulAssign;
case EHTokDivAssign: return EOpDivAssign;
case EHTokAddAssign: return EOpAddAssign;
case EHTokModAssign: return EOpModAssign;
case EHTokLeftAssign: return EOpLeftShiftAssign;
case EHTokRightAssign: return EOpRightShiftAssign;
case EHTokAndAssign: return EOpAndAssign;
case EHTokXorAssign: return EOpExclusiveOrAssign;
case EHTokOrAssign: return EOpInclusiveOrAssign;
case EHTokSubAssign: return EOpSubAssign;
default:
return EOpNull;
}
}
// Map parsing tokens that could be binary operations into binary operators.
TOperator HlslOpMap::binary(EHlslTokenClass op)
{
switch (op) {
case EHTokPlus: return EOpAdd;
case EHTokDash: return EOpSub;
case EHTokStar: return EOpMul;
case EHTokSlash: return EOpDiv;
case EHTokPercent: return EOpMod;
case EHTokRightOp: return EOpRightShift;
case EHTokLeftOp: return EOpLeftShift;
case EHTokAmpersand: return EOpAnd;
case EHTokVerticalBar: return EOpInclusiveOr;
case EHTokCaret: return EOpExclusiveOr;
case EHTokEqOp: return EOpEqual;
case EHTokNeOp: return EOpNotEqual;
case EHTokLeftAngle: return EOpLessThan;
case EHTokRightAngle: return EOpGreaterThan;
case EHTokLeOp: return EOpLessThanEqual;
case EHTokGeOp: return EOpGreaterThanEqual;
case EHTokOrOp: return EOpLogicalOr;
case EHTokXorOp: return EOpLogicalXor;
case EHTokAndOp: return EOpLogicalAnd;
default:
return EOpNull;
}
}
// Map parsing tokens that could be unary operations into unary operators.
// These are just the ones that can appear in front of its operand.
TOperator HlslOpMap::preUnary(EHlslTokenClass op)
{
switch (op) {
case EHTokPlus: return EOpAdd; // means no-op, but still a unary op was present
case EHTokDash: return EOpNegative;
case EHTokBang: return EOpLogicalNot;
case EHTokTilde: return EOpBitwiseNot;
case EHTokIncOp: return EOpPreIncrement;
case EHTokDecOp: return EOpPreDecrement;
default: return EOpNull; // means not a pre-unary op
}
}
// Map parsing tokens that could be unary operations into unary operators.
// These are just the ones that can appear behind its operand.
TOperator HlslOpMap::postUnary(EHlslTokenClass op)
{
switch (op) {
case EHTokDot: return EOpIndexDirectStruct;
case EHTokLeftBracket: return EOpIndexIndirect; // may need to change later to EOpIndexDirect
case EHTokIncOp: return EOpPostIncrement;
case EHTokDecOp: return EOpPostDecrement;
default: return EOpNull; // means not a post-unary op
}
}
// Map operators into their level of precedence.
PrecedenceLevel HlslOpMap::precedenceLevel(TOperator op)
{
switch (op) {
case EOpLogicalOr:
return PlLogicalOr;
case EOpLogicalXor:
return PlLogicalXor;
case EOpLogicalAnd:
return PlLogicalAnd;
case EOpInclusiveOr:
return PlBitwiseOr;
case EOpExclusiveOr:
return PlBitwiseXor;
case EOpAnd:
return PlBitwiseAnd;
case EOpEqual:
case EOpNotEqual:
return PlEquality;
case EOpLessThan:
case EOpGreaterThan:
case EOpLessThanEqual:
case EOpGreaterThanEqual:
return PlRelational;
case EOpRightShift:
case EOpLeftShift:
return PlShift;
case EOpAdd:
case EOpSub:
return PlAdd;
case EOpMul:
case EOpDiv:
case EOpMod:
return PlMul;
default:
return PlBad;
}
}
} // end namespace glslang

69
hlsl/hlslOpMap.h Executable file
View File

@ -0,0 +1,69 @@
//
//Copyright (C) 2016 Google, Inc.
//
//All rights reserved.
//
//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions
//are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of Google, Inc., nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
//POSSIBILITY OF SUCH DAMAGE.
//
#ifndef HLSLOPMAP_H_
#define HLSLOPMAP_H_
#include "hlslScanContext.h"
namespace glslang {
enum PrecedenceLevel {
PlBad,
PlLogicalOr,
PlLogicalXor,
PlLogicalAnd,
PlBitwiseOr,
PlBitwiseXor,
PlBitwiseAnd,
PlEquality,
PlRelational,
PlShift,
PlAdd,
PlMul
};
class HlslOpMap {
public:
static TOperator assignment(EHlslTokenClass op);
static TOperator binary(EHlslTokenClass op);
static TOperator preUnary(EHlslTokenClass op);
static TOperator postUnary(EHlslTokenClass op);
static PrecedenceLevel precedenceLevel(TOperator);
};
} // end namespace glslang
#endif // HLSLOPMAP_H_

View File

@ -309,7 +309,7 @@ EHlslTokenClass HlslScanContext::tokenizeClass(HlslToken& token)
case ';': afterType = false; return EHTokSemicolon;
case ',': afterType = false; return EHTokComma;
case ':': return EHTokColon;
case '=': afterType = false; return EHTokEqual;
case '=': afterType = false; return EHTokAssign;
case '(': afterType = false; return EHTokLeftParen;
case ')': afterType = false; return EHTokRightParen;
case '.': field = true; return EHTokDot;

View File

@ -42,7 +42,7 @@ namespace glslang {
class HlslTokenStream {
public:
HlslTokenStream(HlslScanContext& scanner)
explicit HlslTokenStream(HlslScanContext& scanner)
: scanner(scanner) { }
virtual ~HlslTokenStream() { }

View File

@ -207,6 +207,7 @@ enum EHlslTokenClass {
EHTokAndOp,
EHTokOrOp,
EHTokXorOp,
EHTokAssign,
EHTokMulAssign,
EHTokDivAssign,
EHTokAddAssign,
@ -226,7 +227,6 @@ enum EHlslTokenClass {
EHTokDot,
EHTokComma,
EHTokColon,
EHTokEqual,
EHTokSemicolon,
EHTokBang,
EHTokDash,