Writing a plugin
Pegase has a plugin system that allows you to extend the base functionalities. A plugin is a simple object with four optional properties:
name
: the name of your plugin.castParser
: A function to convert custom tag argument types intoParser
instances.directives
: Custom directive definitions.resolve
: A string toParser
map that will be used as a fallback resolver for undefined non-terminals in your peg expressions. Think of it as global rules.
For the exact type signature of these properties, please refer to API > Types. Plugins then have to be added to the peg
tag's plugins
array. Order matters: in case of conflict (a conflicting resolve
rule, directive
definition or castParser
behavior), the first will win. Let's add two directives @min
and @max
, that transform the children
of the wrapped parser to only keep respectively the minimum and the maximum value and emit it as a single child:
peg.plugins.push({
name: "my-plugin",
directives: {
min: parser => peg`${parser} ${() => Math.min(...$children())}`,
max: parser => peg`${parser} ${() => Math.max(...$children())}`
}
});
Testing it:
const max = peg`
list: $int+ @max
$int: \d+ @number
`;
max.value("36 12 42 3"); // 42
To remove a plugin, you can manipulate the plugins
array just like any other array: splice
it, or replace it entirely:
peg.plugins = peg.plugins.filter(({ name }) => name !== "my-plugin");