Skip to content

Restrict grammar for @if #191

Description

@stefnotch

The wesl spec allows for attribute before assignments

@if(foo)
a = 3;

However, I am not sure how to implement that in the language server's parser. It requires arbitrary, complex lookahead. As in, the following is a problem to parse

@some_attr
(very + complex * (expression)) = 3;

When the parser sees the (, it has to make a choice. Does it parse it as an attribute @some_attr(very + complex * (expression)) or is the attribute finished (very + complex * (expression)) = 3;. With backtracking, that's doable. I really do not want backtracking in the language server parser, as it

  • is significantly more complex to maintain
    • would mess with our error recovery capabilities
  • introduces a source of slowdowns even for just WGSL (backtracking is a slowdown)
  • still does not address the fundamental issue of this grammar being ambiguous

To elaborate on the last point, the WGSL grammar recently got extended to allow for function calls in the lhs side of an expression. The following is now syntactically valid WGSL.

foo() = 3;
(foo()) = 3;

If WGSL or WESL ever gets function pointers, then this would be valid WGSL. foo.bar is the function pointer and it's called with value

(foo.bar)(value) = 3;

Combining it with an ambiguous attribute, we get

@if
(foo.bar)(value) = 3;

Which is completely ambiguous. (foo.bar) might either be a part of the attribute or not. We can't have ambiguous grammars.

Now we could say that @if always requires ( after it and that parsing that attribute needs to happen during the parsing step, instead of afterwards.
However, that just punts the problem into the future for when we get around to user defined attributes. And it still leaves me with complications in wgsl-analyzer. Wgsl-analyzer's current attribute handling code is rather complex, further complicated by the fact that it supports both WGSL and WESL. I would like to have a single unified parser for "general" attributes and only assign a meaning to them in the syntax tree layer.

See also
webgpu-tools/wesl-rs#162
#171

Proposal

We should only allow @if before declarations. Everything else can be written as @if { whatever }
Concretely, we should only allow @if before

  • const value declarations
  • variable declarations
  • directives
  • struct declarations

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Todo

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions