squiggle/src/components/editor/parse.js
2020-03-03 15:58:53 +03:00

138 lines
3.4 KiB
JavaScript

const _math = require("mathjs");
const math = _math.create(_math.all);
// Functions for parsing/processing user input strings are here
const DISTR_REGEXS = [
/beta\(/g,
/(log)?normal\(/g,
/multimodal\(/g,
/mm\(/g,
/uniform\(/g
];
/**
*
* @param user_input_string
* @returns {{mm_args_string: string, outer_string: string}}
*/
function parse_initial_string(user_input_string) {
let outer_output_string = "";
let mm_args_string = "";
let idx = 0;
while (idx < user_input_string.length) {
if (
user_input_string.substring(idx - 11, idx) === "multimodal(" ||
user_input_string.substring(idx - 3, idx) === "mm("
) {
let num_open_brackets = 1;
while (num_open_brackets > 0 && idx < user_input_string.length) {
mm_args_string += user_input_string[idx];
idx += 1;
if (user_input_string[idx] === ")") {
num_open_brackets -= 1;
} else if (user_input_string[idx] === "(") {
num_open_brackets += 1;
}
}
outer_output_string += ")";
idx += 1;
} else {
outer_output_string += user_input_string[idx];
idx += 1;
}
}
return {
outer_string: outer_output_string,
mm_args_string: mm_args_string
};
}
/**
* @param mm_args_string
* @returns {{distrs: [], weights: string}}
*/
function separate_mm_args(mm_args_string) {
if (mm_args_string.endsWith(",")) {
mm_args_string = mm_args_string.slice(0, -1);
}
let args_array = [];
let num_open_brackets = 0;
let arg_substring = "";
for (let char of mm_args_string) {
if (num_open_brackets === 0 && char === ",") {
args_array.push(arg_substring.trim());
arg_substring = "";
} else {
if (char === ")" || char === "]") {
num_open_brackets -= 1;
} else if (char === "(" || char === "[") {
num_open_brackets += 1;
}
arg_substring += char;
}
}
return {
distrs: args_array,
weights: arg_substring.trim()
};
}
/**
* @param distr_string
* @returns {[]}
*/
function get_distr_substrings(distr_string) {
let substrings = [];
for (let regex of DISTR_REGEXS) {
let matches = distr_string.matchAll(regex);
for (let match of matches) {
let idx = match.index + match[0].length;
let num_open_brackets = 1;
let distr_substring = "";
while (num_open_brackets !== 0 && idx < distr_string.length) {
distr_substring += distr_string[idx];
if (distr_string[idx] === "(") {
num_open_brackets += 1;
} else if (distr_string[idx] === ")") {
num_open_brackets -= 1;
}
idx += 1;
}
substrings.push((match[0] + distr_substring).trim());
}
}
return substrings;
}
/**
* @param substr
* @returns {(string|*)[]}
*/
function get_distr_name_and_args(substr) {
let distr_name = "";
let args_str = "";
let args_flag = false;
for (let char of substr) {
if (!args_flag && char !== "(") {
distr_name += char;
}
if (args_flag && char !== ")") {
args_str += char;
}
if (char === "(") {
args_str += "[";
args_flag = true;
}
}
args_str += "]";
let args = math.compile(args_str).evaluate()._data;
return [distr_name, args];
}
exports.get_distr_name_and_args = get_distr_name_and_args;
exports.get_distr_substrings = get_distr_substrings;
exports.separate_mm_args = separate_mm_args;
exports.parse_initial_string = parse_initial_string;