我正在PEG.js
上玩,试图创建一个能够获取字符串并创建对象的解析器。
例如,取字符串“a& b”并创建:
{type:"operator",value:operator, children:[a, b]}
但是,如果有两个或更多巢,我已经到达了返回结果可能需要10秒以上的阶段。
我一直在使用的测试论点是:
(All a (All a (All a b)))
语法确实会返回正确的答案,但需要的时间太长。我的问题是,导致这种简单解析的时间延迟是什么原因?
可以在PEG.js
在线尝试编辑语法我的语法是:
start = sep* All:All sep* {return All}
All = sep* operator:"All" sep* xValue: Ex sep* pValue: Ex{return {type:"operator",value:operator, children:[xValue, pValue]}} /Ex
Ex = sep* operator:"Ex" sep* xValue: AND sep* pValue: AND {return {type:"operator",value:operator, children:[xValue, pValue]}} /AND
AND= left: Plus sep* operator:"&" sep* right:AND {return {type:"operator", value:operator, children:[left,right]}} / Plus
Plus = left: Equals sep* operator:"+" sep* right:Plus{return {type:"operator", value:operator, children:[left,right]}}/ Equals
Equals = left:GEQ sep* operator:"=" sep* right:Equals{return {type:"operator", value:operator, children:[left,right]}}/GEQ
GEQ = left:implication sep* operator:">=" sep* right:GEQ{return {type:"operator", value:operator, children:[left,right]}}/implication
implication = left:OR sep* operator:"->" sep* right:implication{return {type:"operator", value:operator, children:[left,right]}}/OR
OR = left:Not sep* operator:"|" sep* right:OR{return {type:"operator", value:operator, children:[left,right]}}/Not
Not = sep* operator:"¬" sep* right:Suc{return {type:"operator", value:operator, children:[right]}}/Suc
Suc = sep* operator:"suc" sep* right:primary{return {type:"operator", value:operator, children:[right]}}/primary
primary = letter:letter{return {type:"variable", value:letter}}/ "{" sep* All:All sep* "}" {return All}/"(" sep* All:All sep* ")" {return All}
sep = spaces:[' ',\\t]
letter = "false"/"0"/letters:[A-Za-z]
答案 0 :(得分:0)
我猜这与你的所有sep*
有关。如果你看看布莱恩福特最初的PEG论文中的例子,那么以白色空间开头的唯一规则是第一个。然后,他逻辑上打破了他的语法,使词汇部分(标记规则)位于底部,每个标记定义后跟空格。我认为它会解决你的问题,但即使它没有,它也会使它更具可读性(并且可能更容易修复)。
例如:
start = SPACING All:All
All = operator:All_op xValue:Ex pValue: Ex
/ Ex
Ex = operator:Ex_op xValue:AND pValue:AND
/* etc. */
/* Lexical Portion */
All_op = 'All' SPACING
Ex_op = 'Ex' SPACING
SPACING = [ \t]*