PEGjs:请求帮助/指南定义算术函数

时间:2015-11-16 16:15:50

标签: javascript context-free-grammar pegjs

我正在学习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]

以上规则仅支持两个数字的产品/总和。我怎样才能实现上述目标?

先谢谢 Manjunath Reddy

2 个答案:

答案 0 :(得分:1)

良好的开端,但你需要弄清楚如何解析参数列表并进行更多的递归。

我发现最好的学习方法是通过例子(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 :(得分:1)

通常,如果要解析无界列表,例如

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]*