HLSL: Implement ?: grammar productions.

Missing are implicit conversions between int/bool/etc.
diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp
index be148eb..3c96560 100755
--- a/hlsl/hlslGrammar.cpp
+++ b/hlsl/hlslGrammar.cpp
@@ -1548,8 +1548,9 @@
 //    a op (b op (c op d))
 //
 // assigment_expression
-//      : binary_expression op binary_expression op binary_expression ...
-//      | initializer
+//      : initializer
+//      | conditional_expression
+//      | conditional_expression assign_op conditional_expression assign_op conditional_expression ...
 //
 bool HlslGrammar::acceptAssignmentExpression(TIntermTyped*& node)
 {
@@ -1562,8 +1563,8 @@
         return false;
     }
 
-    // binary_expression
-    if (! acceptBinaryExpression(node, PlLogicalOr))
+    // conditional_expression
+    if (! acceptConditionalExpression(node))
         return false;
 
     // assignment operation?
@@ -1571,12 +1572,12 @@
     if (assignOp == EOpNull)
         return true;
 
-    // assignment op
+    // assign_op
     TSourceLoc loc = token.loc;
     advanceToken();
 
-    // binary_expression
-    // But, done by recursing this function, which automatically
+    // conditional_expression assign_op conditional_expression ...
+    // Done by recursing this function, which automatically
     // gets the right-to-left associativity.
     TIntermTyped* rightNode = nullptr;
     if (! acceptAssignmentExpression(rightNode)) {
@@ -1595,6 +1596,46 @@
     return true;
 }
 
+// Accept a conditional expression, which associates right-to-left,
+// accomplished by the "true" expression calling down to lower
+// precedence levels than this level.
+//
+// conditional_expression
+//      : binary_expression
+//      | binary_expression QUESTION expression COLON assignment_expression
+//
+bool HlslGrammar::acceptConditionalExpression(TIntermTyped*& node)
+{
+    // binary_expression
+    if (! acceptBinaryExpression(node, PlLogicalOr))
+        return false;
+
+    if (! acceptTokenClass(EHTokQuestion))
+        return true;
+
+    TIntermTyped* trueNode = nullptr;
+    if (! acceptExpression(trueNode)) {
+        expected("expression after ?");
+        return false;
+    }
+    TSourceLoc loc = token.loc;
+
+    if (! acceptTokenClass(EHTokColon)) {
+        expected(":");
+        return false;
+    }
+
+    TIntermTyped* falseNode = nullptr;
+    if (! acceptAssignmentExpression(falseNode)) {
+        expected("expression after :");
+        return false;
+    }
+
+    node = intermediate.addSelection(node, trueNode, falseNode, loc);
+
+    return true;
+}
+
 // Accept a binary expression, for binary operations that
 // associate left-to-right.  This is, it is implicit, for example
 //