<commit_before>'use strict';
/**
 * Grammar without left recursion
 *
 * eqn         -> expr = expr
 * expr        -> term expr_rest
 * expr_rest   -> + term expr_rest
 *             | - term expr_rest
 *             | ε
 *
 * term        -> factor term_rest
 * term_rest   -> * term term_rest
 *             |   term term_rest
 *             | ^ term term_rest
 *             | / term term_rest
 *             | ε
 *
 * factor      -> (expr)
 *             | num
 *             | id
 *
 **/

let Lexer            = require('./lexer'),

    $tokens          = require('./tokens'),
    LiteralNumber    = $tokens.LiteralNumber,
    Addition         = $tokens.Addition,
    Subtraction      = $tokens.Subtraction,
    Multiplication   = $tokens.Multiplication,
    Division         = $tokens.Division,
    Exponentiation   = $tokens.Exponentiation,
    LeftParenthesis  = $tokens.LeftParenthesis,
    RightParenthesis = $tokens.RightParenthesis,
    Identifier       = $tokens.Identifier,

    $expressions     = require('./expressions'),
    Expression       = $expressions.Expression,

    $helper          = require('./helper'),
    isInt            = $helper.isInt,

    Fraction         = require('./fractions')

;

class Parser {

    constructor() { this.lexer = new Lexer(); }
    set input(input) {
        this.lexer.input = input;
        this.tokens = this.lexer.tokens();
        this._token_iteration = null;
    }
    update() { this._token_iteration = this.tokens.next(); }
    get token() { return this._token_iteration.value; }
    done() { return this._token_iteration.done; }

    parse(string)     {
        this.input = string;
        this.update();
        return this.parseExpr();
    }
    parseExpr() { return this.parseExprRest(this.parseTerm()); }
    parseTerm() { return this.parseTermRest(this.parseFactor()); }
    parseFactor() {
        if (this.token instanceof LiteralNumber) {
            let num = this.parseNumber();
            this.update();
            return num;
        } else if (this.token instanceof Identifier) {
            let identifier = new Expression(this.token.name);
            this.update();
            return identifier;
        } else if (this.token instanceof LeftParenthesis) {
            this.update();
            let expr = this.parseExpr();
            if (this.token instanceof RightParenthesis) {
                this.update();
                return expr;
            } else {
                throw new SyntaxError('Unbalanced Parenthesis');
            }
        } else { return undefined; }
    }
    parseNumber() {
        let intValue = parseInt(this.token.string);
        //Integer conversion
        if (intValue == this.token.string) {
            return new Expression(intValue);      
        } else {
            //Split the decimal number to integer and decimal parts
            let splits = this.token.string.split('.');
            //count the digits of the decimal part
            let decimals = splits[1].length;
            //determine the multiplication factor
            let factor = Math.pow(10,decimals);
            let float_op = parseFloat(this.token.string);
            //multiply the float with the factor and divide it again afterwards 
            //to create a valid expression object
            return new Expression(parseInt(float_op * factor)).divide(factor);
        }
    }
    parseExprRest(term) {
        if (this.token instanceof Addition) {
            this.update();
            let plusterm = this.parseTerm();
            if(term === undefined || plusterm === undefined) throw new SyntaxError('Missing operand');
            return this.parseExprRest(term.add(plusterm));
        } else if (this.token instanceof Subtraction) {
            this.update();
            let minusterm = this.parseTerm();
            //This case is entered when a negative number is parsed e.g. x = -4
            if (term === undefined) {
                return this.parseExprRest(minusterm.multiply(-1));
            } else {
                return this.parseExprRest(term.subtract(minusterm));
            }
        } else {
            return term;
        }
    }
    parseTermRest(factor) {
        if (this.token instanceof Multiplication) {
            this.update();
            let mulfactor = this.parseFactor(),
                termRest  = this.parseTermRest(mulfactor),
                product   = factor.multiply(termRest);
            return product;
        } else if (this.token instanceof Exponentiation) {
            this.update();
            let powfactor = this.parseFactor();
            //WORKAROUND: algebra.js only allows integers and fractions for
            //raising
            return this.parseTermRest(
                factor.pow(parseInt(powfactor.toString()))
            );
        } else if (this.token instanceof Division) {
            this.update();<commit_msg>import less classes<commit_after>'use strict';
/**
 * Grammar without left recursion
 *
 * eqn         -> expr = expr
 * expr        -> term expr_rest
 * expr_rest   -> + term expr_rest
 *             | - term expr_rest
 *             | ε
 *
 * term        -> factor term_rest
 * term_rest   -> * term term_rest
 *             |   term term_rest
 *             | ^ term term_rest
 *             | / term term_rest
 *             | ε
 *
 * factor      -> (expr)
 *             | num
 *             | id
 *
 **/

let Lexer            = require('./lexer'),
    Fraction         = require('./fractions'),
    $tokens          = require('./tokens'),
    $expressions     = require('./expressions'),
    $helper          = require('./helper'),
    Expression       = $expressions.Expression,
    isInt            = $helper.isInt
;

class Parser {

    constructor() { this.lexer = new Lexer(); }
    set input(input) {
        this.lexer.input = input;
        this.tokens = this.lexer.tokens();
        this._token_iteration = null;
    }
    update() { this._token_iteration = this.tokens.next(); }
    get token() { return this._token_iteration.value; }
    done() { return this._token_iteration.done; }

    parse(string)     {
        this.input = string;
        this.update();
        return this.parseExpr();
    }
    parseExpr() { return this.parseExprRest(this.parseTerm()); }
    parseTerm() { return this.parseTermRest(this.parseFactor()); }
    parseFactor() {
        if (this.token instanceof $tokens.LiteralNumber) {
            let num = this.parseNumber();
            this.update();
            return num;
        } else if (this.token instanceof $tokens.Identifier) {
            let identifier = new Expression(this.token.name);
            this.update();
            return identifier;
        } else if (this.token instanceof $tokens.LeftParenthesis) {
            this.update();
            let expr = this.parseExpr();
            if (this.token instanceof $tokens.RightParenthesis) {
                this.update();
                return expr;
            } else {
                throw new SyntaxError('Unbalanced Parenthesis');
            }
        } else { return undefined; }
    }
    parseNumber() {
        let intValue = parseInt(this.token.string);
        //Integer conversion
        if (intValue == this.token.string) {
            return new Expression(intValue);      
        } else {
            //Split the decimal number to integer and decimal parts
            let splits = this.token.string.split('.');
            //count the digits of the decimal part
            let decimals = splits[1].length;
            //determine the multiplication factor
            let factor = Math.pow(10,decimals);
            let float_op = parseFloat(this.token.string);
            //multiply the float with the factor and divide it again afterwards 
            //to create a valid expression object
            return new Expression(parseInt(float_op * factor)).divide(factor);
        }
    }
    parseExprRest(term) {
        if (this.token instanceof $tokens.Addition) {
            this.update();
            let plusterm = this.parseTerm();
            if(term === undefined || plusterm === undefined) throw new SyntaxError('Missing operand');
            return this.parseExprRest(term.add(plusterm));
        } else if (this.token instanceof $tokens.Subtraction) {
            this.update();
            let minusterm = this.parseTerm();
            //This case is entered when a negative number is parsed e.g. x = -4
            if (term === undefined) {
                return this.parseExprRest(minusterm.multiply(-1));
            } else {
                return this.parseExprRest(term.subtract(minusterm));
            }
        } else {
            return term;
        }
    }
    parseTermRest(factor) {
        if (this.token instanceof $tokens.Multiplication) {
            this.update();
            let mulfactor = this.parseFactor(),
                termRest  = this.parseTermRest(mulfactor),
                product   = factor.multiply(termRest);
            return product;
        } else if (this.token instanceof $tokens.Exponentiation) {
            this.update();
            let powfactor = this.parseFactor();
            //WORKAROUND: algebra.js only allows integers and fractions for
            //raising
            return this.parseTermRest(
                factor.pow(parseInt(powfactor.toString()))
            );
        } else if (this.token instanceof $tokens.Division) {
            this.update();
{'fraction_non_alphanumeric': 0.11027780711946762, 'fraction_numerical': 0.0010563008344776593, 'mean_word_length': 1.7222541690626798, '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': '1717727', 'n_tokens_mistral': 2485, 'n_tokens_neox': 2433, 'n_words': 605}