我又回到了探索pegjs,显然还没有掌握核心概念。我试图解析一个以谓词开头的“查询语言”,然后解析一个操作数列表(可以包含另一个谓词)。因此,一个简单的例子是:
OR(
"string1"
"string2"
)我希望将上述内容转化为:
{
predicate: "OR",
operands: [
{
type: "STRING",
value: "string1"
},
{
type: "STRING",
value: "string2"
}
]
}此查询:
OR(
"string1"
"string2"
AND (
"string4"
"string5"
)
"string3"
)会变成这样的AST:
{
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解析器(http://pegjs.majda.cz/online)中。
start =
or_predicate
or_predicate
= ws* "OR" ws* "(" ws* operands:or_predicate ws* ")" ws*
{ if(Array.isArray(operands)) {
return {predicate: "OR", operands: operands}
} else {
return {predicate: "OR", operands: [operands] }
}
}
/ and_predicate
and_predicate
= ws* "AND" ws* "(" operands:and_predicate ")"
{ if(Array.isArray(operands)) {
return {predicate: "AND", operands: operands}
} else {
return {predicate: "AND", operands: [operands] }
}
}
/ operands
operands
= ws* values:operand+ { return values; }
operand =
string
/ ws or_predicate:or_predicate { return or_predicate; }
string =
ws* "\"" value:valid_variable_characters "\""
{ return { type: "STRING", value: value.join("")}}
// List of valid characters for string variables
valid_variable_characters =
[a-zA-Z0-9 _]+
ws =
[ \t\n]上面的语法处理了我给出的两个例子,但我注意到了两个问题,这就引出了以下三个问题。
1.语法在这个看似简单的输入上失败(关键是嵌套OR紧跟在父OR之后,"string“在末尾):
OR(
OR (
"string1"
)
"string2"
)我不知道是什么导致了这件事,也不知道如何解决。
2.语法中目前有一条用于operand规则的愚蠢行:
operand =
string
/ ws or_predicate:or_predicate { return or_predicate; }注意or_predicate前第三行的前导空格(ws)。如果没有这个空格,我就会得到错误“超过最大调用堆栈大小”。我认为这与左递归有关,但并不是肯定的。理想情况下,我希望能够在那里没有必需的'ws‘,这样一个没有空格的查询就能工作:
OR("string1"OR("string2")"string3")现在,您必须人为地添加一些额外的空格,如下所示:
OR("string1" OR("string2") "string3")3.我是否完全不正确地理解这个语法?这只是我尝试的第二次,第一次是基于pegjs的算术例子,所以我意识到我可能做的完全错误,这可能是我遇到这些问题的原因。
感谢您的帮助和时间!
诚挚的问候,
边缘
发布于 2015-03-12 11:53:43
我对聚乙二醇也很陌生,但是在主要看示例而不是阅读文档之后,您就掌握了它的诀窍。
尝试将您的版本与此版本进行比较:
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"
}
]
}https://stackoverflow.com/questions/28976751
复制相似问题