470 lines
22 KiB
JavaScript
470 lines
22 KiB
JavaScript
'use strict';
|
|
|
|
const builtin_dialect = require('./dialect/builtin');
|
|
const func_dialect = require('./dialect/func');
|
|
const llvm_dialect = require('./dialect/llvm');
|
|
const arith_dialect = require('./dialect/arith');
|
|
const math_dialect = require('./dialect/math');
|
|
const cf_dialect = require('./dialect/cf');
|
|
const scf_dialect = require('./dialect/scf');
|
|
const memref_dialect = require('./dialect/memref');
|
|
const vector_dialect = require('./dialect/vector');
|
|
const tensor_dialect = require('./dialect/tensor');
|
|
const bufferization_dialect = require('./dialect/bufferization');
|
|
const affine_dialect = require('./dialect/affine');
|
|
const linalg_dialect = require('./dialect/linalg');
|
|
|
|
const common = {
|
|
// Top level production:
|
|
// (operation | attribute-alias-def | type-alias-def)
|
|
toplevel : $ => seq($._toplevel, repeat($._toplevel)),
|
|
_toplevel : $ => choice($.operation, $.attribute_alias_def, $.type_alias_def),
|
|
|
|
// Common syntax (lang-ref)
|
|
// digit ::= [0-9]
|
|
// hex_digit ::= [0-9a-fA-F]
|
|
// letter ::= [a-zA-Z]
|
|
// id-punct ::= [$._-]
|
|
//
|
|
// integer-literal ::= decimal-literal | hexadecimal-literal
|
|
// decimal-literal ::= digit+
|
|
// hexadecimal-literal ::= `0x` hex_digit+
|
|
// float-literal ::= [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
|
|
// string-literal ::= `"` [^"\n\f\v\r]* `"` TODO: define escaping rules
|
|
//
|
|
_digit : $ => /[0-9]/,
|
|
integer_literal : $ => choice($._decimal_literal, $._hexadecimal_literal),
|
|
_decimal_literal : $ => token(seq(optional(/[-+]/), repeat1(/[0-9]/))),
|
|
_hexadecimal_literal : $ => token(seq('0x', repeat1(/[0-9a-fA-F]/))),
|
|
float_literal : $ =>
|
|
token(seq(optional(/[-+]/), repeat1(/[0-9]/), '.', repeat(/[0-9]/),
|
|
optional(seq(/[eE]/, optional(/[-+]/), repeat1(/[0-9]/))))),
|
|
string_literal : $ => token(seq('"', repeat(/[^\\"\n\f\v\r]+/), '"')),
|
|
bool_literal : $ => token(choice('true', 'false')),
|
|
unit_literal : $ => token('unit'),
|
|
complex_literal : $ =>
|
|
seq('(', choice($.integer_literal, $.float_literal), ',',
|
|
choice($.integer_literal, $.float_literal), ')'),
|
|
tensor_literal : $ =>
|
|
seq(token(choice('dense', 'sparse')), '<',
|
|
optional(choice(
|
|
seq($.nested_idx_list, repeat(seq(',', $.nested_idx_list))),
|
|
$._primitive_idx_literal)),
|
|
'>'),
|
|
array_literal : $ => seq(token('array'), '<', $.type, ':', $._idx_list, '>'),
|
|
_literal : $ => choice($.integer_literal, $.float_literal, $.string_literal,
|
|
$.bool_literal, $.tensor_literal, $.array_literal,
|
|
$.complex_literal, $.unit_literal),
|
|
|
|
nested_idx_list : $ =>
|
|
seq('[', optional(choice($.nested_idx_list, $._idx_list)),
|
|
repeat(seq(',', $.nested_idx_list)), ']'),
|
|
_idx_list : $ => prec.right(seq($._primitive_idx_literal,
|
|
repeat(seq(',', $._primitive_idx_literal)))),
|
|
_primitive_idx_literal : $ => choice($.integer_literal, $.float_literal,
|
|
$.bool_literal, $.complex_literal),
|
|
|
|
// Identifiers
|
|
// bare-id ::= (letter|[_]) (letter|digit|[_$.])*
|
|
// bare-id-list ::= bare-id (`,` bare-id)*
|
|
// value-id ::= `%` suffix-id
|
|
// suffix-id ::= (digit+ | ((letter|id-punct) (letter|id-punct|digit)*))
|
|
// alias-name :: = bare-id
|
|
//
|
|
// symbol-ref-id ::= `@` (suffix-id | string-literal) (`::`
|
|
// symbol-ref-id)?
|
|
// value-id-list ::= value-id (`,` value-id)*
|
|
//
|
|
// // Uses of value, e.g. in an operand list to an operation.
|
|
// value-use ::= value-id
|
|
// value-use-list ::= value-use (`,` value-use)*
|
|
bare_id : $ => token(seq(/[a-zA-Z_]/, repeat(/[a-zA-Z0-9_$.]/))),
|
|
_alias_or_dialect_id : $ => token(seq(/[a-zA-Z_]/, repeat(/[a-zA-Z0-9_$]/))),
|
|
bare_id_list : $ => seq($.bare_id, repeat(seq(',', $.bare_id))),
|
|
value_use : $ => seq('%', $._suffix_id),
|
|
_suffix_id : $ => token(seq(
|
|
choice(repeat1(/[0-9]/), seq(/[a-zA-Z_$.-]/, repeat(/[a-zA-Z0-9_$.-]/))),
|
|
optional(seq(choice(':', '#'), repeat1(/[0-9]/))))),
|
|
symbol_ref_id : $ => seq('@', choice($._suffix_id, $.string_literal),
|
|
optional(seq('::', $.symbol_ref_id))),
|
|
_value_use_list : $ => seq($.value_use, repeat(seq(',', $.value_use))),
|
|
|
|
// Operations
|
|
// operation ::= op-result-list? (generic-operation |
|
|
// custom-operation)
|
|
// trailing-location?
|
|
// generic-operation ::= string-literal `(` value-use-list? `)`
|
|
// successor-list? region-list?
|
|
// dictionary-attribute? `:` function-type
|
|
// custom-operation ::= bare-id custom-operation-format
|
|
// op-result-list ::= op-result (`,` op-result)* `=`
|
|
// op-result ::= value-id (`:` integer-literal)
|
|
// successor-list ::= `[` successor (`,` successor)* `]`
|
|
// successor ::= caret-id (`:` bb-arg-list)?
|
|
// region-list ::= `(` region (`,` region)* `)`
|
|
// dictionary-attribute ::= `{` (attribute-entry (`,` attribute-entry)*)?
|
|
// `}`
|
|
// trailing-location ::= (`loc` `(` location `)`)?
|
|
operation : $ =>
|
|
seq(field('lhs', optional($._op_result_list)),
|
|
field('rhs', choice($.generic_operation, $.custom_operation)),
|
|
field('location', optional($.trailing_location))),
|
|
generic_operation : $ => seq(
|
|
$.string_literal, $._value_use_list_parens, optional($._successor_list),
|
|
optional($._region_list), optional($.attribute), ':', $.function_type),
|
|
// custom-operation rule is defined later in the grammar, post the generic.
|
|
_op_result_list : $ => seq($.op_result, repeat(seq(',', $.op_result)), '='),
|
|
op_result : $ => seq($.value_use, optional(seq(':', $.integer_literal))),
|
|
_successor_list : $ =>
|
|
seq('[', $.successor, repeat(seq(',', $.successor)), ']'),
|
|
successor : $ => seq($.caret_id, optional($._value_arg_list)),
|
|
_region_list : $ => seq('(', $.region, repeat(seq(',', $.region)), ')'),
|
|
dictionary_attribute : $ => seq('{', optional($.attribute_entry),
|
|
repeat(seq(',', $.attribute_entry)), '}'),
|
|
trailing_location : $ => seq(token('loc'), '(', $.location, ')'),
|
|
// TODO: Complete location forms.
|
|
location : $ => $.string_literal,
|
|
|
|
// Blocks
|
|
// block ::= block-label operation+
|
|
// block-label ::= block-id block-arg-list? `:`
|
|
// block-id ::= caret-id
|
|
// caret-id ::= `^` suffix-id
|
|
// value-id-and-type ::= value-id `:` type
|
|
//
|
|
// // Non-empty list of names and types.
|
|
// value-id-and-type-list ::= value-id-and-type (`,` value-id-and-type)*
|
|
//
|
|
// block-arg-list ::= `(` value-id-and-type-list? `)`
|
|
block : $ => seq($.block_label, repeat1($.operation)),
|
|
block_label : $ => seq($._block_id, optional($.block_arg_list), ':'),
|
|
_block_id : $ => $.caret_id,
|
|
caret_id : $ => seq('^', $._suffix_id),
|
|
_value_use_and_type : $ => seq($.value_use, optional(seq(':', $.type))),
|
|
_value_use_and_type_list : $ =>
|
|
seq($._value_use_and_type, repeat(seq(',', $._value_use_and_type))),
|
|
block_arg_list : $ => seq('(', optional($._value_use_and_type_list), ')'),
|
|
_value_arg_list : $ => seq('(', optional($._value_use_type_list), ')'),
|
|
_value_use_type_list : $ => seq($._value_use_list, $._type_annotation),
|
|
|
|
// Regions
|
|
// region ::= `{` entry-block? block* `}`
|
|
// entry-block ::= operation+
|
|
region : $ => seq('{', optional($.entry_block), repeat($.block), '}'),
|
|
entry_block : $ => repeat1($.operation),
|
|
|
|
// Types
|
|
// type ::= type-alias | dialect-type | builtin-type
|
|
//
|
|
// type-list-no-parens ::= type (`,` type)*
|
|
// type-list-parens ::= `(` type-list-no-parens? `)`
|
|
//
|
|
// // This is a common way to refer to a value with a specified type.
|
|
// ssa-use-and-type ::= ssa-use `:` type
|
|
// ssa-use ::= value-use
|
|
//
|
|
// // Non-empty list of names and types.
|
|
// ssa-use-and-type-list ::= ssa-use-and-type (`,` ssa-use-and-type)*
|
|
//
|
|
// function-type ::= (type | type-list-parens) `->` (type |
|
|
// type-list-parens)
|
|
type : $ => choice($.type_alias, $.dialect_type, $.builtin_type),
|
|
_type_list_no_parens : $ => prec.left(seq($.type, repeat(seq(',', $.type)))),
|
|
_type_list_parens : $ => seq('(', optional($._type_list_no_parens), ')'),
|
|
function_type : $ =>
|
|
seq(choice($.type, $._type_list_parens), $._function_return),
|
|
_function_return : $ => seq(token('->'), choice($.type, $._type_list_parens)),
|
|
_type_annotation : $ =>
|
|
seq(':', choice(seq($.type, choice('from', 'into', 'to'), $.type),
|
|
$._type_list_no_parens)),
|
|
_function_type_annotation : $ => seq(':', $.function_type),
|
|
_literal_and_type : $ => seq($._literal, optional($._type_annotation)),
|
|
|
|
// Type aliases
|
|
// type-alias-def ::= '!' alias-name '=' type
|
|
// type-alias ::= '!' alias-name
|
|
type_alias_def : $ => seq('!', $._alias_or_dialect_id, '=', $.type),
|
|
type_alias : $ => seq('!', $._alias_or_dialect_id),
|
|
|
|
// Dialect Types
|
|
// dialect-namespace ::= bare-id
|
|
//
|
|
// opaque-dialect-item ::= dialect-namespace '<' string-literal '>'
|
|
//
|
|
// pretty-dialect-item ::= dialect-namespace '.'
|
|
// pretty-dialect-item-lead-ident pretty-dialect-item-body?
|
|
//
|
|
// pretty-dialect-item-lead-ident ::= '[A-Za-z][A-Za-z0-9._]*'
|
|
// pretty-dialect-item-body ::= '<' pretty-dialect-item-contents+ '>'
|
|
// pretty-dialect-item-contents ::= pretty-dialect-item-body
|
|
// | '(' pretty-dialect-item-contents+ ')'
|
|
// | '[' pretty-dialect-item-contents+ ']'
|
|
// | '{' pretty-dialect-item-contents+ '}'
|
|
// | '[^[<({>\])}\0]+'
|
|
//
|
|
// dialect-type ::= '!' (opaque-dialect-item | pretty-dialect-item)
|
|
dialect_type : $ =>
|
|
seq('!', choice($.opaque_dialect_item, $.pretty_dialect_item)),
|
|
dialect_namespace : $ => $._alias_or_dialect_id,
|
|
dialect_ident : $ => $._alias_or_dialect_id,
|
|
opaque_dialect_item : $ =>
|
|
seq($.dialect_namespace, '<', $.string_literal, '>'),
|
|
pretty_dialect_item : $ => seq($.dialect_namespace, '.', $.dialect_ident,
|
|
optional($.pretty_dialect_item_body)),
|
|
pretty_dialect_item_body : $ =>
|
|
seq('<', repeat($._pretty_dialect_item_contents), '>'),
|
|
_pretty_dialect_item_contents : $ =>
|
|
prec.left(choice($.pretty_dialect_item_body, repeat1(/[^<>]/))),
|
|
|
|
// Builtin types
|
|
builtin_type : $ => choice(
|
|
// TODO: Add opaque_type
|
|
$.integer_type, $.float_type, $.complex_type, $.index_type, $.memref_type,
|
|
$.none_type, $.tensor_type, $.vector_type, $.tuple_type),
|
|
|
|
// signed-integer-type ::= `si`[1-9][0-9]*
|
|
// unsigned-integer-type ::= `ui`[1-9][0-9]*
|
|
// signless-integer-type ::= `i`[1-9][0-9]*
|
|
// integer-type ::= signed-integer-type | unsigned-integer-type |
|
|
// signless-integer-type
|
|
integer_type : $ =>
|
|
token(seq(choice('si', 'ui', 'i'), /[1-9]/, repeat(/[0-9]/))),
|
|
float_type : $ => token(
|
|
choice('f16', 'f32', 'f64', 'f80', 'f128', 'bf16', 'f8E4M3FN', 'f8E5M2')),
|
|
index_type : $ => token('index'),
|
|
none_type : $ => token('none'),
|
|
complex_type : $ => seq(token('complex'), '<', $._prim_type, '>'),
|
|
_prim_type : $ =>
|
|
choice($.integer_type, $.float_type, $.index_type, $.complex_type,
|
|
$.none_type, $.memref_type, $.vector_type, $.tensor_type),
|
|
|
|
// memref-type ::= `memref` `<` dimension-list-ranked type
|
|
// (`,` layout-specification)? (`,` memory-space)? `>`
|
|
// layout-specification ::= attribute-value
|
|
// memory-space ::= attribute-value
|
|
memref_type : $ =>
|
|
seq(token('memref'), '<', field('dimension_list', $.dim_list),
|
|
optional(seq(',', $.attribute_value)),
|
|
optional(seq(',', $.attribute_value)), '>'),
|
|
dim_list : $ => seq($._dim_primitive, repeat(seq('x', $._dim_primitive))),
|
|
_dim_primitive : $ => choice($._prim_type, repeat1($._digit), '?', '*'),
|
|
|
|
// tensor-type ::= `tensor` `<` dimension-list type (`,` encoding)? `>`
|
|
// dimension-list ::= (dimension `x`)*
|
|
// dimension ::= `?` | decimal-literal
|
|
// encoding ::= attribute-value
|
|
// tensor-type ::= `tensor` `<` `*` `x` type `>`
|
|
tensor_type : $ => seq(token('tensor'), '<', $.dim_list,
|
|
optional(seq(',', $.tensor_encoding)), '>'),
|
|
tensor_encoding : $ => $.attribute_value,
|
|
|
|
// vector-type ::= `vector` `<` vector-dim-list vector-element-type `>`
|
|
// vector-element-type ::= float-type | integer-type | index-type
|
|
// vector-dim-list := (static-dim-list `x`)? (`[` static-dim-list `]` `x`)?
|
|
// static-dim-list ::= decimal-literal (`x` decimal-literal)*
|
|
vector_type : $ =>
|
|
seq(token('vector'), '<', optional($.vector_dim_list), $._prim_type, '>'),
|
|
vector_dim_list : $ =>
|
|
choice(seq($._static_dim_list, 'x',
|
|
optional(seq('[', $._static_dim_list, ']', 'x'))),
|
|
seq('[', $._static_dim_list, ']', 'x')),
|
|
_static_dim_list : $ =>
|
|
seq(repeat1($._digit), repeat(seq('x', repeat1($._digit)))),
|
|
|
|
// tuple-type ::= `tuple` `<` (type ( `,` type)*)? `>`
|
|
tuple_type : $ =>
|
|
seq(token('tuple'), '<', $.tuple_dim, repeat(seq(',', $.tuple_dim)), '>'),
|
|
tuple_dim : $ => $._prim_type,
|
|
|
|
// Attributes
|
|
// attribute-entry ::= (bare-id | string-literal) `=` attribute-value
|
|
// attribute-value ::= attribute-alias | dialect-attribute |
|
|
// builtin-attribute
|
|
attribute_entry : $ => seq(choice($.bare_id, $.string_literal),
|
|
optional(seq('=', $.attribute_value))),
|
|
attribute_value : $ =>
|
|
choice(seq('[', optional($._attribute_value_nobracket),
|
|
repeat(seq(',', $._attribute_value_nobracket)), ']'),
|
|
$._attribute_value_nobracket),
|
|
_attribute_value_nobracket : $ =>
|
|
choice($.attribute_alias, $.dialect_attribute, $.builtin_attribute,
|
|
$.dictionary_attribute, $._literal_and_type, $.type),
|
|
attribute : $ => choice($.attribute_alias, $.dialect_attribute,
|
|
$.builtin_attribute, $.dictionary_attribute),
|
|
|
|
// Attribute Value Aliases
|
|
// attribute-alias-def ::= '#' alias-name '=' attribute-value
|
|
// attribute-alias ::= '#' alias-name
|
|
attribute_alias_def : $ =>
|
|
seq('#', $._alias_or_dialect_id, '=', $.attribute_value),
|
|
attribute_alias : $ => seq('#', $._alias_or_dialect_id),
|
|
|
|
// Dialect Attribute Values
|
|
dialect_attribute : $ =>
|
|
seq('#', choice($.opaque_dialect_item, $.pretty_dialect_item)),
|
|
|
|
// Builtin Attribute Values
|
|
builtin_attribute : $ => choice(
|
|
// TODO
|
|
$.strided_layout, $.affine_map, $.affine_set),
|
|
strided_layout : $ => seq(token('strided'), '<', '[', $._dim_list_comma, ']',
|
|
optional(seq(',', token('offset'), ':',
|
|
choice($.integer_literal, '?', '*'))),
|
|
'>'),
|
|
_dim_list_comma : $ =>
|
|
seq($._dim_primitive, repeat(seq(',', $._dim_primitive))),
|
|
|
|
affine_map : $ =>
|
|
seq(token('affine_map'), '<', $._multi_dim_affine_expr_parens,
|
|
optional($._multi_dim_affine_expr_sq), token('->'),
|
|
$._multi_dim_affine_expr_parens, '>'),
|
|
affine_set : $ =>
|
|
seq(token('affine_set'), '<', $._multi_dim_affine_expr_parens,
|
|
optional($._multi_dim_affine_expr_sq), ':',
|
|
$._multi_dim_affine_expr_parens, '>'),
|
|
_multi_dim_affine_expr_parens : $ =>
|
|
seq('(', optional($._multi_dim_affine_expr), ')'),
|
|
_multi_dim_affine_expr_sq : $ =>
|
|
seq('[', optional($._multi_dim_affine_expr), ']'),
|
|
|
|
// affine-expr ::= `(` affine-expr `)`
|
|
// | affine-expr `+` affine-expr
|
|
// | affine-expr `-` affine-expr
|
|
// | `-`? integer-literal `*` affine-expr
|
|
// | affine-expr `ceildiv` integer-literal
|
|
// | affine-expr `floordiv` integer-literal
|
|
// | affine-expr `mod` integer-literal
|
|
// | `-`affine-expr
|
|
// | bare-id
|
|
// | `-`? integer-literal
|
|
// multi-dim-affine-expr ::= `(` `)`
|
|
// | `(` affine-expr (`,` affine-expr)* `)`
|
|
|
|
// semi-affine-expr ::= `(` semi-affine-expr `)`
|
|
// | semi-affine-expr `+` semi-affine-expr
|
|
// | semi-affine-expr `-` semi-affine-expr
|
|
// | symbol-or-const `*` semi-affine-expr
|
|
// | semi-affine-expr `ceildiv` symbol-or-const
|
|
// | semi-affine-expr `floordiv` symbol-or-const
|
|
// | semi-affine-expr `mod` symbol-or-const
|
|
// | bare-id
|
|
// | `-`? integer-literal
|
|
// symbol-or-const ::= `-`? integer-literal | symbol-id
|
|
// multi-dim-semi-affine-expr ::= `(` semi-affine-expr (`,` semi-affine-expr)*
|
|
// `)`
|
|
|
|
// affine-constraint ::= affine-expr `>=` `affine-expr`
|
|
// | affine-expr `<=` `affine-expr`
|
|
// | affine-expr `==` `affine-expr`
|
|
// affine-constraint-conjunction ::= affine-constraint (`,`
|
|
// affine-constraint)*
|
|
|
|
_multi_dim_affine_expr : $ =>
|
|
seq($._affine_expr, repeat(seq(',', $._affine_expr))),
|
|
_affine_expr : $ => prec.right(choice(
|
|
seq('(', $._affine_expr, ')'), seq('-', $._affine_expr),
|
|
seq($._affine_expr, $._affine_token, $._affine_expr), $._affine_prim)),
|
|
_affine_prim : $ =>
|
|
choice($.integer_literal, $.value_use, $.bare_id,
|
|
seq('symbol', '(', $.value_use, ')'),
|
|
seq(choice('max', 'min'), '(', $._value_use_list, ')')),
|
|
_affine_token : $ => token(
|
|
choice('+', '-', '*', 'ceildiv', 'floordiv', 'mod', '==', '>=', '<=')),
|
|
|
|
func_return : $ => seq(token('->'), $.type_list_attr_parens),
|
|
func_arg_list : $ => seq(
|
|
'(', optional(choice($.variadic, $._value_id_and_type_attr_list)), ')'),
|
|
_value_id_and_type_attr_list : $ => seq(
|
|
$._value_id_and_type_attr, repeat(seq(',', $._value_id_and_type_attr)),
|
|
optional(seq(',', $.variadic))),
|
|
_value_id_and_type_attr : $ => seq($._function_arg, optional($.attribute)),
|
|
_function_arg : $ =>
|
|
choice(seq($.value_use, ':', $.type), $.value_use, $.type),
|
|
type_list_attr_parens : $ =>
|
|
choice($.type,
|
|
seq('(', $.type, optional($.attribute),
|
|
repeat(seq(',', $.type, optional($.attribute))), ')'),
|
|
seq('(', ')')),
|
|
variadic : $ => token('...'),
|
|
|
|
// (func.func|llvm.func) takes arguments, an optional return type, and and
|
|
// optional body
|
|
_op_func : $ =>
|
|
seq(field('visibility', optional('private')),
|
|
field('name', $.symbol_ref_id), field('arguments', $.func_arg_list),
|
|
field('return', optional($.func_return)),
|
|
field('attributes', optional(seq(token('attributes'), $.attribute))),
|
|
field('body', optional($.region))),
|
|
|
|
// dim-use-list ::= `(` ssa-use-list? `)`
|
|
// symbol-use-list ::= `[` ssa-use-list? `]`
|
|
// dim-and-symbol-use-list ::= dim-use-list symbol-use-list?
|
|
_value_use_list_parens : $ => seq('(', optional($._value_use_list), ')'),
|
|
_dim_and_symbol_use_list : $ =>
|
|
seq($._value_use_list_parens, optional($._dense_idx_list)),
|
|
|
|
// assignment-list ::= assignment | assignment `,` assignment-list
|
|
// assignment ::= ssa-value `=` ssa-value
|
|
_value_assignment_list : $ => seq('(', optional($._value_assignment),
|
|
repeat(seq(',', $._value_assignment)), ')'),
|
|
_value_assignment : $ => seq($.value_use, '=', $.value_use),
|
|
|
|
_dense_idx_list : $ => seq(
|
|
'[',
|
|
optional(seq(choice($.integer_literal, $.value_use),
|
|
repeat(seq(',', choice($.integer_literal, $.value_use))))),
|
|
']'),
|
|
|
|
// lower-bound ::= `max`? affine-map-attribute dim-and-symbol-use-list |
|
|
// shorthand-bound
|
|
// upper-bound ::= `min`? affine-map-attribute dim-and-symbol-use-list |
|
|
// shorthand-bound
|
|
// shorthand-bound ::= ssa-id | `-`? integer-literal
|
|
_bound : $ =>
|
|
choice(seq($.attribute, $._dim_and_symbol_use_list), $._shorthand_bound),
|
|
_shorthand_bound : $ => choice($.value_use, $.integer_literal),
|
|
|
|
// Dialect-specific attributes
|
|
restrict_attr : $ => token('restrict'),
|
|
writable_attr : $ => token('writable'),
|
|
gather_dims_attr : $ =>
|
|
seq(token('gather_dims'), '(', $._dense_idx_list, ')'),
|
|
scatter_dims_attr : $ =>
|
|
seq(token('scatter_dims'), '(', $._dense_idx_list, ')'),
|
|
unique_attr : $ => token('unique'),
|
|
nofold_attr : $ => token('nofold'),
|
|
outer_dims_perm_attr : $ =>
|
|
seq(token('outer_dims_perm'), '=', $._dense_idx_list),
|
|
inner_dims_pos_attr : $ =>
|
|
seq(token('inner_dims_pos'), '=', $._dense_idx_list),
|
|
inner_tiles_attr : $ => seq(token('inner_tiles'), '=', $._dense_idx_list),
|
|
isWrite_attr : $ => token(choice('read', 'write')),
|
|
localityHint_attr : $ => seq(token('locality'), '<', $.integer_literal, '>'),
|
|
isDataCache_attr : $ => token(choice('data', 'instr')),
|
|
fastmath_attr : $ =>
|
|
seq(token('fastmath'), '<',
|
|
seq($._fastmath_flag, repeat(seq(',', $._fastmath_flag))), '>'),
|
|
_fastmath_flag : $ => token(choice('none', 'reassoc', 'nnan', 'ninf', 'nsz',
|
|
'arcp', 'contract', 'afn', 'fast')),
|
|
|
|
// Comment (standard BCPL)
|
|
comment : $ => token(seq('//', /.*/)),
|
|
|
|
// TODO: complete
|
|
custom_operation : $ =>
|
|
choice($.builtin_dialect, $.func_dialect, $.llvm_dialect, $.arith_dialect,
|
|
$.math_dialect, $.cf_dialect, $.scf_dialect, $.memref_dialect,
|
|
$.vector_dialect, $.tensor_dialect, $.bufferization_dialect,
|
|
$.affine_dialect, $.linalg_dialect)
|
|
}
|
|
|
|
module.exports = grammar({
|
|
name : 'mlir',
|
|
extras : $ => [/\s/, $.comment],
|
|
conflicts : $ => [[ $._static_dim_list, $._static_dim_list ],
|
|
[ $.dictionary_attribute, $.region ]],
|
|
rules : Object.assign(common, builtin_dialect, func_dialect, llvm_dialect,
|
|
arith_dialect, math_dialect, cf_dialect, scf_dialect,
|
|
memref_dialect, vector_dialect, tensor_dialect,
|
|
bufferization_dialect, affine_dialect, linalg_dialect)
|
|
});
|