PEGjs:请求 Help/guide 定义算术函数
PEGjs: Request Help/guide in defining Arithmetic functions
我正在学习 PEGjs 语法,我请求以下方面的帮助或指导:
我有这样的功能,PRODUCT(), SUM(), DIVIDE()
PRODUCT 可以将数字/PRODUCT()/SUM()/DIVIDE(
) 作为参数(除逗号分隔外的任何数字)
ex: PRODUCT(2, 5, SUM(5, 6, 7), DIVIDE(5, 2), PRODUCT(4, 6, 20, 12))
SUM 可以采用以逗号分隔的任意数量的参数。
Ex: SUM(4, 5, 10, DIVIDE(SUM(2, 5, 6), 3))
DIVIDE 将采用两个参数(必须有 2 个),数字或其他函数
Ex: DIVIDE(3, PRODUCT(3, 4, SUM(2, 3)))
有人可以帮助或指导我如何实现吗?
我目前的规则
start = sum
/multiply
multiply = "PRODUCT("a:digit "," __ b:digit ")" {return a * b}
sum = "SUM("a:digit "," b:digit ")" {return a + b}
digit = [0-9]
__ = WhiteSpace*
WhiteSpace "whitespace"
= [ \t\r\n]
以上规则只支持product/sum两个号码。我怎样才能实现上述目标?
提前致谢
曼朱纳斯·雷迪
好的开始,但您需要弄清楚如何解析参数列表并进行更多递归。
我发现最好的学习方法是通过示例 (https://github.com/pegjs/pegjs/tree/master/examples)。
在 online editor 试试这个:
start
= sum
/ multiply
/ divide
multiply
= "PRODUCT(" _ args:arguments _ ")" { return args.reduce(function(a,b) {return a*b;}); }
sum
= "SUM(" _ args:arguments _ ")" { return args.reduce(function(a,b) {return a+b;}); }
divide
= "DIVIDE(" _ dividend:argument _ "," _ divisor:argument _ ")" { return dividend / divisor; }
arguments
= first:argument rest:(_ ',' _ arg:argument { return arg; })* { return [first].concat(rest); }
argument
= multiply
/ sum
/ divide
/ number
number
= digits:(digit)+ { return parseInt(digits.join(''), 10); }
digit = [0-9]
_ "optionalWhitespace"
= whitespace *
whitespace
= [ \t\n\r]+
示例:
PRODUCT(2, 5, SUM(5, 6, 7), DIVIDE(5, 2), PRODUCT(4, 6, 20, 12))
2592000
SUM(4, 5, 10, DIVIDE(SUM(2, 5, 6), 3))
23.333333333333332
DIVIDE(3, PRODUCT(3, 4, SUM(2, 3)))
0.05
一般来说,如果你想解析一个无界列表,比如
1, 2, 3, 4
您可以创建递归规则如下:
args = head:Integer rest:(_ "," _ r:args{ return r; })? {
return rest != null ? [head].concat(rest) : [head];
}
Integer = [0-9]+ { return parseInt(text(), 10); }
_ = [ \t\n\r]*
我正在学习 PEGjs 语法,我请求以下方面的帮助或指导:
我有这样的功能,PRODUCT(), SUM(), DIVIDE()
PRODUCT 可以将数字/PRODUCT()/SUM()/DIVIDE(
) 作为参数(除逗号分隔外的任何数字)
ex: PRODUCT(2, 5, SUM(5, 6, 7), DIVIDE(5, 2), PRODUCT(4, 6, 20, 12))
SUM 可以采用以逗号分隔的任意数量的参数。
Ex: SUM(4, 5, 10, DIVIDE(SUM(2, 5, 6), 3))
DIVIDE 将采用两个参数(必须有 2 个),数字或其他函数
Ex: DIVIDE(3, PRODUCT(3, 4, SUM(2, 3)))
有人可以帮助或指导我如何实现吗?
我目前的规则
start = sum
/multiply
multiply = "PRODUCT("a:digit "," __ b:digit ")" {return a * b}
sum = "SUM("a:digit "," b:digit ")" {return a + b}
digit = [0-9]
__ = WhiteSpace*
WhiteSpace "whitespace"
= [ \t\r\n]
以上规则只支持product/sum两个号码。我怎样才能实现上述目标?
提前致谢 曼朱纳斯·雷迪
好的开始,但您需要弄清楚如何解析参数列表并进行更多递归。
我发现最好的学习方法是通过示例 (https://github.com/pegjs/pegjs/tree/master/examples)。
在 online editor 试试这个:
start
= sum
/ multiply
/ divide
multiply
= "PRODUCT(" _ args:arguments _ ")" { return args.reduce(function(a,b) {return a*b;}); }
sum
= "SUM(" _ args:arguments _ ")" { return args.reduce(function(a,b) {return a+b;}); }
divide
= "DIVIDE(" _ dividend:argument _ "," _ divisor:argument _ ")" { return dividend / divisor; }
arguments
= first:argument rest:(_ ',' _ arg:argument { return arg; })* { return [first].concat(rest); }
argument
= multiply
/ sum
/ divide
/ number
number
= digits:(digit)+ { return parseInt(digits.join(''), 10); }
digit = [0-9]
_ "optionalWhitespace"
= whitespace *
whitespace
= [ \t\n\r]+
示例:
PRODUCT(2, 5, SUM(5, 6, 7), DIVIDE(5, 2), PRODUCT(4, 6, 20, 12))
2592000
SUM(4, 5, 10, DIVIDE(SUM(2, 5, 6), 3))
23.333333333333332
DIVIDE(3, PRODUCT(3, 4, SUM(2, 3)))
0.05
一般来说,如果你想解析一个无界列表,比如
1, 2, 3, 4
您可以创建递归规则如下:
args = head:Integer rest:(_ "," _ r:args{ return r; })? {
return rest != null ? [head].concat(rest) : [head];
}
Integer = [0-9]+ { return parseInt(text(), 10); }
_ = [ \t\n\r]*