@tabnas/abnf 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,6 +27,35 @@ tn.abnf(`greet = "hi" / "hello"`)
|
|
|
27
27
|
tn.parse('hi') // => ({ rule: 'greet', src: 'hi', kids: [] })
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
## Left recursion
|
|
31
|
+
|
|
32
|
+
Left-recursive rules are accepted directly. A left-recursion pass
|
|
33
|
+
(Paull's algorithm) rewrites direct (`P = P a / b`) and indirect
|
|
34
|
+
recursion into `P = b *(a)`, which the push-down engine runs without
|
|
35
|
+
re-entering a rule at the same position:
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
const { Tabnas } = require('@tabnas/parser')
|
|
39
|
+
const { abnf } = require('@tabnas/abnf')
|
|
40
|
+
|
|
41
|
+
const tn = new Tabnas({ plugins: [abnf] })
|
|
42
|
+
tn.abnf(`
|
|
43
|
+
expr = expr PL term / term
|
|
44
|
+
term = NR
|
|
45
|
+
PL = "+"
|
|
46
|
+
`)
|
|
47
|
+
|
|
48
|
+
tn.parse('1+2+3').kids.map((k) => k.rule) // => ['PL', 'term', 'PL', 'term']
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Because it is a rewrite, the tree is **flat** (no nested `expr`; the
|
|
52
|
+
leading operand folds into the rule, so associativity is applied in an
|
|
53
|
+
action, not read off the AST), and `@ref` alt actions on the rewritten
|
|
54
|
+
branches are look-up-only — attach actions to the sub-rules instead. A
|
|
55
|
+
**purely** left-recursive rule (no non-recursive branch) is an error.
|
|
56
|
+
See [concepts.md](doc/concepts.md) and the root
|
|
57
|
+
[README](../README.md#left-recursion) for the full details and caveats.
|
|
58
|
+
|
|
30
59
|
## Documentation
|
|
31
60
|
|
|
32
61
|
Four-quadrant [Diátaxis](https://diataxis.fr) docs:
|