gpt4 book ai didi

javascript - 将正则表达式转换为 PegJs 语法

转载 作者:行者123 更新时间:2023-12-03 04:36:35 25 4
gpt4 key购买 nike

我是 PEGjs 新手,我正在尝试编写 PEGjs 语法转换正则表达式 (\s*[\(])|(\s*[\)])|(\"[^\(\)]+?\")|([^\(\)\s]+) 语法。

基本上我想做的是转换测试输入

(App= smtp AND "SPort"!= 25) OR (App= pop3 AND "SPort"!= 110) OR (App = imap AND "SPort"!= 143) AND (App= imap OR “运动”!= 143)

转换成如下的json格式

{
"eventTypes": [
"All"
],
"condition": {
"operator": "and",
"terms": [
{
"operator": "or",
"terms": [
{
"operator": "or",
"terms": [
{
"operator": "and",
"terms": [
{
"name": "App",
"operator": "equals",
"value": "smtp"
},
{
"name": "Sport",
"operator": "notEquals",
"value": "25"
}
]
},
{
"operator": "and",
"terms": [
{
"name": "App",
"operator": "equals",
"value": "pop3"
},
{
"name": "Sport",
"operator": "notEquals",
"value": "110"
}
]
}
]
},
{
"operator": "and",
"terms": [
{
"name": "App",
"operator": "equals",
"value": "imap"
},
{
"name": "Sport",
"operator": "notEquals",
"value": "143"
}
]
}
]
},
{
"operator": "or",
"terms": [
{
"name": "App",
"operator": "equals",
"value": "imap"
},
{
"name": "Sport",
"operator": "notEquals",
"value": "143"
}
]
}
]
}
}

我编写了一些复杂的 javascript 代码来将示例输入转换为 JSON 格式,但代码有点复杂,并且从长远来看不容易维护,所以我想尝试一下语法解析器。由于我是语法世界的新手,我寻求一些帮助或指导来实现执行上述操作的语法,以便我可以根据需要增强/编写?

You can see the output of the Regex here

编辑

Javascript解决方案:

 var str = '((Application = smtp AND "Server Port" != 25) AND (Application = smtp AND "Server Port" != 25)) OR (Application = pop3 AND "Server Port" != 110) OR (Application = imap AND "Server Port" != 143) AND (Application = imap OR "Server Port" != 143)';

var final = str.replace(/\((?!\()/g,"['") //replace ( with [' if it's not preceded with (
.replace(/\(/g,"[") //replace ( with [
.replace(/\)/g,"']") //replace ) with ']
.replace(/\sAND\s/g,"','AND','") //replace AND with ','AND','
.replace(/\sOR\s/g,"','OR','") //replace OR with ','OR','
.replace(/'\[/g,"[") //replace '[ with [
.replace(/\]'/g,"]") //replace ]' with ]
.replace(/"/g,"\\\"") //escape double quotes
.replace(/'/g,"\""); //replace ' with "
console.log(JSON.parse("["+final+"]"))

最佳答案

据我所知,您无法准确获得您想要的结果,因为它需要无限循环。具体来说,给定以下输入:

A OR B OR C

您要求此输出:

(A OR B) OR C

要获得此结果,您需要有这样的规则:

BOOL = left:( BOOL / Expression ) "OR" right:( Expression )

这会造成无限循环,因为 BOOL 永远无法解析。 BOOL 无法解析,因为 BOOL 中的第一条规则是匹配 BOOL。然而,我们可以得到

A OR ( B OR C )

因为

BOOL = left:( Expression ) "OR" right:( BOOL / Expression )

不会创建无限循环。这是因为我们可以在递归回 BOOL 之前开始匹配某些东西。我知道这有点令人兴奋,但相信我...在递归之前,您必须有一些东西让 PegJS 开始匹配。

如果这是可以接受的,那么我相信这个语法将使您非常接近所需的输出:

// Our top-level rule is Expression
Expression
= BOOL
/ SubExpression
/ Comparison
/ Term

// A sub expression is just an expression wrapped in parentheses
// Note that this does not cause an infinite loop because the first term is always "("
SubExpression
= _ "(" _ innards: Expression _ ")" _ { return innards; }

Comparison
= name:Term _ operator:("=" / "!=") _ value:Term {
return {
name: name,
operator: operator === '=' ? 'equals' : 'notEquals',
value: value,
};
}

BOOL = AND / OR

// We separate the AND and OR because we want AND to take precendence over OR
AND
= _ left:( OR / SubExpression / Comparison ) _ "AND" _ right:( AND / OR / SubExpression / Comparison ) _ {
return {
operator: 'and',
terms: [ left, right ]
}
}

OR
= _ left:( SubExpression / Comparison ) _ "OR" _ right:( OR / SubExpression / Comparison ) _ {
return {
operator: 'or',
terms: [ left, right ]
}
}

Term
= '"'? value:$( [0-9a-zA-Z]+ ) '"'? {
return value;
}

Integer "integer"
= _ [0-9]+ { return parseInt(text(), 10); }

_ "whitespace"
= [ \t\n\r]*

根据您的输入,我们会得到:

{
"operator": "and",
"terms": [
{
"operator": "or",
"terms": [
{
"operator": "and",
"terms": [
{
"name": "App",
"operator": "equals",
"value": "smtp"
},
{
"name": "SPort",
"operator": "notEquals",
"value": "25"
}
]
},
{
"operator": "or",
"terms": [
{
"operator": "and",
"terms": [
{
"name": "App",
"operator": "equals",
"value": "pop3"
},
{
"name": "SPort",
"operator": "notEquals",
"value": "110"
}
]
},
{
"operator": "and",
"terms": [
{
"name": "App",
"operator": "equals",
"value": "imap"
},
{
"name": "SPort",
"operator": "notEquals",
"value": "143"
}
]
}
]
}
]
},
{
"operator": "or",
"terms": [
{
"name": "App",
"operator": "equals",
"value": "imap"
},
{
"name": "SPort",
"operator": "notEquals",
"value": "143"
}
]
}
]
}

关于javascript - 将正则表达式转换为 PegJs 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43269126/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com