Skip to content

Instantly share code, notes, and snippets.

@s-yoshiki
Created November 15, 2020 08:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save s-yoshiki/9a0ff8ebef6e5cc2a41a872f8e741348 to your computer and use it in GitHub Desktop.
Save s-yoshiki/9a0ff8ebef6e5cc2a41a872f8e741348 to your computer and use it in GitHub Desktop.
PEG math parser
{
function filledArray(count, value) {
var result = new Array(count), i;
for (i = 0; i < count; i++) {
result[i] = value;
}
return result;
}
function extractOptional(optional, index) {
return optional ? optional[index] : null;
}
function extractList(list, index) {
var result = new Array(list.length), i;
for (i = 0; i < list.length; i++) {
result[i] = list[i][index];
}
return result;
}
function buildList(head, tail, index) {
return [head].concat(extractList(tail, index));
}
function buildTree(head, tail, builder) {
var result = head, i;
for (i = 0; i < tail.length; i++) {
result = builder(result, tail[i]);
}
return result;
}
function optionalList(value) {
return value !== null ? value : [];
}
}
Expression
= head:Term tail:(_ ("+" / "-") _ Term)* {
var result = head, i;
for (i = 0; i < tail.length; i++) {
if (tail[i][1] === "+") { result += tail[i][3]; }
if (tail[i][1] === "-") { result -= tail[i][3]; }
}
return result;
}
Term
= head:Factor tail:(_ ("*" / "/") _ Factor)* {
var result = head, i;
for (i = 0; i < tail.length; i++) {
if (tail[i][1] === "*") { result *= tail[i][3]; }
if (tail[i][1] === "/") { result /= tail[i][3]; }
}
return result;
}
/*
* (2)関数 functionを先頭に追加
*/
Factor
= function
/ "(" _ expr:Expression _ ")" { return expr; }
/ Num
Num
= _ head:[0-9]+ tail:('.' [0-9]+)? _ {
var result = head.join('');
if (tail && tail[1]) {
result += '.' + tail[1].join('');
}
return parseFloat(result);
}
_ "whitespace"
= [ \t\n\r]*
/*
* (3)識別子
*/
identifier
= [A-Za-z_][A-Za-z0-9_]+ { return text(); }
const
= identifier
/ "PI"+ { return 3; }
/ Num
/*
* (4)パラメータリスト
*/
ParameterList
= head:Expression tail:( _ "," _ Expression )* {
var ret = buildList(head,tail,3)
return ret;
}
/*
* (5)関数追加(複数パラメータ対応)
*/
function
= func:identifier _ "(" _ params:ParameterList? _ ")" {
const funcName = func.toLowerCase();
// 関数実行処理
switch(funcName) {
case "sum" : // sum関数を実行
if (params == null) {
alert("パラメータがありません:sum")
}
return params.reduce(function(l,r) { return l + r })
default :
return 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment