export default grammar({
name: 'modulemap',
extras: $ => [
/\s/,
$.comment,
],
word: $ => $.identifier,
rules: {
source_file: $ => repeat($._module_declaration),
_module_declaration: $ => choice(
$.module_declaration,
$.extern_module_declaration
),
module_declaration: $ => seq(
optional('explicit'),
optional('framework'),
'module',
field('name', $.module_id), field('attributes', optional($.attributes)),
field('body', $.module_body)
),
extern_module_declaration: $ => seq(
'extern',
'module',
field('name', $.module_id),
field('path', $.string_literal)
),
module_body: $ => seq(
'{',
repeat($.module_member),
'}'
),
module_member: $ => choice(
$.requires_declaration,
$.header_declaration,
$.umbrella_dir_declaration,
$.submodule_declaration,
$.export_declaration,
$.export_as_declaration,
$.use_declaration,
$.link_declaration,
$.config_macros_declaration,
$.conflict_declaration
),
requires_declaration: $ => seq(
'requires',
$.feature_list
),
feature_list: $ => seq(
$.feature,
repeat(seq(',', $.feature))
),
feature: $ => seq(
optional('!'),
$.identifier
),
header_declaration: $ => seq(
choice(
seq(optional('private'), optional('textual')),
'umbrella',
'exclude'
),
'header',
field('path', $.string_literal),
optional($.header_attributes)
),
header_attributes: $ => seq(
'{',
repeat($.header_attribute),
'}'
),
header_attribute: $ => seq(
choice('size', 'mtime'),
$.integer_literal
),
umbrella_dir_declaration: $ => seq(
'umbrella',
field('path', $.string_literal)
),
submodule_declaration: $ => choice(
$._module_declaration,
$.inferred_submodule_declaration,
),
inferred_submodule_declaration: $ => seq(
optional('explicit'),
optional('framework'),
'module',
'*',
optional($.attributes),
'{',
repeat($.inferred_submodule_member),
'}'
),
inferred_submodule_member: $ => seq(
'export',
'*'
),
export_declaration: $ => seq(
'export',
$.wildcard_module_id
),
export_as_declaration: $ => seq(
'export_as',
$.identifier
),
use_declaration: $ => seq(
'use',
$.module_id
),
link_declaration: $ => seq(
'link',
optional('framework'),
field('library', $.string_literal)
),
config_macros_declaration: $ => seq(
'config_macros',
optional($.attributes),
optional($.config_macro_list)
),
config_macro_list: $ => seq(
$.identifier,
repeat(seq(',', $.identifier))
),
conflict_declaration: $ => seq(
'conflict',
field('module', $.module_id),
',',
field('message', $.string_literal)
),
attributes: $ => repeat1($.attribute),
attribute: $ => seq(
'[',
$.identifier,
']'
),
module_id: $ => seq(
$.identifier,
repeat(seq('.', $.identifier))
),
wildcard_module_id: $ => choice(
$.identifier,
'*',
seq(identifier, '.', wildcard_module_id)),
wildcard_module_id: $ => seq(
choice($.identifier, '*'),
repeat(seq('.', choice($.identifier, '*')))
),
identifier: $ => /[a-zA-Z_]\w*/,
string_literal: $ => /"[^"\n]*"/,
integer_literal: $ => /\d+/,
comment: $ => token(choice(
seq('//', /.*/),
seq(
'/*',
/[^*]*\*+([^/*][^*]*\*+)*/,
'/'
)
)),
}
});