<commit_before>import genlex from '../../lib/genlex/genlex';
import token from '../../lib/genlex/token';
import {F, C, N} from '../../lib/parsec/index';
import stream from '../../lib/stream/index';


//
// Facilities
//

var tkNumber = token.parser.number,
    tkKeyword = token.parser.keyword;

function tkKey(s) {
    return tkKeyword.match(s);
}

const priorToken = () => tkKey('*').or(tkKey('/'))


const multExpr = () => terminal().then(subMultExpr().opt())
    .map(([left, optRight]) => left * optRight.orElse(1));


const subMultExpr = function () {

    return tkKey('*').drop().then(terminal())
        .then(F.lazy(subMultExpr).opt())
        .map(([left, optRight]) => left * optRight.orElse(1))
};

function terminal() {
    return tkNumber.or(F.lazy(multExpr));
}

function priorExpr() {
    return terminal().then(subPriorExpr().opt())
        .map(([left, optRight]) => {
            if (optRight.isPresent()){
                let [operator, right] = optRight.get();
                return operator === '*' ? left*right : left/right;
            }else{
                return left;
            }

        });

}

function subPriorExpr() {

    return priorToken().then(terminal())
        .then(F.lazy(subPriorExpr).opt())
        .map(([token, left, optRight]) => {
            console.log(token, left, optRight);
            return [token, left * optRight.orElse(1)];
        })
};


function multParser() {
    var keywords = ['*', '/'],
        tokenizer = genlex
            .generator(keywords)
            .tokenBetweenSpaces(token.builder);

    return tokenizer.chain(priorExpr().thenLeft(F.eos().drop()));
}

export default {
    setUp: function (done) {
        done();
    },

    'expect multExpr to make mults': function (test) {
        let parsing = multParser().parse(stream.ofString('3 * 4'));
        test.equal(parsing.value, 12, 'simple multiplication');

        parsing = multParser().parse(stream.ofString('14 / 4'));
        console.log('>>>', parsing.value);
        test.equal(parsing.value, 3.5, 'simple division');

        test.done();
    }

}<commit_msg>#103: Making good priority when composing mult and div Using flatMap for a left pririty (or composition ?) instead of then(F.Lazy)<commit_after>import genlex from '../../lib/genlex/genlex';
import token from '../../lib/genlex/token';
import {F, C, N} from '../../lib/parsec/index';
import stream from '../../lib/stream/index';


//
// Facilities
//

var tkNumber = token.parser.number,
    tkKeyword = token.parser.keyword;

function tkKey(s) {
    return tkKeyword.match(s);
}

const priorToken = () => tkKey('*').or(tkKey('/'));


function terminal() {
    return tkNumber.or(F.lazy(priorExpr));
}

function priorExpr() {
    return terminal().flatMap(optSubPriorExp);


}

function optSubPriorExp(priorValue) {
    // console.log('previousValue', priorValue);
    return subPriorExpr(priorValue).opt()
        .map(opt => opt.isPresent() ? opt.get() : priorValue);
}


function subPriorExpr(priorValue) {

    return priorToken().then(terminal())
        .map(([token, left]) => token === '*' ? priorValue * left : priorValue / left)
        .flatMap(optSubPriorExp)
}


function multParser() {
    let keywords = ['*', '/'];
    let tokenizer = genlex
        .generator(keywords)
        .tokenBetweenSpaces(token.builder);

    return tokenizer.chain(priorExpr().thenLeft(F.eos().drop()));
}

export default {
    setUp: function (done) {
        done();
    },

    'expect multExpr to make mults': function (test) {
        let parsing = multParser().parse(stream.ofString('3 * 4'));
        test.equal(parsing.value, 12, 'simple multiplication');

        parsing = multParser().parse(stream.ofString('14 / 4'));

        test.equal(parsing.value, 3.5, 'simple division');

        parsing = multParser().parse(stream.ofString('14 / 4*3 '));

        test.equal(parsing.value, 10.5, 'combine mult and div');

        parsing = multParser().parse(stream.ofString('14 / 4*3 /2*  2 '));

        test.equal(parsing.value, 10.5, 'combine more mult and div');

        test.done();
    }

}
{'fraction_non_alphanumeric': 0.18017578125, 'fraction_numerical': 0.009765625, 'mean_word_length': 2.7552703941338224, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4809994', 'n_tokens_mistral': 1357, 'n_tokens_neox': 1280, 'n_words': 268}