簡體   English   中英

PEGjs 中的條件語法規則

[英]Conditional grammar rule in PEGjs

我正在嘗試實現一個解析基本算術表達式的簡單 DSL。 這需要在瀏覽器中完成,所以我使用 PEGjs 來生成解析器。

表達式中的術語可以是數字(整數或實數)、變量(變量是傳遞給解析器的上下文對象上的屬性)、條件或通過點表示法訪問的屬性。

我希望條件看起來像這個condition?value ,如果condition為真,則該術語等於value ?兩側的變量? 也可以是像這樣object.property1?object.property2這樣的對象的點符號訪問屬性。

因此,如果解析器傳遞了一個像這樣的對象:

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

表達方式:

500 + depth + material.include?edge.face + material.thickness應該等於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 repo 中查看了 javascript 的示例語法,條件規則看起來很像我在這里得到的,但我仍然無法讓它工作。

實現像我在 PEGjs 規則中描述的那樣的條件語句的正確方法是什么?

我知道這有點晚了,但問題是您的variable是一個評估為"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
    }

請注意,此解決方案並不完整,因為如果您嘗試訪問material.include ,其中material從未在您的上下文中定義,則會導致錯誤。 您可能想要添加額外的錯誤處理,但它確實適用於給定的示例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM