Javascript 为什么生成的解析器如此之慢?

Javascript 为什么生成的解析器如此之慢?,javascript,parsing,logic,peg,Javascript,Parsing,Logic,Peg,我在PEG.js上玩游戏,试图创建一个能够获取字符串并创建对象的解析器 例如,以字符串“a&b”为例,创建: {type:"operator",value:operator, children:[a, b]} 但是,如果有两个或更多的巢穴,返回结果可能需要10秒以上 我一直使用的测试参数是: (All a (All a (All a b))) 语法确实会返回正确答案,但耗时太长。我的问题是,是什么导致了这样一个简单的解析的时间延迟 可以在以下位置尝试在线编辑语法: 我的语法是: start=

我在
PEG.js上玩游戏,试图创建一个能够获取字符串并创建对象的解析器

例如,以字符串“a&b”为例,创建:

{type:"operator",value:operator, children:[a, b]}
但是,如果有两个或更多的巢穴,返回结果可能需要10秒以上

我一直使用的测试参数是:

(All a (All a (All a b)))
语法确实会返回正确答案,但耗时太长。我的问题是,是什么导致了这样一个简单的解析的时间延迟

可以在以下位置尝试在线编辑语法:

我的语法是:

start=sep*All:All sep*{return All}
All=sep*运算符:“All”sep*xValue:Ex-sep*pValue:Ex{return{type:“operator”,value:operator,children:[xValue,pValue]}}/Ex
Ex=sep*运算符:“Ex”sep*xValue:和sep*pValue:和{return{type:“operator”,value:operator,children:[xValue,pValue]}}和
AND=left:Plus sep*运算符:&“sep*right:AND{return{type:“operator”,value:operator,children:[left,right]}/Plus
Plus=left:Equals sep*运算符:“+”sep*right:Plus{return{type:“operator”,value:operator,children:[left,right]}/Equals
Equals=left:GEQ sep*运算符:“=”sep*right:Equals{return{type:“operator”,value:operator,children:[left,right]}/GEQ
GEQ=left:implication sep*运算符:“>=”sep*right:GEQ{return{type:“operator”,value:operator,children:[left,right]}/implication
implication=left:或sep*运算符:“->”sep*right:implication{return{type:“operator”,value:operator,children:[左,右]}或
OR=left:Not sep*运算符:“|”sep*right:或{return{type:“operator”,value:operator,children:[left,right]}/Not
Not=sep*运算符:“,”sep*右侧:Suc{return{type:“运算符”,值:运算符,子项:[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=空格:['',\\t]
letter=“false”/“0”/letters:[A-Za-z]

我猜这与你所有的
sep*
s有关。如果你看看布莱恩·福特(Bryan Ford)最初的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]*

PEG是一个回溯解析器;它将尝试多种备选方案,寻找一种可行的方案。你可能是在回溯死亡。