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
grammarFromScriptElementandgrammarsFromScriptElementsfunctions have been entirely removed. - The
primitiveValueproperty of nodes, which was deprecated in Ohm v16, has now been completely removed — useNode.sourceStringinstead.