tools: intrinsic-gen - [[decoration]] -> @attribute

More closely resembles WGSL.

Change-Id: Ia1b93bb443b4e3bf9329f8026d1924f12648cb7b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/92245
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/tools/src/cmd/intrinsic-gen/ast/ast.go b/tools/src/cmd/intrinsic-gen/ast/ast.go
index 75b74c7..55e7cc0 100644
--- a/tools/src/cmd/intrinsic-gen/ast/ast.go
+++ b/tools/src/cmd/intrinsic-gen/ast/ast.go
@@ -85,15 +85,15 @@
 
 // EnumEntry describes an entry in a enumerator
 type EnumEntry struct {
-	Source      tok.Source
-	Name        string
-	Decorations Decorations
+	Source     tok.Source
+	Name       string
+	Attributes Attributes
 }
 
 // Format implements the fmt.Formatter interface
 func (e EnumEntry) Format(w fmt.State, verb rune) {
-	if len(e.Decorations) > 0 {
-		fmt.Fprintf(w, "%v %v", e.Decorations, e.Name)
+	if len(e.Attributes) > 0 {
+		fmt.Fprintf(w, "%v %v", e.Attributes, e.Name)
 	} else {
 		fmt.Fprint(w, e.Name)
 	}
@@ -136,7 +136,7 @@
 	Source         tok.Source
 	Kind           IntrinsicKind
 	Name           string
-	Decorations    Decorations
+	Attributes     Attributes
 	TemplateParams TemplateParams
 	Parameters     Parameters
 	ReturnType     *TemplatedName
@@ -243,15 +243,15 @@
 // TypeDecl describes a type declaration
 type TypeDecl struct {
 	Source         tok.Source
-	Decorations    Decorations
+	Attributes     Attributes
 	Name           string
 	TemplateParams TemplateParams
 }
 
 // Format implements the fmt.Formatter interface
 func (p TypeDecl) Format(w fmt.State, verb rune) {
-	if len(p.Decorations) > 0 {
-		p.Decorations.Format(w, verb)
+	if len(p.Attributes) > 0 {
+		p.Attributes.Format(w, verb)
 		fmt.Fprintf(w, " type %v", p.Name)
 	}
 	fmt.Fprintf(w, "type %v", p.Name)
@@ -296,13 +296,13 @@
 	}
 }
 
-// Decorations is a list of Decoration
+// Attributes is a list of Attribute
 // Example:
 //   [[a(x), b(y)]]
-type Decorations []Decoration
+type Attributes []Attribute
 
 // Format implements the fmt.Formatter interface
-func (l Decorations) Format(w fmt.State, verb rune) {
+func (l Attributes) Format(w fmt.State, verb rune) {
 	fmt.Fprint(w, "[[")
 	for i, d := range l {
 		if i > 0 {
@@ -313,30 +313,30 @@
 	fmt.Fprint(w, "]]")
 }
 
-// Take looks up the decoration with the given name. If the decoration is found
-// it is removed from the Decorations list and returned, otherwise nil is
-// returned and the Decorations are not altered.
-func (l *Decorations) Take(name string) *Decoration {
-	for i, d := range *l {
-		if d.Name == name {
+// Take looks up the attribute with the given name. If the attribute is found
+// it is removed from the Attributes list and returned, otherwise nil is
+// returned and the Attributes are not altered.
+func (l *Attributes) Take(name string) *Attribute {
+	for i, a := range *l {
+		if a.Name == name {
 			*l = append((*l)[:i], (*l)[i+1:]...)
-			return &d
+			return &a
 		}
 	}
 	return nil
 }
 
-// Decoration describes a single decoration
+// Attribute describes a single attribute
 // Example:
-//   a(x)
-type Decoration struct {
+//   @a(x)
+type Attribute struct {
 	Source tok.Source
 	Name   string
 	Values []string
 }
 
 // Format implements the fmt.Formatter interface
-func (d Decoration) Format(w fmt.State, verb rune) {
+func (d Attribute) Format(w fmt.State, verb rune) {
 	fmt.Fprintf(w, "%v", d.Name)
 	if len(d.Values) > 0 {
 		fmt.Fprintf(w, "(")
diff --git a/tools/src/cmd/intrinsic-gen/lexer/lexer.go b/tools/src/cmd/intrinsic-gen/lexer/lexer.go
index a81875e..d8a486a 100644
--- a/tools/src/cmd/intrinsic-gen/lexer/lexer.go
+++ b/tools/src/cmd/intrinsic-gen/lexer/lexer.go
@@ -52,6 +52,8 @@
 			l.next()
 		case '\n':
 			l.next()
+		case '@':
+			l.tok(1, tok.Attr)
 		case '(':
 			l.tok(1, tok.Lparen)
 		case ')':
@@ -89,8 +91,6 @@
 				l.skip(l.count(toFirst('\n')))
 				l.next() // Consume newline
 			case l.match("/", tok.Divide):
-			case l.match("[[", tok.Ldeco):
-			case l.match("]]", tok.Rdeco):
 			case l.match("->", tok.Arrow):
 			case l.match("-", tok.Minus):
 			case l.match("fn", tok.Function):
diff --git a/tools/src/cmd/intrinsic-gen/lexer/lexer_test.go b/tools/src/cmd/intrinsic-gen/lexer/lexer_test.go
index f17eb23..21d5787 100644
--- a/tools/src/cmd/intrinsic-gen/lexer/lexer_test.go
+++ b/tools/src/cmd/intrinsic-gen/lexer/lexer_test.go
@@ -127,11 +127,8 @@
 		{">", tok.Token{Kind: tok.Gt, Runes: []rune(">"), Source: tok.Source{
 			S: loc(1, 1, 0), E: loc(1, 2, 1),
 		}}},
-		{"[[", tok.Token{Kind: tok.Ldeco, Runes: []rune("[["), Source: tok.Source{
-			S: loc(1, 1, 0), E: loc(1, 3, 2),
-		}}},
-		{"]]", tok.Token{Kind: tok.Rdeco, Runes: []rune("]]"), Source: tok.Source{
-			S: loc(1, 1, 0), E: loc(1, 3, 2),
+		{"@", tok.Token{Kind: tok.Attr, Runes: []rune("@"), Source: tok.Source{
+			S: loc(1, 1, 0), E: loc(1, 2, 1),
 		}}},
 		{"(", tok.Token{Kind: tok.Lparen, Runes: []rune("("), Source: tok.Source{
 			S: loc(1, 1, 0), E: loc(1, 2, 1),
diff --git a/tools/src/cmd/intrinsic-gen/parser/parser.go b/tools/src/cmd/intrinsic-gen/parser/parser.go
index f381b3a..b1a87f1 100644
--- a/tools/src/cmd/intrinsic-gen/parser/parser.go
+++ b/tools/src/cmd/intrinsic-gen/parser/parser.go
@@ -43,40 +43,40 @@
 
 func (p *parser) parse() (*ast.AST, error) {
 	out := ast.AST{}
-	var decorations ast.Decorations
+	var attributes ast.Attributes
 	for p.err == nil {
 		t := p.peek(0)
 		if t == nil {
 			break
 		}
 		switch t.Kind {
-		case tok.Ldeco:
-			decorations = append(decorations, p.decorations()...)
+		case tok.Attr:
+			attributes = append(attributes, p.attributes()...)
 		case tok.Enum:
-			if len(decorations) > 0 {
-				p.err = fmt.Errorf("%v unexpected decoration", decorations[0].Source)
+			if len(attributes) > 0 {
+				p.err = fmt.Errorf("%v unexpected attribute", attributes[0].Source)
 			}
 			out.Enums = append(out.Enums, p.enumDecl())
 		case tok.Match:
-			if len(decorations) > 0 {
-				p.err = fmt.Errorf("%v unexpected decoration", decorations[0].Source)
+			if len(attributes) > 0 {
+				p.err = fmt.Errorf("%v unexpected attribute", attributes[0].Source)
 			}
 			out.Matchers = append(out.Matchers, p.matcherDecl())
 		case tok.Type:
-			out.Types = append(out.Types, p.typeDecl(decorations))
-			decorations = nil
+			out.Types = append(out.Types, p.typeDecl(attributes))
+			attributes = nil
 		case tok.Function:
-			out.Builtins = append(out.Builtins, p.builtinDecl(decorations))
-			decorations = nil
+			out.Builtins = append(out.Builtins, p.builtinDecl(attributes))
+			attributes = nil
 		case tok.Operator:
-			out.Operators = append(out.Operators, p.operatorDecl(decorations))
-			decorations = nil
+			out.Operators = append(out.Operators, p.operatorDecl(attributes))
+			attributes = nil
 		case tok.Constructor:
-			out.Constructors = append(out.Constructors, p.constructorDecl(decorations))
-			decorations = nil
+			out.Constructors = append(out.Constructors, p.constructorDecl(attributes))
+			attributes = nil
 		case tok.Converter:
-			out.Converters = append(out.Converters, p.converterDecl(decorations))
-			decorations = nil
+			out.Converters = append(out.Converters, p.converterDecl(attributes))
+			attributes = nil
 		default:
 			p.err = fmt.Errorf("%v unexpected token '%v'", t.Source, t.Kind)
 		}
@@ -99,9 +99,9 @@
 }
 
 func (p *parser) enumEntry() ast.EnumEntry {
-	decos := p.decorations()
+	decos := p.attributes()
 	name := p.expect(tok.Identifier, "enum entry")
-	return ast.EnumEntry{Source: name.Source, Decorations: decos, Name: string(name.Runes)}
+	return ast.EnumEntry{Source: name.Source, Attributes: decos, Name: string(name.Runes)}
 }
 
 func (p *parser) matcherDecl() ast.MatcherDecl {
@@ -118,13 +118,13 @@
 	return m
 }
 
-func (p *parser) typeDecl(decos ast.Decorations) ast.TypeDecl {
+func (p *parser) typeDecl(decos ast.Attributes) ast.TypeDecl {
 	p.expect(tok.Type, "type declaration")
 	name := p.expect(tok.Identifier, "type name")
 	m := ast.TypeDecl{
-		Source:      name.Source,
-		Decorations: decos,
-		Name:        string(name.Runes),
+		Source:     name.Source,
+		Attributes: decos,
+		Name:       string(name.Runes),
 	}
 	if p.peekIs(0, tok.Lt) {
 		m.TemplateParams = p.templateParams()
@@ -132,13 +132,10 @@
 	return m
 }
 
-func (p *parser) decorations() ast.Decorations {
-	if p.match(tok.Ldeco) == nil {
-		return nil
-	}
-	out := ast.Decorations{}
-	for p.err == nil {
-		name := p.expect(tok.Identifier, "decoration name")
+func (p *parser) attributes() ast.Attributes {
+	var out ast.Attributes
+	for p.match(tok.Attr) != nil && p.err == nil {
+		name := p.expect(tok.Identifier, "attribute name")
 		values := []string{}
 		if p.match(tok.Lparen) != nil {
 			for p.err == nil {
@@ -147,29 +144,25 @@
 					break
 				}
 			}
-			p.expect(tok.Rparen, "decoration values")
+			p.expect(tok.Rparen, "attribute values")
 		}
-		out = append(out, ast.Decoration{
+		out = append(out, ast.Attribute{
 			Source: name.Source,
 			Name:   string(name.Runes),
 			Values: values,
 		})
-		if p.match(tok.Comma) == nil {
-			break
-		}
 	}
-	p.expect(tok.Rdeco, "decoration list")
 	return out
 }
 
-func (p *parser) builtinDecl(decos ast.Decorations) ast.IntrinsicDecl {
+func (p *parser) builtinDecl(decos ast.Attributes) ast.IntrinsicDecl {
 	p.expect(tok.Function, "function declaration")
 	name := p.expect(tok.Identifier, "function name")
 	f := ast.IntrinsicDecl{
-		Source:      name.Source,
-		Kind:        ast.Builtin,
-		Decorations: decos,
-		Name:        string(name.Runes),
+		Source:     name.Source,
+		Kind:       ast.Builtin,
+		Attributes: decos,
+		Name:       string(name.Runes),
 	}
 	if p.peekIs(0, tok.Lt) {
 		f.TemplateParams = p.templateParams()
@@ -182,14 +175,14 @@
 	return f
 }
 
-func (p *parser) operatorDecl(decos ast.Decorations) ast.IntrinsicDecl {
+func (p *parser) operatorDecl(decos ast.Attributes) ast.IntrinsicDecl {
 	p.expect(tok.Operator, "operator declaration")
 	name := p.next()
 	f := ast.IntrinsicDecl{
-		Source:      name.Source,
-		Kind:        ast.Operator,
-		Decorations: decos,
-		Name:        string(name.Runes),
+		Source:     name.Source,
+		Kind:       ast.Operator,
+		Attributes: decos,
+		Name:       string(name.Runes),
 	}
 	if p.peekIs(0, tok.Lt) {
 		f.TemplateParams = p.templateParams()
@@ -202,14 +195,14 @@
 	return f
 }
 
-func (p *parser) constructorDecl(decos ast.Decorations) ast.IntrinsicDecl {
+func (p *parser) constructorDecl(decos ast.Attributes) ast.IntrinsicDecl {
 	p.expect(tok.Constructor, "constructor declaration")
 	name := p.next()
 	f := ast.IntrinsicDecl{
-		Source:      name.Source,
-		Kind:        ast.Constructor,
-		Decorations: decos,
-		Name:        string(name.Runes),
+		Source:     name.Source,
+		Kind:       ast.Constructor,
+		Attributes: decos,
+		Name:       string(name.Runes),
 	}
 	if p.peekIs(0, tok.Lt) {
 		f.TemplateParams = p.templateParams()
@@ -222,14 +215,14 @@
 	return f
 }
 
-func (p *parser) converterDecl(decos ast.Decorations) ast.IntrinsicDecl {
+func (p *parser) converterDecl(decos ast.Attributes) ast.IntrinsicDecl {
 	p.expect(tok.Converter, "converter declaration")
 	name := p.next()
 	f := ast.IntrinsicDecl{
-		Source:      name.Source,
-		Kind:        ast.Converter,
-		Decorations: decos,
-		Name:        string(name.Runes),
+		Source:     name.Source,
+		Kind:       ast.Converter,
+		Attributes: decos,
+		Name:       string(name.Runes),
 	}
 	if p.peekIs(0, tok.Lt) {
 		f.TemplateParams = p.templateParams()
diff --git a/tools/src/cmd/intrinsic-gen/parser/parser_test.go b/tools/src/cmd/intrinsic-gen/parser/parser_test.go
index 0dea9b3..405aad2 100644
--- a/tools/src/cmd/intrinsic-gen/parser/parser_test.go
+++ b/tools/src/cmd/intrinsic-gen/parser/parser_test.go
@@ -43,15 +43,15 @@
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			utils.ThisLine(),
-			"enum E { A [[deco]] B C }",
+			"enum E { A @attr B C }",
 			ast.AST{
 				Enums: []ast.EnumDecl{{
 					Name: "E",
 					Entries: []ast.EnumEntry{
 						{Name: "A"},
 						{
-							Decorations: ast.Decorations{{
-								Name:   "deco",
+							Attributes: ast.Attributes{{
+								Name:   "attr",
 								Values: []string{},
 							}},
 							Name: "B",
@@ -81,43 +81,43 @@
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			utils.ThisLine(),
-			"[[deco]] type T",
+			"@attr type T",
 			ast.AST{
 				Types: []ast.TypeDecl{{
-					Decorations: ast.Decorations{
-						{Name: "deco", Values: []string{}},
+					Attributes: ast.Attributes{
+						{Name: "attr", Values: []string{}},
 					},
 					Name: "T",
 				}},
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			utils.ThisLine(),
-			"[[deco_a, deco_b]] type T",
+			"@attr_a @attr_b type T",
 			ast.AST{
 				Types: []ast.TypeDecl{{
-					Decorations: ast.Decorations{
-						{Name: "deco_a", Values: []string{}},
-						{Name: "deco_b", Values: []string{}},
+					Attributes: ast.Attributes{
+						{Name: "attr_a", Values: []string{}},
+						{Name: "attr_b", Values: []string{}},
 					},
 					Name: "T",
 				}},
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			utils.ThisLine(),
-			`[[deco("a", "b")]] type T`, ast.AST{
+			`@attr("a", "b") type T`, ast.AST{
 				Types: []ast.TypeDecl{{
-					Decorations: ast.Decorations{
-						{Name: "deco", Values: []string{"a", "b"}},
+					Attributes: ast.Attributes{
+						{Name: "attr", Values: []string{"a", "b"}},
 					},
 					Name: "T",
 				}},
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			utils.ThisLine(),
-			`[[deco(1, "x")]] type T`, ast.AST{
+			`@attr(1, "x") type T`, ast.AST{
 				Types: []ast.TypeDecl{{
-					Decorations: ast.Decorations{
-						{Name: "deco", Values: []string{"1", "x"}},
+					Attributes: ast.Attributes{
+						{Name: "attr", Values: []string{"1", "x"}},
 					},
 					Name: "T",
 				}},
@@ -157,13 +157,13 @@
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			utils.ThisLine(),
-			"[[deco]] fn F()",
+			"@attr fn F()",
 			ast.AST{
 				Builtins: []ast.IntrinsicDecl{{
 					Kind: ast.Builtin,
 					Name: "F",
-					Decorations: ast.Decorations{
-						{Name: "deco", Values: []string{}},
+					Attributes: ast.Attributes{
+						{Name: "attr", Values: []string{}},
 					},
 					Parameters: ast.Parameters{},
 				}},
@@ -281,13 +281,13 @@
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			utils.ThisLine(),
-			"[[deco]] op F()",
+			"@attr op F()",
 			ast.AST{
 				Operators: []ast.IntrinsicDecl{{
 					Kind: ast.Operator,
 					Name: "F",
-					Decorations: ast.Decorations{
-						{Name: "deco", Values: []string{}},
+					Attributes: ast.Attributes{
+						{Name: "attr", Values: []string{}},
 					},
 					Parameters: ast.Parameters{},
 				}},
@@ -405,13 +405,13 @@
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			utils.ThisLine(),
-			"[[deco]] ctor F()",
+			"@attr ctor F()",
 			ast.AST{
 				Constructors: []ast.IntrinsicDecl{{
 					Kind: ast.Constructor,
 					Name: "F",
-					Decorations: ast.Decorations{
-						{Name: "deco", Values: []string{}},
+					Attributes: ast.Attributes{
+						{Name: "attr", Values: []string{}},
 					},
 					Parameters: ast.Parameters{},
 				}},
@@ -529,13 +529,13 @@
 			},
 		}, { ///////////////////////////////////////////////////////////////////
 			utils.ThisLine(),
-			"[[deco]] conv F()",
+			"@attr conv F()",
 			ast.AST{
 				Converters: []ast.IntrinsicDecl{{
 					Kind: ast.Converter,
 					Name: "F",
-					Decorations: ast.Decorations{
-						{Name: "deco", Values: []string{}},
+					Attributes: ast.Attributes{
+						{Name: "attr", Values: []string{}},
 					},
 					Parameters: ast.Parameters{},
 				}},
@@ -672,16 +672,16 @@
 			"test.txt:1:1 unexpected token 'integer'",
 		},
 		{
-			"[[123]]",
-			"test.txt:1:3 expected 'ident' for decoration name, got 'integer'",
-		},
-		{
-			"[[abc",
-			"expected ']]' for decoration list, but reached end of file",
+			"@123",
+			"test.txt:1:2 expected 'ident' for attribute name, got 'integer'",
 		},
 	} {
 		got, err := parser.Parse(test.src, "test.txt")
-		if gotErr := err.Error(); test.expect != gotErr {
+		gotErr := ""
+		if err != nil {
+			gotErr = err.Error()
+		}
+		if test.expect != gotErr {
 			t.Errorf(`Parse() returned error "%+v", expected error "%+v"`, gotErr, test.expect)
 		}
 		if got != nil {
diff --git a/tools/src/cmd/intrinsic-gen/resolver/resolve.go b/tools/src/cmd/intrinsic-gen/resolver/resolve.go
index 4972a3d..f3894d4 100644
--- a/tools/src/cmd/intrinsic-gen/resolver/resolve.go
+++ b/tools/src/cmd/intrinsic-gen/resolver/resolve.go
@@ -130,14 +130,14 @@
 			Name: ast.Name,
 			Enum: s,
 		}
-		if internal := ast.Decorations.Take("internal"); internal != nil {
+		if internal := ast.Attributes.Take("internal"); internal != nil {
 			entry.IsInternal = true
 			if len(internal.Values) != 0 {
-				return fmt.Errorf("%v unexpected value for internal decoration", ast.Source)
+				return fmt.Errorf("%v unexpected value for internal attribute", ast.Source)
 			}
 		}
-		if len(ast.Decorations) != 0 {
-			return fmt.Errorf("%v unknown decoration", ast.Decorations[0].Source)
+		if len(ast.Attributes) != 0 {
+			return fmt.Errorf("%v unknown attribute", ast.Attributes[0].Source)
 		}
 		if err := r.globals.declare(entry, e.Source); err != nil {
 			return err
@@ -173,16 +173,16 @@
 	}
 	t.TemplateParams = templateParams
 
-	// Scan for decorations
-	if d := a.Decorations.Take("display"); d != nil {
+	// Scan for attributes
+	if d := a.Attributes.Take("display"); d != nil {
 		if len(d.Values) != 1 {
-			return fmt.Errorf("%v expected a single value for 'display' decoration", d.Source)
+			return fmt.Errorf("%v expected a single value for 'display' attribute", d.Source)
 		}
 		t.DisplayName = d.Values[0]
 	}
-	if d := a.Decorations.Take("precedence"); d != nil {
+	if d := a.Attributes.Take("precedence"); d != nil {
 		if len(d.Values) != 1 {
-			return fmt.Errorf("%v expected a single integer value for 'precedence' decoration", d.Source)
+			return fmt.Errorf("%v expected a single integer value for 'precedence' attribute", d.Source)
 		}
 		n, err := strconv.Atoi(d.Values[0])
 		if err != nil {
@@ -191,8 +191,8 @@
 		t.Precedence = n
 	}
 
-	if len(a.Decorations) != 0 {
-		return fmt.Errorf("%v unknown decoration", a.Decorations[0].Source)
+	if len(a.Attributes) != 0 {
+		return fmt.Errorf("%v unknown attribute", a.Attributes[0].Source)
 	}
 
 	return nil
@@ -302,8 +302,8 @@
 		TemplateParams: templateParams,
 	}
 
-	// Process overload decorations
-	if stageDeco := a.Decorations.Take("stage"); stageDeco != nil {
+	// Process overload attributes
+	if stageDeco := a.Attributes.Take("stage"); stageDeco != nil {
 		for stageDeco != nil {
 			for _, stage := range stageDeco.Values {
 				switch stage {
@@ -317,7 +317,7 @@
 					return fmt.Errorf("%v unknown stage '%v'", stageDeco.Source, stage)
 				}
 			}
-			stageDeco = a.Decorations.Take("stage")
+			stageDeco = a.Attributes.Take("stage")
 		}
 	} else {
 		overload.CanBeUsedInStage = sem.StageUses{
@@ -326,14 +326,14 @@
 			Compute:  true,
 		}
 	}
-	if deprecated := a.Decorations.Take("deprecated"); deprecated != nil {
+	if deprecated := a.Attributes.Take("deprecated"); deprecated != nil {
 		overload.IsDeprecated = true
 		if len(deprecated.Values) != 0 {
-			return fmt.Errorf("%v unexpected value for deprecated decoration", deprecated.Source)
+			return fmt.Errorf("%v unexpected value for deprecated attribute", deprecated.Source)
 		}
 	}
-	if len(a.Decorations) != 0 {
-		return fmt.Errorf("%v unknown decoration", a.Decorations[0].Source)
+	if len(a.Attributes) != 0 {
+		return fmt.Errorf("%v unknown attribute", a.Attributes[0].Source)
 	}
 
 	// Append the overload to the intrinsic
diff --git a/tools/src/cmd/intrinsic-gen/resolver/resolver_test.go b/tools/src/cmd/intrinsic-gen/resolver/resolver_test.go
index 7ce9236..6679431 100644
--- a/tools/src/cmd/intrinsic-gen/resolver/resolver_test.go
+++ b/tools/src/cmd/intrinsic-gen/resolver/resolver_test.go
@@ -44,7 +44,7 @@
 			`type X`,
 			success,
 		}, {
-			`[[display("Y")]] type X`,
+			`@display("Y") type X`,
 			success,
 		}, {
 			`
@@ -188,14 +188,14 @@
 file.txt:1:13 'X' already declared
 First declared here: file.txt:1:6`,
 		}, {
-			`[[meow]] type X`,
+			`@meow type X`,
 			`
-file.txt:1:3 unknown decoration
+file.txt:1:2 unknown attribute
 `,
 		}, {
-			`[[display("Y", "Z")]] type X`,
+			`@display("Y", "Z") type X`,
 			`
-file.txt:1:3 expected a single value for 'display' decoration`,
+file.txt:1:2 expected a single value for 'display' attribute`,
 		}, {
 			`
 enum e { a }
diff --git a/tools/src/cmd/intrinsic-gen/tok/tok.go b/tools/src/cmd/intrinsic-gen/tok/tok.go
index c5def48..b34f19e 100644
--- a/tools/src/cmd/intrinsic-gen/tok/tok.go
+++ b/tools/src/cmd/intrinsic-gen/tok/tok.go
@@ -37,6 +37,7 @@
 	And          Kind = "&"
 	AndAnd       Kind = "&&"
 	Arrow        Kind = "->"
+	Attr         Kind = "@"
 	Assign       Kind = "="
 	Colon        Kind = ":"
 	Comma        Kind = ","
@@ -46,7 +47,6 @@
 	Ge           Kind = ">="
 	Gt           Kind = ">"
 	Lbrace       Kind = "{"
-	Ldeco        Kind = "[["
 	Le           Kind = "<="
 	Lparen       Kind = "("
 	Lt           Kind = "<"
@@ -58,7 +58,6 @@
 	OrOr         Kind = "||"
 	Plus         Kind = "+"
 	Rbrace       Kind = "}"
-	Rdeco        Kind = "]]"
 	Rparen       Kind = ")"
 	Shl          Kind = "<<"
 	Shr          Kind = ">>"