正则表达式递归JSL是否支持递归正则表达式?
我试过了?R和 \ g <0>它们似乎都不起作用。
regex("test(1, (2, 3));", "\(([^()]|(?R))*\");Re:正则表达式递归几分钟后维基百科给出一组没有左递归的规则......运行速度快。
text = "(1+2)*(3+4+5)*6*7*8*21*(0+(1+(2*3))+4*(5+6)*7*8+(((12+13+14)*15+16+17)*18+19+20))*22"; // plus, star, paren, integer. pattern does not handle spaces.
stack = {}; // the "working" stack... holds the RPN numbers
// the following add and mul routines pop two numbers and push the result...
addstack = Function( {},
{num1 = Num( Remove From( stack )[1] ), num2 = Num( Remove From( stack )[1] )},
Insert Into( stack, Char( num1 + num2 ) )
);
mulstack = Function( {},
{num1 = Num( Remove From( stack )[1] ), num2 = Num( Remove From( stack )[1] )},
Insert Into( stack, Char( num1 * num2 ) )
);
dummy = {}; // dummy variable with a subscript that will evaluate as needed
// BNF-like grammar of Expression, Term, Factor, Constant
// >? is the conditional assignment from LHS to RHS. The >>
// immediate assignment will not work because of back-up and retry
// which would push incorrect items to stack. The RHS of the >? is either
// the dummy[] list or working stack. The dummy stack reference uses the
// calculation of its subscript to manipulate the working stack.
// As the grammar/pattern runs, the expression is evaluated.
/*
E = (Expr( T ) + "+" + Expr( E )) >? dummy[addstack(); 1] | Expr( T );
T = (Expr( T ) + "*" + Expr( F )) >? dummy[mulstack(); 1] | Expr( F );
F = ("(" + Expr( E ) + ")") | Expr( C );
C = Pat Span( "0123456789" ) >? stack[N Items( stack ) + 1];
*/
// re-written without left recursion
// https://en.wikipedia.org/wiki/Left_recursion#Removing_left_recursion
//
E = Expr( T ) + Expr( EP );
EP = ("+" + Expr( T ) >? dummy[addstack(); 1] + Expr( EP )) | "";
T = Expr( F ) + Expr( TP );
TP = ("*" + Expr( F ) >? dummy[mulstack(); 1] + Expr( TP )) | "";
F = ("(" + Expr( E ) + ")") | Expr( C );
C = Pat Span( "0123456789" ) >? stack[N Items( stack ) + 1];
rc = Pat Match( text, Pat Pos( 0 ) + E + Pat R Pos( 0 ), NULL, FULLSCAN );
If( rc,
Show( rc, Num( stack[1] ), Eval( Parse( text ) ) ); // use JMP's parse to verify the answer
,
Show( rc )
);
如果你正在密切关注,你会想知道第一个版本是如何运行的,左递归。为什么它不会永远循环,或者至少在递归消耗可用内存之前?默认情况下,模式匹配器假定每个expr(...)必须至少匹配一个字符。在某些时候,递归足够深,以至于没有足够的文本留下并且匹配备份。所有备份和重试都需要一个长字符串。在第二个示例中,没有左递归,patmatch()需要FULLSCAN选项来关闭该假设,因为expr()现在可以匹配“”(零个字符)。
Re:正则表达式递归不,但模式匹配器喜欢递归。这是表达式解释器的完整示例。我不是语法专家;我认为这是一个递归下降解析器 ,我认为它对中等长度的表达式进行了大量的后向跟踪,对于拥有超过10-20个运算符的表达式来说,它显然很慢。
如果模式匹配,PatMatch返回1,如果失败则返回0(不平衡的parens,无效的运算符,无效的数字)。
text = "3+4*((5+7)*(9+11*2+2)+13)"; // plus, star, paren, integer. pattern does not handle spaces.
stack = {}; // the "working" stack... holds the RPN numbers
// the following add and mul routines pop two numbers and push the result...
addstack = Function( {},
{num1 = Num( Remove From( stack )[1] ), num2 = Num( Remove From( stack )[1] )},
Insert Into( stack, Char( num1 + num2 ) )
);
mulstack = Function( {},
{num1 = Num( Remove From( stack )[1] ), num2 = Num( Remove From( stack )[1] )},
Insert Into( stack, Char( num1 * num2 ) )
);
dummy = {}; // dummy variable with a subscript that will evaluate as needed
// BNF-like grammar of Expression, Term, Factor, Constant
// >? is the conditional assignment from LHS to RHS. The >>
// immediate assignment will not work because of back-up and retry
// which would push incorrect items to stack. The RHS of the >? is either
// the dummy[] list or working stack. The dummy stack reference uses the
// calculation of its subscript to manipulate the working stack.
// As the grammar/pattern runs, the expression is evaluated.
E = (Expr( T ) + "+" + Expr( E )) >? dummy[addstack(); 1] | Expr( T );
T = (Expr( T ) + "*" + Expr( F )) >? dummy[mulstack(); 1] | Expr( F );
F = ("(" + Expr( E ) + ")") | Expr( C );
C = Pat Span( "0123456789" ) >? stack[N Items( stack ) + 1];
rc = Pat Match( text, Pat Pos( 0 ) + E + Pat R Pos( 0 ) );
If( rc,
Show( rc, Num( stack[1] ), Eval( Parse( text ) ) ); // use JMP's parse to verify the answer
,
Show( rc )
);