From 8ab351ba327638a869d6704ffd8be27e7ded3797 Mon Sep 17 00:00:00 2001 From: Amaan Qureshi Date: Fri, 10 Jan 2025 22:00:07 -0500 Subject: [PATCH] docs: add example usage of conflicts --- .../creating-parsers/3-writing-the-grammar.md | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/docs/src/creating-parsers/3-writing-the-grammar.md b/docs/src/creating-parsers/3-writing-the-grammar.md index a42c99a4..26d66c8f 100644 --- a/docs/src/creating-parsers/3-writing-the-grammar.md +++ b/docs/src/creating-parsers/3-writing-the-grammar.md @@ -291,6 +291,69 @@ This is where `prec.left` and `prec.right` come into use. We want to select the } ``` +## Using Conflicts + +Sometimes, conflicts are actually desirable. In our JavaScript grammar, expressions and patterns can create intentional ambiguity. +A construct like `[x, y]` could be legitimately parsed as both an array literal (like in `let a = [x, y]`) or as a destructuring +pattern (like in `let [x, y] = arr`). + +```js +module.exports = grammar({ + name: "javascript", + + rules: { + expression: $ => choice( + $.identifier, + $.array, + $.pattern, + ), + + array: $ => seq( + "[", + optional(seq( + $.expression, repeat(seq(",", $.expression)) + )), + "]" + ), + + array_pattern: $ => seq( + "[", + optional(seq( + $.pattern, repeat(seq(",", $.pattern)) + )), + "]" + ), + + pattern: $ => choice( + $.identifier, + $.array_pattern, + ), + }, +}) +``` + +In such cases, we want the parser to explore both possibilities by explicitly declaring this ambiguity: + +```js +{ + name: "javascript", + + conflicts: $ => [ + [$.array, $.array_pattern], + ], + + rules: { + // ... + }, +} +``` + +```admonish note +The example is a bit contrived for the purpose of illustrating the usage of conflicts. The actual JavaScript grammar isn't +structured like that, but this conflict is actually present in the +[Tree-sitter JavaScript grammar](https://github.com/tree-sitter/tree-sitter-javascript/blob/108b2d4d17a04356a340aea809e4dd5b801eb40d/grammar.js#L100). +``` + ## Hiding Rules You may have noticed in the above examples that some grammar rule name like `_expression` and `_type` began with an underscore.