Created
November 15, 2020 08:48
-
-
Save s-yoshiki/9a0ff8ebef6e5cc2a41a872f8e741348 to your computer and use it in GitHub Desktop.
PEG math parser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
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