grammar.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. /*
  2. * Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  3. * Exceptions. See /LICENSE for license information.
  4. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  5. */
  6. // This grammar is more permissive than toolchain because it is geared towards
  7. // editor use.
  8. function repeat_sep1(thing, sep) {
  9. return seq(thing, repeat(seq(sep, thing)));
  10. }
  11. function comma_sep(thing) {
  12. // Trailing comma is only allowed if there is at least one element.
  13. return optional(seq(repeat_sep1(thing, ','), optional(',')));
  14. }
  15. // This is based on toolchain/parser/precedence.cpp
  16. const PREC = {
  17. TermPrefix: 12,
  18. TermPostfix: 12,
  19. NumericPrefix: 11,
  20. NumericPostfix: 11,
  21. Multiplicative: 10,
  22. Additive: 9,
  23. BitwisePrefix: 8,
  24. BitwiseAnd: 7,
  25. BitwiseOr: 7,
  26. BitwiseXor: 7,
  27. BitShift: 7,
  28. TypePostfix: 6,
  29. LogicalPrefix: 5,
  30. Relational: 4,
  31. LogicalAnd: 3,
  32. LogicalOr: 3,
  33. IfExpression: 2,
  34. WhereClause: 1,
  35. };
  36. module.exports = grammar({
  37. name: 'carbon',
  38. word: ($) => $.ident,
  39. conflicts: ($) => [
  40. [$.paren_pattern, $.paren_expression],
  41. [$.struct_literal, $.struct_type_literal],
  42. ],
  43. extras: ($) => [/\s/, $.comment],
  44. // NOTE: This must match the order in src/scanner.c, names are not used for matching.
  45. externals: ($) => [$.binary_star, $.postfix_star, $.string],
  46. rules: {
  47. source_file: ($) =>
  48. seq(
  49. optional($.package_directive),
  50. repeat($.import_directive),
  51. repeat($.declaration)
  52. ),
  53. api_or_impl: ($) => choice('api', 'impl'),
  54. library_path: ($) => seq('library', $.string),
  55. package_directive: ($) =>
  56. seq('package', $.ident, optional($.library_path), $.api_or_impl, ';'),
  57. import_directive: ($) =>
  58. seq('import', $.ident, optional($.library_path), ';'),
  59. comment: ($) => token(seq('//', /.*/)),
  60. // NOTE: this must be before ident rule to increase its priority.
  61. // https://github.com/carbon-language/carbon-lang/blob/trunk/proposals/p2015.md#syntax
  62. numeric_type_literal: ($) => /[iuf][1-9][0-9]*/,
  63. ident: ($) => /[A-Za-z_][A-Za-z0-9_]*/,
  64. bool_literal: ($) => choice('true', 'false'),
  65. numeric_literal: ($) => {
  66. // This is using variables because rules are not allowed in
  67. // token.immediate and token.
  68. // https://github.com/tree-sitter/tree-sitter/issues/449
  69. const decimal_integer_literal = choice('0', /[1-9](_?[0-9])*/);
  70. const hex_digits = /[0-9A-F](_?[0-9A-F])*/;
  71. const binary_integer_literal = /0b[01](_?[01])*/;
  72. const hex_integer_literal = seq('0x', token.immediate(hex_digits));
  73. const decimal_real_number_literal = seq(
  74. decimal_integer_literal,
  75. token.immediate(/\.[0-9](_?[0-9])*/),
  76. optional(
  77. seq(
  78. token.immediate(/e[+-]?/),
  79. token.immediate(decimal_integer_literal)
  80. )
  81. )
  82. );
  83. const hex_real_number_literal = seq(
  84. hex_integer_literal,
  85. token.immediate('.'),
  86. token.immediate(hex_digits),
  87. optional(
  88. seq(
  89. token.immediate(/p[+-]?/),
  90. token.immediate(decimal_integer_literal)
  91. )
  92. )
  93. );
  94. return token(
  95. choice(
  96. decimal_integer_literal,
  97. binary_integer_literal,
  98. hex_integer_literal,
  99. decimal_real_number_literal,
  100. hex_real_number_literal
  101. )
  102. );
  103. },
  104. array_literal: ($) =>
  105. seq(
  106. '[',
  107. field('type', $._expression),
  108. ';',
  109. optional(field('size', $._expression)),
  110. ']'
  111. ),
  112. struct_literal: ($) =>
  113. seq('{', comma_sep(seq($.designator, '=', $._expression)), '}'),
  114. struct_type_literal: ($) =>
  115. seq('{', comma_sep(seq($.designator, ':', $._expression)), '}'),
  116. builtin_type: ($) => choice('Self', 'String', 'bool', 'type'),
  117. literal: ($) =>
  118. choice(
  119. $.bool_literal,
  120. $.numeric_literal,
  121. $.numeric_type_literal,
  122. $.string,
  123. $.struct_literal,
  124. $.struct_type_literal
  125. ),
  126. binding_lhs: ($) => choice($.ident, '_'),
  127. paren_pattern: ($) =>
  128. seq(
  129. '(',
  130. comma_sep(choice($._pattern_without_expression, $._expression)),
  131. ')'
  132. ),
  133. _pattern_without_expression: ($) =>
  134. choice(
  135. 'auto',
  136. seq($.binding_lhs, ':', $._expression),
  137. seq($.binding_lhs, ':!', $._expression),
  138. seq('template', $.binding_lhs, ':!', $._expression),
  139. seq('var', $._pattern),
  140. $.paren_pattern,
  141. // alternative patterns
  142. // example: Optional(i32).Some(x: i32)
  143. seq($._simple_expression, $.paren_pattern)
  144. ),
  145. _pattern: ($) =>
  146. choice($._pattern_without_expression, $._simple_expression),
  147. unary_prefix_expression: ($) => {
  148. const table = [
  149. [PREC.NumericPrefix, '-'],
  150. [PREC.NumericPrefix, '--'],
  151. [PREC.NumericPrefix, '++'],
  152. [PREC.BitwisePrefix, '^'],
  153. [PREC.LogicalPrefix, 'not'],
  154. ];
  155. return choice(
  156. ...table.map(([precedence, operator]) =>
  157. prec(
  158. precedence,
  159. seq(field('operator', operator), field('value', $._expression))
  160. )
  161. )
  162. );
  163. },
  164. binary_expression: ($) => {
  165. const table = [
  166. [PREC.LogicalAnd, 'and'],
  167. [PREC.LogicalOr, 'or'],
  168. [PREC.BitwiseAnd, '&'],
  169. [PREC.BitwiseOr, '|'],
  170. [PREC.BitwiseXor, '^'],
  171. [PREC.BitShift, choice('<<', '>>')],
  172. [PREC.Relational, choice('==', '!=', '<', '<=', '>', '>=')],
  173. [PREC.Additive, choice('+', '-')],
  174. [PREC.Multiplicative, choice($.binary_star, '/', '%')],
  175. ];
  176. return choice(
  177. ...table.map(([precedence, operator]) =>
  178. prec.left(
  179. precedence,
  180. seq(
  181. field('left', $._expression),
  182. field('operator', operator),
  183. field('right', $._expression)
  184. )
  185. )
  186. )
  187. );
  188. },
  189. // This should be non-associative but conflicts are not allowed in tree-sitter
  190. as_expression: ($) => prec.left(seq($._expression, 'as', $._expression)),
  191. ref_expression: ($) =>
  192. prec.right(PREC.TermPrefix, seq('&', $._simple_expression)),
  193. deref_expression: ($) =>
  194. prec.right(PREC.TermPrefix, seq('*', $._simple_expression)),
  195. fn_type_expression: ($) =>
  196. prec.left(seq('__Fn', $.paren_expression, '->', $._simple_expression)),
  197. if_expression: ($) =>
  198. prec(
  199. PREC.IfExpression,
  200. seq('if', $._expression, 'then', $._expression, 'else', $._expression)
  201. ),
  202. paren_expression: ($) => seq('(', comma_sep($._expression), ')'),
  203. index_expression: ($) =>
  204. prec(
  205. PREC.TermPostfix,
  206. seq($._simple_expression, '[', $._expression, ']')
  207. ),
  208. designator: ($) => seq('.', choice('base', $.ident)),
  209. postfix_expression: ($) =>
  210. prec(
  211. PREC.TermPostfix,
  212. seq(
  213. $._simple_expression,
  214. choice(
  215. '++',
  216. '--',
  217. $.designator,
  218. seq('->', $.ident),
  219. seq(choice('.', '->'), '(', $._expression, ')')
  220. )
  221. )
  222. ),
  223. where_clause: ($) =>
  224. choice(
  225. seq($._simple_expression, '==', $._simple_expression),
  226. seq($._simple_expression, 'impls', $._simple_expression),
  227. seq($._simple_expression, '=', $._simple_expression),
  228. prec.left(
  229. PREC.WhereClause + 1,
  230. seq($.where_clause, 'and', $.where_clause)
  231. )
  232. ),
  233. where_expression: ($) =>
  234. prec.left(PREC.WhereClause, seq($._expression, 'where', $.where_clause)),
  235. call_expression: ($) =>
  236. prec(PREC.TermPostfix, seq($._simple_expression, $.paren_expression)),
  237. pointer_expression: ($) =>
  238. prec(PREC.TypePostfix, seq($._simple_expression, $.postfix_star)),
  239. _simple_expression: ($) =>
  240. choice(
  241. $.array_literal,
  242. $.builtin_type,
  243. $.call_expression,
  244. $.deref_expression,
  245. $.fn_type_expression,
  246. $.ident,
  247. $.index_expression,
  248. $.literal,
  249. $.paren_expression,
  250. $.pointer_expression,
  251. $.postfix_expression,
  252. $.ref_expression,
  253. 'self',
  254. '.Self',
  255. $.designator
  256. ),
  257. _expression: ($) =>
  258. choice(
  259. $.as_expression,
  260. $.binary_expression,
  261. $.if_expression,
  262. $.unary_prefix_expression,
  263. $.where_expression,
  264. $._simple_expression
  265. ),
  266. var_declaration: ($) =>
  267. seq(
  268. 'var',
  269. $._pattern_without_expression,
  270. optional(seq('=', $._expression)),
  271. ';'
  272. ),
  273. let_declaration: ($) =>
  274. seq('let', $._pattern_without_expression, '=', $._expression, ';'),
  275. assign_statement: ($) =>
  276. seq($._expression, $._assign_operator, $._expression, ';'),
  277. _assign_operator: ($) =>
  278. choice('=', '+=', '/=', '*=', '%=', '-=', '&=', '|=', '^=', '<<=', '>>='),
  279. match_clause: ($) =>
  280. seq(choice(seq('case', $._pattern), 'default'), '=>', $.block),
  281. match_statement: ($) =>
  282. seq('match', '(', $._expression, ')', '{', repeat($.match_clause), '}'),
  283. returned_var_statement: ($) => seq('returned', $.var_declaration),
  284. while_statement: ($) => seq('while', '(', $._expression, ')', $.block),
  285. break_statement: ($) => seq('break', ';'),
  286. continue_statement: ($) => seq('continue', ';'),
  287. return_statement: ($) =>
  288. seq('return', optional(choice('var', $._expression)), ';'),
  289. if_statement: ($) =>
  290. seq('if', '(', $._expression, ')', $.block, optional($.else)),
  291. else: ($) => choice(seq('else', $.if_statement), seq('else', $.block)),
  292. for_statement: ($) =>
  293. seq('for', '(', $._pattern, 'in', $._expression, ')', $.block),
  294. statement: ($) =>
  295. choice(
  296. seq($._expression, ';'),
  297. $.assign_statement,
  298. $.var_declaration,
  299. $.let_declaration,
  300. $.match_statement,
  301. $.returned_var_statement,
  302. $.if_statement,
  303. $.while_statement,
  304. $.break_statement,
  305. $.continue_statement,
  306. $.return_statement,
  307. $.for_statement
  308. ),
  309. block: ($) => seq('{', repeat($.statement), '}'),
  310. declared_name: ($) => repeat_sep1($.ident, '.'),
  311. generic_binding: ($) =>
  312. seq(optional('template'), $.ident, ':!', $._expression),
  313. deduced_param: ($) =>
  314. choice(
  315. $.generic_binding,
  316. seq(optional('addr'), 'self', ':', $._expression)
  317. ),
  318. deduced_params: ($) => seq('[', comma_sep($.deduced_param), ']'),
  319. return_type: ($) => seq('->', choice('auto', $._expression)),
  320. function_declaration: ($) =>
  321. seq(
  322. optional(choice('abstract', 'virtual', 'impl')),
  323. 'fn',
  324. $.declared_name,
  325. optional($.deduced_params),
  326. $.paren_pattern,
  327. optional($.return_type),
  328. choice($.block, ';')
  329. ),
  330. namespace_declaration: ($) => seq('namespace', $.declared_name, ';'),
  331. alias_declaration: ($) =>
  332. seq('alias', $.declared_name, '=', $._expression, ';'),
  333. type_params: ($) => $.paren_pattern,
  334. interface_body_item: ($) =>
  335. choice(
  336. $.function_declaration,
  337. seq('let', $.generic_binding, ';'),
  338. seq('extend', $._expression, ';'),
  339. seq('require', $._expression, 'impls', $._expression, ';')
  340. ),
  341. interface_body: ($) => seq('{', repeat($.interface_body_item), '}'),
  342. interface_declaration: ($) =>
  343. seq(
  344. 'interface',
  345. $.declared_name,
  346. optional($.deduced_params),
  347. optional($.type_params),
  348. choice(';', $.interface_body)
  349. ),
  350. constraint_declaration: ($) =>
  351. seq(
  352. 'constraint',
  353. $.declared_name,
  354. optional($.deduced_params),
  355. optional($.type_params),
  356. choice(';', $.interface_body)
  357. ),
  358. impl_body_item: ($) => choice($.function_declaration, $.alias_declaration),
  359. impl_body: ($) => seq('{', repeat($.impl_body_item), '}'),
  360. impl_declaration: ($) =>
  361. seq(
  362. 'impl',
  363. optional(seq('forall', $.deduced_params)),
  364. optional($._expression),
  365. 'as',
  366. $._expression,
  367. $.impl_body
  368. ),
  369. extend_impl_declaration: ($) =>
  370. seq('extend', 'impl', 'as', $._expression, $.impl_body),
  371. extend_base_declaration: ($) =>
  372. seq('extend', 'base', ':', $._expression, ';'),
  373. destructor_declaration: ($) =>
  374. seq(
  375. optional(choice('virtual', 'impl')),
  376. 'destructor',
  377. optional($.deduced_params),
  378. choice($.block, ';')
  379. ),
  380. class_body_item: ($) =>
  381. choice(
  382. $.declaration,
  383. $.extend_base_declaration,
  384. $.extend_impl_declaration,
  385. $.mix_declaration,
  386. $.destructor_declaration
  387. ),
  388. class_body: ($) => seq('{', repeat($.class_body_item), '}'),
  389. class_declaration: ($) =>
  390. seq(
  391. optional(choice('base', 'abstract')),
  392. 'class',
  393. $.declared_name,
  394. optional($.deduced_params),
  395. optional($.type_params),
  396. choice(';', $.class_body)
  397. ),
  398. choice_declaration: ($) =>
  399. seq(
  400. 'choice',
  401. $.declared_name,
  402. optional($.type_params),
  403. '{',
  404. comma_sep(seq($.ident, optional($.paren_expression))),
  405. '}'
  406. ),
  407. empty_declaration: ($) => ';',
  408. declaration: ($) =>
  409. choice(
  410. $.empty_declaration,
  411. $.namespace_declaration,
  412. $.var_declaration,
  413. $.let_declaration,
  414. $.function_declaration,
  415. $.alias_declaration,
  416. $.interface_declaration,
  417. $.constraint_declaration,
  418. $.impl_declaration,
  419. $.class_declaration,
  420. $.choice_declaration,
  421. $.mixin_declaration,
  422. $.match_first_declaration
  423. ),
  424. // Explorer only experimental featurues
  425. mix_declaration: ($) => seq('__mix', $._expression, ';'),
  426. mixin_declaration: ($) =>
  427. seq(
  428. '__mixin',
  429. $.declared_name,
  430. optional($.type_params),
  431. optional(seq('for', $._expression)),
  432. '{',
  433. repeat(choice($.function_declaration, $.mix_declaration)),
  434. '}'
  435. ),
  436. match_first_declaration: ($) =>
  437. seq('__match_first', '{', repeat($.impl_declaration), '}'),
  438. },
  439. });