comby
comby copied to clipboard
JSX support
(Comby is awesome! Thank you!) I would like to be able to use Comby to match in JSX files (that is, JavaScript or TypeScript files with React-style <Tag>
s).
On the following sample .jsx
or .tsx
file (to demonstrate the syntax):
const a = () => <>
<Route path="/a" component={A}/>
<Route path="/b" render={() => 'b'}/>
</>
With Comby 0.17.0, the :[1]
hole is greedier than I'd like; it matches from the 1st <Route
to the 2nd Route
component's self-closing tag />
:
$ comby -color -match-only '<Route :[1] render={:[2]}/>' '' ~/comby-test.tsx
/Users/sqs/Downloads/comby-test.tsx:2:<Route path="/a" component={A}/>\n <Route path="/b" render={() => 'b'}/>
I would like JSX support that would result in only <Route path="/b" render={() => 'b'}/>
being matched.
Nice, yeah, the use case is clear here. From a parsing perspective, there is a breakdown of two concerns. The first is:
- matching balanced
<
>
or<Thing
/>
tags. In general, this level of parsing is fairly easy to support (context free) and comby already has the general capability. The reason it doesn't work out of box for JSX is in the next bullet. But on this bullet, in some languages, like XML, HTML, you can have labeled tags, like<p>
followed by</p>
(context sensitive). This difference is significant from a parsing perspective, since parsing needs to keep track of the labels, which can be arbitrary--in the interest of supporting JSX fully, does that syntax make occasional or heavy use of labeled tags as well?
The second is:
- disambiguating uses of the characters
<
and>
. The reason comby by default can't treat<
>
as balanced tags for JSX (in contrast, comby does by default treat HTML/XML tags as balanced) is because JSX files use>
and<
as comparison operators in expressionsa < b
and has no easy way to disambiguate. Typically, context information in a grammar/parsing disambiguates when a<
is associated with, say, an arithmetic expression, versus a component here. So to make parsing more precise for the JSX support here, my idea will be to implement a parsing that recognizes, for example, the pattern<whitespace><\w+<whitespace>
as a starting pattern for a balanced<
(versus those of arithmetic expressions). This likely is enough for JSX-purposes.
So that's the context. The solution is workable, just a matter of time/effort in the right places :-)