Ohm v17.0
v17.0.0 is primarily a cleanup release in preparation for some new features that will be coming soon in minor releases. It contains a few breaking changes (as described below), but they are unlikely to affect the majority of Ohm users.
This version also has experimental support for indentation-sensitive grammars.
Upgrading
any
now consumes a full code point
In JavaScript, a string is a sequence of 16-bit code units. Some Unicode characters, such as emoji, are encoded as pairs of 16-bit values. For example, the string '😆' has length 2, but contains a single Unicode code point. Previously, any
matched a single 16-bit code unit — even if that unit was part of a surrogate pair. In v17, any
now matches a full Unicode character.
Old behaviour:
const g = ohm.grammar('OneChar { start = any }');
g.match('😆').succeeded(); // false
New behaviour (Ohm v17+):
const g = ohm.grammar('OneChar { start = any }');
g.match('😆').succeeded(); // true
Namespace helpers removed
The top-level namespace
and extendNamespace
functions have been removed. They were never required — it was always possible to use a plain old object in any API that asked for a namespace.
For example, take the following code (which no longer works in v17+):
const ns = ohm.createNamespace();
ns.G = ohm.grammar('G {}');
ns.G2 = ohm.grammar('G2 <: G {}', ns);
In Ohm v17 and in previous versions, the code could instead be written like this:
const ns = {}; // <- Use a normal object literal
ns.G = ohm.grammar('G {}');
ns.G2 = ohm.grammar('G2 <: G {}', ns);
Named exports only
When used as ES module, the ohm-js
and ohm-js/extras
modules now have only named exports, and no default export. This fixes some issues with the use of Ohm bundles (.ohm-bundle
files) when used with JS module bundlers like Webpack and Rollup (e.g., [#377][issue-377]).
As a result, the following code will no longer work (unless your bundler supports synthetic default imports):
import ohm from 'ohm-js';
In Ohm v17, it should be written like this:
import * as ohm from 'ohm-js';
See #386 for more context on this change.
util
removed
The util
object has been removed from Ohm's public API. The two methods that were relevant to grammar authors — getLineAndColumn
and getLineAndColumnMessage
— have been moved into the extras
module.
Old code (no longer works):
ohm.util.getLineAndColumnMessage(str, [startIdx, endIdx]);
New code (works in Ohm v17+):
import {getLineAndColumnMessage} from 'ohm-js/extras';
// ...
getLineAndColumnMessage(str, [startIdx, endIdx]);
By the way, the Interval
class also has a getLineAndColumnMessage
method, which can be useful inside of semantic actions. For example, if you are using this method with the sourceString
attribute, like this:
getLineAndColumnMessage(aNode.sourceString, [startIdx, endIdx]);
...you can write it this way instead:
aNode.source.getLineAndColumnMessage();
toAST
on built-in list rules
Ohm v17 changed the default behavior of toAST
for the built-in list rules (ListOf
and friends). Both the syntactic (ListOf
, ...) and lexical versions (listOf
, ...) are now represented as arrays, with the separators discarded. Previously, the syntactic versions were represented by arrays, but with separators included, and the lexical versions were represented as strings (just like other lexical rules).
See #394 for the reasoning behind this change.
New features
- (EXPERIMENTAL): This release includes experimental support for indentation-sensitive grammars (e.g., Python, Elm, YAML). See the guide to Parsing indentation sensitive languages.
Other changes
- The deprecated
grammarFromScriptElement
andgrammarsFromScriptElements
functions have been entirely removed. - The
primitiveValue
property of nodes, which was deprecated in Ohm v16, has now been completely removed — useNode.sourceString
instead.