Expressit is a blazing fast, customizable, error-tolerant expression parser that creates safe to eval expressions + a few other goodies.
pnpm install @witchcraft/expressit
oregano
will parse to or egano
or oregano
can be adjusted to allow the use of keywords (usually symbols) without whitespace).prefix(variable)
which gets expanded into prefixvariable
. You can also customize how they get prefixed (e.g. you can make prefix(variable)
expand to prefix.variable
instead).:
): property:OP:value
.=
, >
, <
, etc): property=value
.prop=[val1, val2]
, prop=/regex/flags
, prop=(a || b)
.validate
(for syntax highlighting) and evaluate
ASTs according to custom rules.extractTokens
, getCursorInfo
, getOppositeDelimiter
, getSurroundingErrors
- useful for adding custom syntax highlighting.prettyAst
- pretty prints a compact version of the ast for debuggingisDelimiter
, isQuote
, etc.// while you can import from "@witchcraft/expressit", if using something like vite, it's recommended you do not use barrel imports.
import { Parser } from "@witchcraft/expressit/Parser.js"
import { ErrorToken } from "@witchcraft/expressit/classes/ErrorToken.js"
const parser = new Parser({/* opts */})
const context = {
a: false,
b: true
}
// USER INPUT
const input = "a || b"
const cursor = 1 // a| || b
const ast = parser.parse(input)
if (ast instanceof ErrorToken || !ast.valid) {
// ...show regular errors (no input, missing tokens, etc)
} else {
// validation can be controlled by parser options
const errors = parser.validate(ast)
// ...show more complex errors, e.g. unknown variables, etc
}
// ON AUTOCOMPLETE
const suggestions = parser.autosuggest(input, ast, cursor)
const completions = parser.autocomplete(suggestions, {
// known possible suggestions
variables: ["c", "d", "e"],
// can also be values, prefixes, keywords, properties, etc
})
// ...show completions
// ON ENTER/SUBMIT
const res = parser.evaluate(ast, context)
Many more examples can be found in the tests, and there's also some WIP pre-configured parsers in src/examples whose usage can be seen in ./test/examples.spec.ts.