如何扩展默认的 PEG.js 算术示例以允许多个表达式而不是单个表达式? [英] How to extend default PEG.js arithmetic example to allow multiple expressions not single one?

查看:57
本文介绍了如何扩展默认的 PEG.js 算术示例以允许多个表达式而不是单个表达式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为解析器的一部分,我想添加算术和布尔表达式.我想在 https://pegjs.org/online 上采用默认的 PEG.js 示例,但问题是那个解析器是递归的,你不能写两行或更多行:

As part of my parser I want to add arithmetic and boolean expressions. I wanted to take default PEG.js example at https://pegjs.org/online but the problem is that that parser is recursive and you can't write two or more lines:

例如这是有效的 JavaScript:

For instance this is valid JavaScript:

2 * (3 + 4)
2 * (3 + 4)
2 * (3 + 4)
  + 10

如您所见,有 3 个表达式,行尾不会终止它们.但是对于 PEG.js,它们需要显式编码,以便表达式可以终止.

as you can see there are 3 expressions and end of the line don't terminate them. But with PEG.js they need to be explicitly encoded, so the expression can terminate.

你会如何去创建这样的无限表达式,终止并转到下一个表达式?

How would you go and create infinite expressions like this, that terminate and go to next expression?

推荐答案

您可以为多个表达式添加如下的 Start 规则.

You could add a Start rule like the following for multiple expressions.

Start
  = head:Expression tail:("\n" Expression)* {
    return [head].concat(tail.map(function(element) {
      return element[1];
    }));
  }

Expression
  = head:Term tail:(_ ("+" / "-") _ Term)* {
      return tail.reduce(function(result, element) {
        if (element[1] === "+") { return result + element[3]; }
        if (element[1] === "-") { return result - element[3]; }
      }, head);
    }

Term
  = head:Factor tail:(_ ("*" / "/") _ Factor)* {
      return tail.reduce(function(result, element) {
        if (element[1] === "*") { return result * element[3]; }
        if (element[1] === "/") { return result / element[3]; }
      }, head);
    }

Factor
  = "(" _ expr:Expression _ ")" { return expr; }
  / Integer

Integer "integer"
  = _ [0-9]+ { return parseInt(text(), 10); }

_ "whitespace"
  = [ \t\n\r]*

这篇关于如何扩展默认的 PEG.js 算术示例以允许多个表达式而不是单个表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆