[英]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.