Javascript PEGJS:为谓词优先语法生成AST
我又回到了探索pegjs,显然还没有掌握核心概念。我试图解析一种“查询语言”,它首先是一个谓词,然后是一个操作数列表(可能包含另一个谓词)。因此,一个简单的例子是:Javascript PEGJS:为谓词优先语法生成AST,javascript,parsing,grammar,abstract-syntax-tree,pegjs,Javascript,Parsing,Grammar,Abstract Syntax Tree,Pegjs,我又回到了探索pegjs,显然还没有掌握核心概念。我试图解析一种“查询语言”,它首先是一个谓词,然后是一个操作数列表(可能包含另一个谓词)。因此,一个简单的例子是: OR( "string1" "string2" ) 我希望将上述内容转换为: { predicate: "OR", operands: [ { type: "STRING", value: "string1" },
OR(
"string1"
"string2"
)
我希望将上述内容转换为:
{
predicate: "OR",
operands: [
{
type: "STRING",
value: "string1"
},
{
type: "STRING",
value: "string2"
}
]
}
此查询:
OR(
"string1"
"string2"
AND (
"string4"
"string5"
)
"string3"
)
将变成这样:
{
predicate: "OR",
operands: [
{
type: "STRING",
value: "string1"
},
{
type: "STRING",
value: "string2"
},
{
predicate: "AND"
operands: [
{
type: "STRING",
value: "string4"
},
{
type: "STRING",
value: "string5"
}
]
},
{
type: "STRING",
value: "string3"
}
]
}
我的语法很接近,但有几个问题。下面是当前的PEGJS语法。它可以直接粘贴到在线pegjs解析器()
上面的语法处理了我给出的两个例子,但我注意到了两个问题,这就引出了下面三个问题
1.语法在这个看似简单的输入上失败(关键是嵌套或紧跟在父或之后,并且“字符串”在末尾):
我不知道是什么原因造成的,也不知道如何修复
2.语法当前对操作数
规则有以下愚蠢的行:
operand =
string
/ ws or_predicate:or_predicate { return or_predicate; }
注意或\u谓词
前面第三行的前导空格(ws)。如果没有空白,我会得到错误“超过了最大调用堆栈大小”。我认为这与左递归有关,但不是正面的。理想情况下,我希望那里没有必需的“ws”,这样一个没有空格的查询就可以工作了:
OR("string1"OR("string2")"string3")
现在,您必须人为地添加一些额外的空格,如下所示:
OR("string1" OR("string2") "string3")
3.我是否完全错误地理解了这个语法?这只是我尝试的第二个,第一个是基于pegjs算术示例的,所以我意识到我可能完全错了,这可能就是我遇到这些问题的原因
感谢您的帮助和时间
致以最良好的祝愿
Ed我对PEG也很陌生,但你主要是在看了文档而不是阅读了文档之后才掌握了窍门 尝试将您的版本与此版本进行比较:
start
= ws* predicate:predicate ws* { return predicate; }
predicate
= "OR" ws* "(" operands:operand+ ")" { return { predicate: 'OR', operands: operands }; }
/ "AND" ws* "(" operands:operand+ ")" { return { predicate: 'AND', operands: operands }; }
operand
= ws* predicate:predicate ws* { return predicate; }
/ ws* string:string ws* { return string; }
string
= "\"" chars:valid_variable_characters+ "\"" { return { type: "STRING", value: chars.join("")}}
valid_variable_characters = [a-zA-Z0-9 _]
ws = [ \t\n]
空格是可选的
OR("str1"OR("str2""str3"AND("str4""str5"))"str6")
给出:
{
"predicate": "OR",
"operands": [
{
"type": "STRING",
"value": "str1"
},
{
"predicate": "OR",
"operands": [
{
"type": "STRING",
"value": "str2"
},
{
"type": "STRING",
"value": "str3"
},
{
"predicate": "AND",
"operands": [
{
"type": "STRING",
"value": "str4"
},
{
"type": "STRING",
"value": "str5"
}
]
}
]
},
{
"type": "STRING",
"value": "str6"
}
]
}
哇,非常感谢。我可以用你的例子作为基础,并从那里建立起来。这太棒了!
OR("str1"OR("str2""str3"AND("str4""str5"))"str6")
{
"predicate": "OR",
"operands": [
{
"type": "STRING",
"value": "str1"
},
{
"predicate": "OR",
"operands": [
{
"type": "STRING",
"value": "str2"
},
{
"type": "STRING",
"value": "str3"
},
{
"predicate": "AND",
"operands": [
{
"type": "STRING",
"value": "str4"
},
{
"type": "STRING",
"value": "str5"
}
]
}
]
},
{
"type": "STRING",
"value": "str6"
}
]
}