Mirror: The magical sticky regex-based parser generator 🧙
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Update export and README

+20 -19
+19 -16
README.md
··· 10 10 <br /> 11 11 </div> 12 12 13 - Leveraging the power of sticky regexes and Babel code generation, `reghex` allows 13 + Leveraging the power of sticky regexes and JS code generation, `reghex` allows 14 14 you to code parsers quickly, by surrounding regular expressions with a regex-like 15 15 [DSL](https://en.wikipedia.org/wiki/Domain-specific_language). 16 16 ··· 30 30 npm install --save reghex 31 31 ``` 32 32 33 - ##### 2. Add the plugin to your Babel configuration (`.babelrc`, `babel.config.js`, or `package.json:babel`) 33 + ##### 2. Add the plugin to your Babel configuration _(optional)_ 34 + 35 + In your `.babelrc`, `babel.config.js`, or `package.json:babel` add: 34 36 35 37 ```json 36 38 { ··· 41 43 Alternatively, you can set up [`babel-plugin-macros`](https://github.com/kentcdodds/babel-plugin-macros) and 42 44 import `reghex` from `"reghex/macro"` instead. 43 45 46 + This step is **optional**. `reghex` can also generate its optimised JS code during runtime only! 47 + 44 48 ##### 3. Have fun writing parsers! 45 49 46 50 ```js 47 - import match, { parse } from 'reghex'; 51 + import { match, parse } from 'reghex'; 48 52 49 53 const name = match('name')` 50 54 ${/\w+/} ··· 99 103 100 104 ## Authoring Guide 101 105 102 - You can write "matchers" by importing the default import from `reghex` and 106 + You can write "matchers" by importing the `match` import from `reghex` and 103 107 using it to write a matcher expression. 104 108 105 109 ```js 106 - import match from 'reghex'; 110 + import { match } from 'reghex'; 107 111 108 112 const name = match('name')` 109 113 ${/\w+/} 110 114 `; 111 115 ``` 112 116 113 - As can be seen above, the `match` function, which is what we've called the 114 - default import, is called with a "node name" and is then called as a tagged 115 - template. This template is our **parsing definition**. 117 + As can be seen above, the `match` function, is called with a "node name" and 118 + is then called as a tagged template. This template is our **parsing definition**. 116 119 117 120 `reghex` functions only with its Babel plugin, which will detect `match('name')` 118 121 and replace the entire tag with a parsing function, which may then look like ··· 208 211 in the parsed string. This is just one feature of the regex-like DSL. The 209 212 available operators are the following: 210 213 211 - | Operator | Example | Description | 212 - | -------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 213 - | `?` | `${/1/}?` | An **optional** may be used to make an interpolation optional. This means that the interpolation may or may not match. | 214 - | `*` | `${/1/}*` | A **star** can be used to match an arbitrary amount of interpolation or none at all. This means that the interpolation may repeat itself or may not be matched at all. | 215 - | `+` | `${/1/}+` | A **plus** is used like `*` and must match one or more times. When the matcher doesn't match, that's considered a failing case, since the match isn't optional. | 216 - | `\|` | `${/1/} \| ${/2/}` | An **alternation** can be used to match either one thing or another, falling back when the first interpolation fails. | 217 - | `()` | `(${/1/} ${/2/})+` | A **group** can be used to apply one of the other operators to an entire group of interpolations. | 214 + | Operator | Example | Description | 215 + | -------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 216 + | `?` | `${/1/}?` | An **optional** may be used to make an interpolation optional. This means that the interpolation may or may not match. | 217 + | `*` | `${/1/}*` | A **star** can be used to match an arbitrary amount of interpolation or none at all. This means that the interpolation may repeat itself or may not be matched at all. | 218 + | `+` | `${/1/}+` | A **plus** is used like `*` and must match one or more times. When the matcher doesn't match, that's considered a failing case, since the match isn't optional. | 219 + | `\|` | `${/1/} \| ${/2/}` | An **alternation** can be used to match either one thing or another, falling back when the first interpolation fails. | 220 + | `()` | `(${/1/} ${/2/})+` | A **group** can be used to apply one of the other operators to an entire group of interpolations. | 218 221 | `(?: )` | `(?: ${/1/})` | A **non-capturing group** is like a regular group, but the interpolations matched inside it don't appear in the parser's output. | 219 - | `(?= )` | `(?= ${/1/})` | A **positive lookahead** checks whether interpolations match, and if so continues the matcher without changing the input. If it matches, it's essentially ignored. | 222 + | `(?= )` | `(?= ${/1/})` | A **positive lookahead** checks whether interpolations match, and if so continues the matcher without changing the input. If it matches, it's essentially ignored. | 220 223 | `(?! )` | `(?! ${/1/})` | A **negative lookahead** checks whether interpolations _don't_ match, and if so continues the matcher without changing the input. If the interpolations do match the matcher is aborted. | 221 224 222 225 We can combine and compose these operators to create more complex matchers.
+1 -3
src/core.js
··· 46 46 return pattern(state); 47 47 }; 48 48 49 - const match = (name, transform) => (quasis, ...expressions) => { 49 + export const match = (name, transform) => (quasis, ...expressions) => { 50 50 const ast = parseDSL( 51 51 quasis, 52 52 expressions.map((expression, i) => `_exec(state, _e${i})`) ··· 60 60 ); 61 61 return makeMatcher(_exec, name, transform, ...expressions.map(_pattern)); 62 62 }; 63 - 64 - export default match;