j-simple-parser v1.0.0
A simple and easy to use text parsing javascript library, j-simple-parser comes with elegant parsers that you can use to build complex and more elegant parsers.
CORE PARSERS
Importing core parsers
const {
string,
any,
char,
firstChar,
lastChar,
remainingChars,
digit,
space,
spaceOptional,
letter,
pattern,
word,
charsBefore,
debug,
newLine,
} = require('j-simple-parser');Using core parsers
1).
console.log( string('WE', false).seq(any(space()).star()).parse('Welcome to Magabelab') ); Output
Success { start: 0, end: 7, value: 'Welcome' }2).
console.log( any(char('g')).plus().parse('I am good') ); Output
Success { start: 0, end: 5, value: 'I am ' }3).
console.log( digit().plus().firstMatch('I am 20 years old and my sister is 12 years old') ); Output
Success { start: 5, end: 7, value: '20' }4).
console.log( digit().removeFrom('I am 20 years old and my sister is 12 years old') ); Output
I am years old and my sister is years old5). Capitalize a sentence , using replaceIn method
console.log(letter().replaceIn('I am 20 years old and my sister is 12 years old', (letter) => {
return letter.toUpperCase();
})); Output
I AM 20 YEARS OLD AND MY SISTER IS 12 YEARS OLD6).
console.log( letter().allStringMatches('Magabe Lab') ); Output
['M', 'a', 'g','a', 'b', 'e','L', 'a', 'b']7). Format spaces
console.log(space().replaceIn('I am good ', (_) => {
return ' ';
})); Output
I am good8).
console.log( firstChar().parse('I am the best') ); Output
Success { start: 0, end: 1, value: 'I' }9).
console.log( lastChar().allMatches('I am the best') ); Output
Success { start: 12, end: 13, value: 't' } ]10).
console.log( remainingChars().parse('I am the best') ); Success { start: 0, end: 13, value: 'I am the best' }11).
console.log( space().seq(char('e').repeat(2, 3)).parse(' eee') ); Output
Success { start: 0, end: 7, value: ' eee' }12). using removeFrom method
console.log( digit().or(space()).removeFrom(' 744 eee') ); Output
eee13).
console.log(char('c').parse('chura', 0)); Output
Success { start: 0, end: 1, value: 'c' }14).
console.log(char('c').parse('chura', 1)); Failure { position: 1, message: '' }15).
const tag = char('<')
.seq(letter().plus())
.seq(spaceOptional())
.seq(char('/').optional())
.seq(char('>'));
console.log( tag.firstStringMatch('<tag></tag>') );
console.log( tag.allStringMatches('<tag/><i></i>') ); Outputs
<tag>
[ '<tag/>', '<i>' ]16).
const code = '//my variable' +
'\n' +
'let foo =1;' +
'\n' +
'/*this is my function*/' +
'function getMoney()' +
'{' +
'console.log("money money");' +
'}';
function comment() {
const singleLine = string("//").seq(any(string("//").or(char('\n'))).star()).seq(spaceOptional()).plus();
const multiLine = string("/*").seq(any(string("*/")).plus()).seq(string("*/"));
return singleLine.or(multiLine);
}
console.log( comment().allStringMatches(code) );Output
[ '<tag/>', '<i>' ]WRITING YOUR OWN PARSER
Import the required resources
/** Required when building a parser from scratch**/
const {
Context,
Success,
Failure,
parserPrototype
} = require('j-simple-parser');The data we are going to parse.
const code = '//my variable' +
'\n' +
'let foo =1;' +
'\n' +
'/*this is my function*/' +
'function getMoney()' +
'{' +
'console.log("money money");' +
'}';1). Declare a parser class.
function FunctionParser(className) {
this.className = className;
}2). Extend Parser using parserPrototype function.
parserPrototype function take two arguments, the first argument is the parser class, and the last argument is parseOn function.
parseOn function takes one argument which is the context.
FunctionParser.prototype = parserPrototype(FunctionParser, function (context) {
const buffer = context.buffer;
const pos = context.position;
if (pos < buffer.length) {
const fn_declaration_match = this.fnDeclaration(this.className).parse(buffer, pos);
if (fn_declaration_match.isSuccess()) {
const start = fn_declaration_match.start;
const function_scope_begin_match = spaceOptional().seq(char('{')).parse(buffer, fn_declaration_match.end);
if (function_scope_begin_match.isFailure()) {
return new Failure(function_scope_begin_match.position);
} else {
let list = char('{').or(char('}')).allMatches(buffer, function_scope_begin_match.end);
if (list.length === 0) {
return new Failure(function_scope_begin_match.end);
}
let stack = 1;//the 1 verified by function_scope_begin_match
let end = 0;
for (let i = 0; i < list.length; i++) {
const match = list[i];
if (char('{').hasMatch(match.value)) {
stack++;
} else {
stack--;
}
end = match.end;
if (stack === 0) {
return new Success(buffer, start, end);
}
}
return new Failure(end);
}
} else {
return new Failure(fn_declaration_match.position);
}
} else {
return Failure(buffer.length());
}
})3). After extending your parser using parserPrototype , you can now add more methods, these methods can be used with in parseOn method, here i add fnDeclaration method.
FunctionParser.prototype.fnDeclaration = function (className) {
const pointer_or_ref = char('*').or(char('&'));
const name = (letter().or(char('_'))).seq((char('-').or(char('_')).or(word())).star());
const return_type = name.seq(pointer_or_ref).or(name);
const class_scope_name = string(className).seq(string("::")).seq((char('~').seq(string(className))).or(name));
const with_return_type = return_type.seq(space()).seq(class_scope_name)
.seq(spaceOptional()).seq(char('('))
.seq(any(char(')'), ")").star().seq(char(')')));
const with_no_return_type = spaceOptional().seq(class_scope_name)
.seq(spaceOptional()).seq(char('('))
.seq(any(char(')'), ")").star().seq(char(')'))).or(
spaceOptional().seq(string('function'))
.seq(spaceOptional()).seq(name.optional()).seq(spaceOptional()).seq(char('('))
.seq(any(char(')'), ")").star().seq(char(')')))
);
return with_return_type.or(with_no_return_type);
}4). Following j-simple-parser library conversion, create a factory function for your parser.
function fn(className = '') {
return new FunctionParser(className);
}5). Done, our parser is ready to use.
console.log( fn().allMatches(code) );Output
[
Success {
start: 49,
end: 97,
value: 'function getMoney(){console.log("money money");}'
}
]Using with other parsers.
console.log( comment().seq(fn()).allMatches(code) );Output
[
Success {
start: 26,
end: 97,
value: '/*this is my function*/function getMoney(){console.log("money money");}'
}
]5 years ago