With this, now we can specify a list of attributes on named ops
generated from the spec. The format is defined as
attr-id ::= bare-id (`?`)? attr-typedef ::= type (`[` `]`)? attr-def ::= attr-id `:` attr-typedef tc-attr-def ::= `attr` `(` attr-def-list `)` tc-def ::= `def` bare-id `(`tensor-def-list`)` `->` `(` tensor-def-list`)` (tc-attr-def)?
For example,
ods_def<SomeCppOp> def some_op(...) -> (...) attr( f32_attr: f32, i32_attr: i32, array_attr : f32[], optional_attr? : f32 )
where ? means optional attribute and [] means array type.
Let's follow other test case -- add // for this blank line.