Ejemplo n.º 1
0
 it('can parse a char sequence many times', () => {
     const zeroOrMoreParser = many(pstring('marco'));
     let parsing = zeroOrMoreParser.run('marcomarcociao');
     expect(parsing.isSuccess).to.be.true;
     expect(parsing.toString())
         .to.be.eql('Validation.Success([[[m,a,r,c,o],[m,a,r,c,o]],row=0;col=10;rest=ciao])');
 });
Ejemplo n.º 2
0
 it('allows to exclude parentheses', () => {
     const insideParens = pchar('(')
         .discardFirst(many(anyOf(lowercases)))
         .discardSecond(pchar(')'));
     expect(insideParens.run('(marco)').toString())
         .to.be.eql('Validation.Success([[m,a,r,c,o],row=1;col=0;rest=])');
     expect(insideParens.run('()').toString())
         .to.be.eql('Validation.Success([[],row=1;col=0;rest=])');
 });
Ejemplo n.º 3
0
 it('can parse a char exactly n times and return an array (or fail)', () => {
     const exactlyThree = many(pchar('m'), 3);
     let parsing = exactlyThree.run(text('mmmarco'));
     expect(parsing.isSuccess).to.be.true;
     expect(parsing.toString()).to.be.eql('Validation.Success([[m,m,m],row=0;col=3;rest=arco])');
     parsing = exactlyThree.run(text('mmmmarco'));
     expect(parsing.isFailure).to.be.true;
     expect(parsing.toString()).to.be.eql('Validation.Failure([many pchar_m times=3,times param wanted 3; got 4,row=0;col=0;rest=mmmmarco])');
 });
Ejemplo n.º 4
0
 it('can parse whitespaces!!', () => {
     const whitesParser = many(anyOf(whites));
     const twoWords = sequenceP([pstring('ciao'), whitesParser, pstring('mamma')]);
     let parsing = twoWords.run('ciaomammaX');
     expect(parsing.toString())
         .to.be.eql('Validation.Success([[[c,i,a,o],[],[m,a,m,m,a]],row=0;col=9;rest=X])');
     parsing = twoWords.run('ciao mammaX');
     expect(parsing.toString())
         .to.be.eql('Validation.Success([[[c,i,a,o],[ ],[m,a,m,m,a]],row=0;col=10;rest=X])');
     parsing = twoWords.run('ciao   mammaX');
     expect(parsing.toString())
         .to.be.eql('Validation.Success([[[c,i,a,o],[ , , ],[m,a,m,m,a]],row=0;col=12;rest=X])');
     parsing = twoWords.run('ciao \t mammaX');
     expect(parsing.toString())
         .to.be.eql('Validation.Success([[[c,i,a,o],[ ,\t, ],[m,a,m,m,a]],row=0;col=12;rest=X])');
 });
Ejemplo n.º 5
0
 it('...also when inside a lists', () => {
     const substringsWithCommas = many(many1(anyOf(lowercases)).discardSecond(pchar(',')));
     const listElements = between(pchar('['), substringsWithCommas, pchar(']'));
     expect(listElements.run('[a,b,cd,marco,]1').toString())
         .to.be.eql('Validation.Success([[[a],[b],[c,d],[m,a,r,c,o]],row=0;col=15;rest=1])');
 });
Ejemplo n.º 6
0
 it('cherry-picking elements separated by separators', () => {
     const substringsWithCommas = many(many1(anyOf(lowercases)).discardSecond(pchar(',')));
     expect(substringsWithCommas.run('a,b,cd,1').toString())
         .to.be.eql('Validation.Success([[[a],[b],[c,d]],row=0;col=7;rest=1])');
 });
Ejemplo n.º 7
0
 it('can parse a char many times and return an array', () => {
     const zeroOrMoreParser = many(pchar('m'));
     let parsing = zeroOrMoreParser.run(text('mmmarco'));
     expect(parsing.isSuccess).to.be.true;
     expect(parsing.toString()).to.be.eql('Validation.Success([[m,m,m],row=0;col=3;rest=arco])');
 });
Ejemplo n.º 8
0
 it('can parse a char zero times', () => {
     const zeroOrMoreParser = many(pchar('m'));
     let parsing = zeroOrMoreParser.run(text('arco'));
     expect(parsing.isSuccess).to.be.true;
     expect(parsing.toString()).to.be.eql('Validation.Success([[],row=0;col=0;rest=arco])');
 });
Ejemplo n.º 9
0
const numberP1 = manyChars1(digitP).fmap(parseFloat).setLabel('manyChars1(digitP).fmap(parseFloat)');

console.log('\n05_recursive_grammar.js');
logToScreen('42', numberP1);
// parse("42", number) |> IO.inspect
// # >> {:ok, 42}
logToScreen('1834798542234', numberP1);

// # We also need to ignore whitespaces around a number, to do that we will use
// # the `surrounded_by` combinator, since the whitespaces are optionals we also
// # use the `maybe` combinator
// number = while("0123456789", at_least: 1)
//          |> surrounded_by(bls?)
//          |> bind(&String.to_integer/1)

const numberP2 = between(opt(many(whiteP)), numberP1, opt(many(whiteP)));

logToScreen('   42  ', numberP2);
// parse(" 42 ", number) |> IO.inspect
// # >> {:ok, 42}

// # An expression is a number, an operation between expressions and an expression
// # between parentheses. An expression is defined in terms of itself so it's a
// # recursive definition. For a recursive definition we need a recursive parser
//
// # We need to be able to talk about a parser before having completed its
// # definition, for this we use the `recursive` combinator
//
//
//   def box(%Parser{} = p), do: p
//   def box(%Regex{} = r), do: re(r)
Ejemplo n.º 10
0
    sepBy1,
    lowercaseP,
    uppercaseP,
    letterP,
    digitP,
    whiteP,
    tapP,
    logP,
    pword,
} from 'parsers';

// word = while(letters, at_least: 1)
const wordP = many1(letterP).fmap(arra => arra.join(''));

// separator = lex(",") |> skip
const separatorP = between(many(whiteP), pchar(','), many(whiteP));

// terminator = lex("!") |> one_or_more |> skip
const terminatorP = many1(pchar('!'));

// greetings = sequence_of([word, separator, word, terminator])
const greetingsP = wordP.discardSecond(separatorP).andThen(wordP).discardSecond(terminatorP);

console.log('\n01_hello_world.js');
console.log('Using wordP.discardSecond(separatorP).andThen(wordP).discardSecond(terminatorP);');

logToScreen('Hello,World!');
// # >> {:ok, ["Hello", "World"]}

logToScreen('Hello, World!');
// # >> {:ok, ["Hello", "World"]}