jsdrink is a simple parser combinators library written in TypeScript, ported from cordx56/godrink.
jsdrink is a simple, lightweight library. jsdrink does not depend on non-standard libraries except dev-dependencies.
jsdrink reads input bytes or string and applies parsers in sequence and parses them into the desired structures.
See https://cordx.net/jsdrink/.
Here is an example of a calculator.
import { ParseResult, tf, sequence, any, many0 } from "jsdrink";
import { string, space0 } from "jsdrink/string";
import { integer } from "jsdrink/number";
const expr = (input: string): ParseResult<number> => {
return tf(
sequence(
term,
many0(
tf(
sequence(space0, any(string("+"), string("-")), space0, term),
(parsed) => {
if (parsed[1] == "+") {
return parsed[3];
} else if (parsed[1] == "-") {
return -1 * parsed[3];
} else {
return 0;
}
}
)
)
),
(parsed) => {
return parsed[0] + parsed[1].reduce((sum, elem) => sum + elem, 0);
}
)(input);
};
const term = (input: string): ParseResult<number> => {
return tf(
sequence(
factor,
many0(
tf(
sequence(space0, any(string("*"), string("/")), space0, factor),
(parsed) => {
if (parsed[1] == "*") {
return parsed[3];
} else if (parsed[1] == "/") {
return 1 / parsed[3];
} else {
return 0;
}
}
)
)
),
(parsed) => {
return parsed[0] * parsed[1].reduce((sum, elem) => sum * elem, 1);
}
)(input);
};
const factor = (input: string): ParseResult<number> => {
return any(
integer,
tf(sequence(string("("), space0, expr, space0, string(")")), (parsed) => {
return parsed[2];
})
)(input);
};
console.log(expr("3 / (1 + 2) * 9").parsed); // 9