javascript - PEGjs中的条件语法规则

标签 javascript parsing grammar pegjs

我正在尝试实现一个简单的 DSL 来解析基本算术表达式。这需要在浏览器中完成,因此我使用 PEGjs 来生成解析器。

表达式中的术语可以是数字(整数或实数)、变量(变量是传递给解析器的上下文对象的属性)、条件或通过点表示法访问的属性。

我希望条件看起来像这样 condition?value,其中如果 condition 为 true,则该术语等于 value? 两侧的变量也可以是点符号访问的对象属性,如 object.property1?object.property2

因此,如果解析器传递一个像这样的对象:

context = {
  depth: 100,
  material: {
    thickness: 20
    include: true
  }
  edge: {
    face: 4.5
  }
}

表达式:

500 + 深度 + Material .include?edge.face + Material .厚度 应等于 624.5

我一直在使用PEGjs在线编辑器。我尝试了很多不同的方法,但我似乎无法确定条件。其他一切都有效。相关规则如下:

Variable "variable"
  = variable:identifier accessor:("." identifier)* {
      var result = context[variable], i

      for (i = 0; i < accessor.length; i++) {
        result = result[accessor[i][1]]
      }

      return result
    }

identifier
  = identifier:$([0-9a-zA-Z_\$]+)

Conditional
  = condition:Variable "?" value:Variable {
    return condition ? value : 0
  }

我已经查看了 PEGjs github 存储库中的 javascript 示例语法,条件规则看起来很像我在这里得到的,但我仍然无法让它工作。

实现条件语句(如我在 PEGjs 规则中描述的条件语句)的正确方法是什么?

最佳答案

我知道这有点晚了,但问题是您的变量是一个评估为“material.include”的字符串。

看看这段代码:

var result = context[variable], i

您正在尝试从上下文对象访问名为“material.include”的属性,该属性如下所示:

{
    "material.include": true
}

而不是尝试访问“material”属性引用的对象,然后访问结果对象的“include”属性,如下所示:

{
    "material": {
        "include": true
    }
}

解决方案是将变量字符串按 "." 字符拆分,然后递归查找您的属性:

Variable "variable"
  = variable:identifier accessor:("." identifier)* {
      var path = variable.split(".");
      var result = path.reduce( (nextObject, propName) => nextObject[propName], context );

      for (var i = 0; i < accessor.length; i++) {
        result = result[accessor[i][1]]
      }

      return result
    }

请注意,此解决方案并不完整,因为如果您尝试访问从未在上下文中定义过 materialmaterial.include,则会导致错误。您可能想要添加额外的错误处理,但它确实适用于给定的示例。

关于javascript - PEGjs中的条件语法规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41234164/

相关文章:

javascript - 如何创建云图?

c - 使用 Bison 解析错误

PHP HTML DOM 解析器从 img 标签中选择 alt

javascript - 是否可以计算用户加入之间的秒数?

javascript - 将下拉菜单放置在菜单标题的正下方

javascript - 是否有一个javascript来检查另一个脚本是否已被激活?

c# - 如何正确解析 SQL CREATE TABLE 语句

c - 链表 vector 无法正常工作

regex - 将正则表达式转换为常规语法/右线性语法

php - 未转义的美元符号不会引发错误; PHP 处理边缘情况?