You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This fixes many broken things:
* Most importantly, the Syntax Reference page no longer shows broken
Markdown
* Added syntax highlighting wherever missing
* Fixed some headings not being in table of contents
* Fixed broken anchors
* There are a few false warnings left
* Updated Docusaurus
* Unorphaned or merged pages
* Imported Docker page
* Use a symlink relative path for viewing images locally
Fixes: ohmjs/ohm#475
Copy file name to clipboardExpand all lines: blog/2026-02-20-ohm-v18.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,6 +9,8 @@ _aka "The One that Compiles to Wasm"._
9
9
10
10
After nearly a year of development, we're excited to announce the first beta release of Ohm v18 — the biggest change to Ohm since its initial release. We've totally reworked the core parsing engine to be WebAssembly-based, making parsing around 20x faster on real-world grammars while using a fraction of the memory.
11
11
12
+
{/* truncate */}
13
+
12
14
## What's new
13
15
14
16
Every version of Ohm up to v17 worked the same way under the hood: when you call `grammar.match()`, Ohm walks a tree of parsing expression objects (PExprs), calling `eval()` on each node. (It's a so-called [tree-walking interpreter](https://craftinginterpreters.com/a-tree-walk-interpreter.html).) In the process, it builds up a huge parse tree, with each node a separate object that must be managed by the GC.
@@ -6,11 +6,15 @@ This page documents the API of Ohm/JS, a JavaScript library for working with gra
6
6
7
7
**NOTE:** For grammars defined in a JavaScript string literal (i.e., not in a separate .ohm file), it's recommended to use a [template literal with the String.raw tag](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw).
Instantiate the Grammar defined by `source`. If specified, `optNamespace` is an object in which references to other grammars should be resolved. For example, if the grammar source begins with an inheritance declaration like `MyGrammar <: OtherGrammar { ... }`, then `optNamespace` should have a property named `OtherGrammar`.
Create a new object containing Grammar instances for all of the grammars defined in `source`. As with `ohm.grammar`, if `optNamespace` is specified, it is an object in which references to other grammars should be resolved. Additionally, it will be the prototype of the returned object.
16
20
@@ -21,7 +25,7 @@ Here is an example of instantiating a Grammar:
In the next example We instantiate a new grammar, *Child*, that inherits from our *Parent* grammar. We use the `ohm.grammars` method, which returns an object of our grammars:
Try to match `str` against `g`, returning a [MatchResult](#matchresult-objects). If `optStartRule` is given, it specifies the rule on which to start matching. By default, the start rule is inherited from the supergrammar, or if there is no supergrammar specified, it is the first rule in `g`'s definition.
76
85
77
-
<b><preclass="api">g.matcher()</pre></b>
86
+
```ts
87
+
g.matcher()
88
+
```
78
89
79
90
Create a new [Matcher](#matcher-objects) object which supports incrementally matching `g` against a changing input string.
Try to match `str` against `g`, returning a Trace object. `optStartRule` has the same meaning as in `g.match`. Trace objects have a `toString()` method, which returns a string which summarizes each parsing step (useful for debugging).
Create a new [Semantics](#semantics) object for `g` that inherits all of the operations and attributes in `superSemantics`. `g` must be a descendent of the grammar associated with `superSemantics`.
110
+
Create a new [Semantics](#semantics-objects) object for `g` that inherits all of the operations and attributes in `superSemantics`. `g` must be a descendent of the grammar associated with `superSemantics`.
92
111
93
112
## Matcher objects
94
113
95
114
Matcher objects can be used to incrementally match a changing input against the Matcher's grammar, e.g. in an editor or IDE. When a Matcher's input is modified via `replaceInputRange`, further calls to `match` will reuse the partial results of previous calls wherever possible. Generally, this means that small changes to the input will result in very short match times.
Return `true` if the match failed, otherwise `false`.
132
165
133
166
### MatchFailure objects
134
167
135
168
When `r.failed()` is `true`, `r` has the following additional properties and methods:
136
169
137
-
<b><preclass="api">r.message: string</pre></b>
170
+
```ts
171
+
r.message: string
172
+
```
138
173
139
174
Contains a message indicating where and why the match failed. This message is suitable for end users of a language (i.e., people who do not have access to the grammar source).
Return an array of Failure objects describing the failures the occurred at the rightmost failure position.
152
193
153
-
<h2id="semantics">Semantics, Operations, and Attributes</h2>
194
+
## Semantics, Operations, and Attributes
154
195
155
196
An Operation represents a function that can be applied to a successful match result. Like a [Visitor](http://en.wikipedia.org/wiki/Visitor_pattern), an operation is evaluated by recursively walking the parse tree, and at each node, invoking the matching semantic action from its _action dictionary_.
156
197
@@ -165,21 +206,29 @@ This returns a parse node, whose properties correspond to the operations and att
165
206
166
207
A Semantics instance `s` has the following methods, which all return `this` so they can be chained:
Add a new Operation to this Semantics, using the [semantic actions](#semantic-actions) contained in `actionDict`. The first argument is either a name (e.g. `'prettyPrint'`) or a _signature_ which specifies the operation name and zero or more named parameters (e.g., `'prettyPrint()'`, `'prettyPrint(depth, strict)'`). It is an error if there is already an operation or attribute called `name` in this semantics.
171
214
172
215
If the operation has arguments, they are accessible via `this.args` within a semantic action. For example, `this.args.depth` would hold the value of the `depth` argument for the current action.
Extend the Operation named `name` with the semantic actions contained in `actionDict`. `name` must be the name of an operation in the super semantics — i.e., you must first extend the Semantics via [`extendSemantics`](#extendSemantics) before you can extend any of its operations.
Exactly like `semantics.extendOperation`, except it will extend an Attribute of the super semantics rather than an Operation.
185
234
@@ -189,7 +238,7 @@ A semantic action is a function that computes the value of an operation or attri
189
238
190
239
-_Rule application_, or _non-terminal_ nodes, which correspond to rule application expressions
191
240
-_Terminal_ nodes, for string and number literals, and keyword expressions
192
-
-_Iteration_ nodes, which are associated with expressions inside a [repetition operator](./syntax-reference.md#repetition-operators) (`*`, `+`, and `?`)
241
+
-_Iteration_ nodes, which are associated with expressions inside a [repetition operator](./syntax-reference.md#repetition-operators---) (`*`, `+`, and `?`)
193
242
194
243
Generally, you write a semantic action for each rule in your grammar, and store them together in an _action dictionary_. For example, given the following grammar:
195
244
@@ -239,7 +288,7 @@ The matching semantic action for a particular node is chosen as follows:
239
288
- On a terminal node (e.g., a node produced by the parsing expression `"hello"`), use the semantic action named `_terminal`.
240
289
- On an iteration node (e.g., a node produced by the parsing expression `letter+`), use the semantic action named `_iter`.
241
290
242
-
<spanid="special-actions"></span>The `_iter`, `_nonterminal`, and `_terminal` actions are sometimes called _special actions_. `_iter` and `_nonterminal` take a variable number of arguments, which are typically captured into an array using [rest parameter syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters) , e.g. `_iter(...children) {'{'} ... {'}'}`. The `_terminal` action takes no arguments.
291
+
<spanid="special-actions"></span>The `_iter`, `_nonterminal`, and `_terminal` actions are sometimes called _special actions_. `_iter` and `_nonterminal` take a variable number of arguments, which are typically captured into an array using [rest parameter syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters) , e.g. <code>_iter(...children) { ... }</code>. The `_terminal` action takes no arguments.
243
292
244
293
<!-- @markscript
245
294
markscript.transformNextBlock((code) =>
@@ -250,47 +299,65 @@ The matching semantic action for a particular node is chosen as follows:
250
299
251
300
_**NOTE:** Versions of Ohm prior to v16.0 had slightly different behaviour with regards to default semantic actions. See [here](./releases/ohm-js-16.0.md#default-semantic-actions) for more details._
252
301
253
-
Note that you can also write semantic actions for built-in rules like `letter` or `digit`. For `ListOf`, please see the documentation on [asIteration](#asIteration) below.
302
+
Note that you can also write semantic actions for built-in rules like `letter` or `digit`. For `ListOf`, please see the documentation on [asIteration](#asiteration) below.
254
303
255
304
### Parse Nodes
256
305
257
306
Each parse node is associated with a particular _parsing expression_ (a fragment of an Ohm grammar), and the node captures any input that was successfully parsed by that expression. Unlike many parsing frameworks, Ohm does not have a syntax for binding/capturing -- every parsing expression captures all the input it consumes, and produces a fixed number of values.
258
307
259
308
A node `n` has the following methods and properties:
0 commit comments