1.0.6 • Published 5 years ago
first-follow-solver v1.0.6
First and Follow set Solver
First and follow set solver in Javascript. This library can be used to help you write your Parsers. It is currently being used to auto generate a parser based on the rule set.
Demo
To see this library in action check out this cool tool
How to add the library to your project?
Using npm
npm install first-follow-solverfollowed byimport { solve } from 'first-follow-solver'Or you can compile the library by running
npm run-script buildand then adding the dist/first-follow-solver.js to your html directly:<script src="./dist/first-follow-solver.js"></script>
How to use the library?
let problem = {
rules: [
{lhs: "S", rhs: ["a", "b"]}, // S -> a b
{lhs: "S", rhs: ["b", "b"]}, // S -> b b
{lhs: "S", rhs: ["b"]} // S -> b
],
// if not specified all symbols
// not used on the left side will be assumed to be terminals
terminals: ["a", "b"],
start: "S", // S is a default value
epsilon: "epsilon", // epsilon is the default value
eof: "$", // $ is the default value
}If included from the first-follow-solver.js file:
console.log("Solution", FirstFollowSolver.solve(problem));If included using npm:
console.log("Solution", solve(problem));Full API
solve(config)
validateSymbols(rules, terminals, epsilon)
extractTerminals(rules, mode, epsilon)
parseProgram(text, split)solve (method)
Parameters
configthe configuration objectconfig.rulesan array of rulesconfig.rules.0.lhsan object representing the head of the rule (left hand side)config.rules.0.rhsan array of strings representing the right hand side symbols
config.terminalsan array of string in which every string is a terminalconfig.startstring that represents the non terminal which starts the programconfig.epsilonstring that represents the epsilon symbolconfig.eofstring that represents the end of file symbol (used for follow sets)
Examples
let problem = {
rules: [
{lhs: "S", rhs: ["a", "b"]}, // S -> a b
{lhs: "S", rhs: ["b", "b"]}, // S -> b b
{lhs: "S", rhs: ["b"]} // S -> b
],
// if not specified all symbols
// not used on the left side will be assumed to be terminals
terminals: ["a", "b"],
start: "S", // S is a default value
epsilon: "epsilon", // epsilon is the default value
eof: "$", // $ is the default value
}
console.log("Solution", FirstFollowSolver.solve(problem));
// result is {"firstSet":{"S":["a","b"]},"followSet":{"S":["$"]}}validateSymbols (method)
Parameters
rulesan array of rulesrules.0.lhsan object representing the head of the rule (left hand side)rules.0.rhsan array of strings representing the right hand side symbols
terminalsan array of strings, each string is a terminalepsilonstring that represents the epsilon symbol
Exceptions
- Throws an exception that is a string containing the error if either one of the rules is broken
terminals cannot be on the left hand sidenon terminals must be on the left hand sideExamples
let rules = [
{lhs: "S", rhs: ["a", "b"]}, // S -> a b
{lhs: "S", rhs: ["b", "b"]}, // S -> b b
{lhs: "S", rhs: ["b"]} // S -> b
];
let terminals = ["a", "b"];
let epsilon = "epsilon";
FirstFollowSolver.validateSymbols(rules, terminals, epsilon);extractTerminals (method)
Parameters
rulesan array of rulesrules.0.lhsan object representing the head of the rule (left hand side)rules.0.rhsan array of strings representing the right hand side symbols
modea string that represents how the values are to be extracted- "lowercase" symbols are extracted as terminals if they contain a lowercase char
- "notLhs" symbols are extracted as terminals if they are not rule heads (left hand side)
epsilonstring that represents the epsilon symbol
Examples
let rules = [
{lhs: "S", rhs: ["a", "b"]}, // S -> a b
{lhs: "S", rhs: ["b", "b"]}, // S -> b b
{lhs: "S", rhs: ["b"]} // S -> b
];
let mode = "lowercase";
let epsilon = "epsilon";
console.log("Terminals", FirstFollowSolver.extractTerminals(rules, mode, epsilon));
// result is [a, b]parseProgram (method)
Parameters
textthe full program defined as a string, rules are separated into new linessplitthe string used to separate mutliple single line rules. ExampleS -> A | B
Examples
let grammarAsStr = "S -> demo | epsilon";
let split = "|";
console.log("Rules", FirstFollowSolver.parseProgram(grammarAsStr, split));
// result is [{lhs: "S", rhs: ["demo", "epsilon"]}]