Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Declarator lists as operands of ternary operator parsed incorrectly #436

Open
LeStahL opened this issue Aug 9, 2024 · 4 comments
Open

Comments

@LeStahL
Copy link

LeStahL commented Aug 9, 2024

Hi, it's me again (sorry ._.)

The following shader should be valid (validates using glslangValidator; also compare https://www.shadertoy.com/view/lfjcWt)

#version 450

out vec4 out_color;
uniform float t;

void main() {
    float a, b;

    t > .5
        ? a = .5, b = .5
        : a = .9, b = .1
        ;
    out_color = vec4(a, b, 1, 1);
}

But triggers a parsing error in shader_minifier:

System.AggregateException: One or more errors occurred. (Parse error: Error in minbug.frag: Ln: 10 Col: 17
        ? a = .5, b = .5
                ^
Expecting: infix operator, postfix operator, suffix or ':'
Other error messages:
  ':' is the right part of the ternary operator '?' ':'. The left part is on
  the same line at column 9.
) ---> System.Exception: Parse error: Error in minbug.frag: Ln: 10 Col: 17
        ? a = .5, b = .5
                ^
Expecting: infix operator, postfix operator, suffix or ':'
Other error messages:
  ':' is the right part of the ternary operator '?' ':'. The left part is on
  the same line at column 9.

  at Microsoft.FSharp.Core.PrintfModule+PrintFormatToStringThenFail@1439[TResult].Invoke (System.String message) [0x00000] in <665bb110c40096cda745038310b15b66>:0 
  at <StartupCode$shader_minifier_lib>.$Api+parseAndRewrite@23.Invoke (System.Tuple`2[T1,T2] tupledArg) [0x00019] in <665bb110c40096cda745038310b15b66>:0 
  at Microsoft.FSharp.Collections.ArrayModule+Parallel+Map@1401-2[T,TResult].Invoke (System.Int32 i) [0x00000] in <665bb110c40096cda745038310b15b66>:0 
  at System.Threading.Tasks.Parallel+<ForWorker>c__AnonStorey2`1[TLocal].<>m__1 (System.Threading.Tasks.RangeWorker& currentWorker, System.Int32 timeout, System.Boolean& replicationDelegateYieldedBeforeCompletion) [0x00103] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
--- End of stack trace from previous location where exception was thrown ---

  at System.Threading.Tasks.Parallel+<ForWorker>c__AnonStorey2`1[TLocal].<>m__1 (System.Threading.Tasks.RangeWorker& currentWorker, System.Int32 timeout, System.Boolean& replicationDelegateYieldedBeforeCompletion) [0x0024b] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
  at System.Threading.Tasks.TaskReplicator+Replica`1[TState].ExecuteAction (System.Boolean& yieldedBeforeCompletion) [0x00000] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
  at System.Threading.Tasks.TaskReplicator+Replica.Execute () [0x00029] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
   --- End of inner exception stack trace ---
  at System.Threading.Tasks.TaskReplicator.Run[TState] (System.Threading.Tasks.TaskReplicator+ReplicatableUserAction`1[TState] action, System.Threading.Tasks.ParallelOptions options, System.Boolean stopOnFirstFailure) [0x0006a] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
  at System.Threading.Tasks.Parallel.ForWorker[TLocal] (System.Int32 fromInclusive, System.Int32 toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action`1[T] body, System.Action`2[T1,T2] bodyWithState, System.Func`4[T1,T2,T3,TResult] bodyWithLocal, System.Func`1[TResult] localInit, System.Action`1[T] localFinally) [0x0015c] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
--- End of stack trace from previous location where exception was thrown ---

  at System.Threading.Tasks.Parallel.ThrowSingleCancellationExceptionOrOtherException (System.Collections.ICollection exceptions, System.Threading.CancellationToken cancelToken, System.Exception otherException) [0x00010] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
  at System.Threading.Tasks.Parallel.ForWorker[TLocal] (System.Int32 fromInclusive, System.Int32 toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action`1[T] body, System.Action`2[T1,T2] bodyWithState, System.Func`4[T1,T2,T3,TResult] bodyWithLocal, System.Func`1[TResult] localInit, System.Action`1[T] localFinally) [0x001c5] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
  at System.Threading.Tasks.Parallel.For (System.Int32 fromInclusive, System.Int32 toExclusive, System.Action`1[T] body) [0x00011] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
  at Microsoft.FSharp.Collections.ArrayModule+Parallel.Map[T,TResult] (Microsoft.FSharp.Core.FSharpFunc`2[T,TResult] mapping, T[] array) [0x00024] in <665bb110c40096cda745038310b15b66>:0 
  at ShaderMinifier.Minifier.minify (Options+Options options, System.Tuple`2[System.String,System.String][] files) [0x00150] in <665bb110c40096cda745038310b15b66>:0 
  at ShaderMinifier.Minifier..ctor (Options+Options options, System.Tuple`2[System.String,System.String][] files) [0x0000f] in <665bb110c40096cda745038310b15b66>:0 
  at Main.minifyFiles (Options+Options options, System.Collections.Generic.IEnumerable`1[T] filenames, System.IO.TextWriter out) [0x00073] in <665bb110c40096cda745038310b15b66>:0 
  at Main.run (Options+Options options, System.Collections.Generic.IEnumerable`1[T] filenames) [0x0003b] in <665bb110c40096cda745038310b15b66>:0 
---> (Inner Exception #0) System.Exception: Parse error: Error in minbug.frag: Ln: 10 Col: 17
        ? a = .5, b = .5
                ^
Expecting: infix operator, postfix operator, suffix or ':'
Other error messages:
  ':' is the right part of the ternary operator '?' ':'. The left part is on
  the same line at column 9.

  at Microsoft.FSharp.Core.PrintfModule+PrintFormatToStringThenFail@1439[TResult].Invoke (System.String message) [0x00000] in <665bb110c40096cda745038310b15b66>:0 
  at <StartupCode$shader_minifier_lib>.$Api+parseAndRewrite@23.Invoke (System.Tuple`2[T1,T2] tupledArg) [0x00019] in <665bb110c40096cda745038310b15b66>:0 
  at Microsoft.FSharp.Collections.ArrayModule+Parallel+Map@1401-2[T,TResult].Invoke (System.Int32 i) [0x00000] in <665bb110c40096cda745038310b15b66>:0 
  at System.Threading.Tasks.Parallel+<ForWorker>c__AnonStorey2`1[TLocal].<>m__1 (System.Threading.Tasks.RangeWorker& currentWorker, System.Int32 timeout, System.Boolean& replicationDelegateYieldedBeforeCompletion) [0x00103] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
--- End of stack trace from previous location where exception was thrown ---

  at System.Threading.Tasks.Parallel+<ForWorker>c__AnonStorey2`1[TLocal].<>m__1 (System.Threading.Tasks.RangeWorker& currentWorker, System.Int32 timeout, System.Boolean& replicationDelegateYieldedBeforeCompletion) [0x0024b] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
  at System.Threading.Tasks.TaskReplicator+Replica`1[TState].ExecuteAction (System.Boolean& yieldedBeforeCompletion) [0x00000] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 
  at System.Threading.Tasks.TaskReplicator+Replica.Execute () [0x00029] in <12b418a7818c4ca0893feeaaf67f1e7f>:0 <---

I'm using Shader Minifier 1.4.0

@LeStahL
Copy link
Author

LeStahL commented Aug 9, 2024

It is possible to use the workaround

#version 450

out vec4 out_color;
uniform float t;

void main() {
    float a, b;

    t > .5
        ? (a = .5, b = .5)
        : (a = .9, b = .1)
        ;
    out_color = vec4(a, b, 1, 1);
}

which gets minified to

#version 450

out vec4 v;
uniform float f;
void main()
{
  float m,N;
  f>.5?
    m=.5,N=.5:
    (m=.9,N=.1);
  v=vec4(m,N,1,1);
}

(That's at the cost of one set of unneccessary (, ) , but enables using declarator lists anyways)

@laurentlb
Copy link
Owner

Thanks for the reports!

For the last point, that was the PR that removed the parentheses between ? and :: #396

@therontarigo
Copy link
Contributor

The "workaround" shader is not the same as the original shader. Without the parentheses, the expression should parse as
(t>.5?a=.5,b=.5:a=.9) , b=.1;
, is lower precedence than ? : in GLSL spec.

N.B. It's easier to understand and discuss outputs if renaming is disabled, since this isn't related to a renamer bug.

@therontarigo
Copy link
Contributor

therontarigo commented Aug 10, 2024

The input line with : is red herring; these all parse correctly in the minifier:
t > .5 ? a = .5 : a = .9, b = .1 ;
float c = t > .5 ? a = .5 : a = .9, b = .1 ; (redefines b, see bug #437)
with different result:
t > .5 ? a = .5 : (a = .9, b = .1) ;
float c = t > .5 ? a = .5 : (a = .9, b = .1) ;

The actual bug may be reproduced more simply; these both fail to parse (with different error messages):
t > .5 ? a, b : a ;
float c = t > .5 ? a, b : a ;
While these parse (this is the relevant workaround):
t > .5 ? (a, b) : a ;
float c = t > .5 ? (a, b) : a ;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants