/// // @ts-check export default grammar({ name: 'fsm', rules: { source_file: $ => repeat($.statement), _type: $ => seq( '<', field('type', $.expression_type), '>' ), expression: $ => choice( $.symbol_expression, $.prop_expression, $.pointer_expression, $.or_expression, $.reflect_expression, $.string_expression ), expression_type: $ => choice( 'Expression', $.pointer_expression_type, $.symbol_expression_type, $.string_expression_type, $.or_expression_type, $.reflect_expression_type ), string_expression: $ => prec(-10, /[a-zA-Z0-9]+/), string_expression_type: $ => 'String', symbol_expression: $ => prec(10, seq( ':', field('expression', $.expression) )), symbol_expression_type: $ => 'Symbol', prop_expression: $ => seq( '[', field('expression', $.expression), ']' ), pointer_expression: $ => prec(10, choice( $.action_pointer_expression, $.prop_pointer_expression )), pointer_expression_type: $ => choice( 'Pointer', $.action_pointer_expression_type, $.prop_pointer_expression_type ), prop_pointer_expression: $ => seq( '[[', field('expression', $.expression), ']]' ), prop_pointer_expression_type: $ => 'PropPointer', action_pointer_expression: $ => prec(10, seq( '*', field('expression', $.expression) )), action_pointer_expression_type: $ => 'ActionPointer', reflect_expression: $ => prec(20, seq( '(', field('expression', $.expression), ')' )), reflect_expression_type: $ => 'ReflectExpression', or_expression: $ => prec.left(5, seq( field('prefer', $.expression), '?', field('fallback', $.expression) )), or_expression_type: $ => 'OrExpression', statement: $ => choice( $.route_statement, $.on_statement, $.block_statement, $.move_statement, $.actions_statement, $.action_statement, $.prop_statement, $.optional_prop_statement, $.await_statement, $.reflect_statement, $.or_assign_statement ), route_statement: $ => seq( 'route', field('name', $.expression), field('procedure', $.statement) ), or_assign_statement: $ => prec.left(5, seq( field('operand', $.expression), '?=', field('default', $.expression) )), on_statement: $ => seq( 'on', field('state', $.expression), field('procedure', $.statement) ), block_statement: $ => seq( 'do', field('procedure', repeat($.statement)), 'end' ), actions_statement: $ => prec.right(seq( 'actions', field('expressions', repeat($.expression)) )), action_statement: $ => seq( '*', field('expression', $.expression) ), prop_statement: $ => seq( 'prop', field('name', $.expression), field('type', $._type) ), optional_prop_statement: $ => seq( 'prop?', field('name', $.expression), field('type', $._type) ), move_statement: $ => seq( '=>', field('to', $.expression) ), await_statement: $ => seq( 'await', field('action', $.expression), field('resolved', $.statement), '!', field('rejected', $.statement), ), reflect_statement: $ => seq( '(', field('statement', $.statement), ')' ) } });