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 old
5). 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 OLD
6).
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 good
8).
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
eee
13).
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");}'
}
]
3 years ago