修复达到的最大setlocal递归级别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了修复达到的最大setlocal递归级别相关的知识,希望对你有一定的参考价值。

我知道有人问过这个问题,但这是一个更具体的需求。我最近接受了一个挑战,即尝试通过在Windows上批处理来制作一种简单的“编程语言”。是的但是,编译器只能在返回消息之前处理32个setlocal。因为它们直到“脚本的结尾”都没有关闭(如果没有用endlocal表示),所以对于代码中的每一行,将设置1个局部x的行数这是我所知道的:Endlocal本质上用于“关闭” setlocal如果未指定,则在脚本退出时会自动关闭,但仍保留脚本-局部变量。这允许setlocals的目的-脚本特有的vars处于其核心-仍然可以正常工作而无需结束它。这意味着我可以在同一术语实例中执行新的批处理脚本(只需键入'%home% software dir.bat')而无需关闭原始setlocal。然后,新脚本可能具有另一个setlocal。这导致了问题。它循环回到自身,也可能就是这样。

所以,这是我不知道的/问题:

我使用1 setlocal键入要编译的文件名,它将打开编译器脚本,并且每行使用1 setlocal。我尝试在编译器需要setlocal之后立即在代码中放入“ endlocal”(就像所有命令完成后一样,在下面的代码中),但是脚本只是崩溃了。当我也尝试在第一个程序中执行此操作时,它也会崩溃。

因此,我有3个选择答:找出放置本地语言的位置以允许脚本运行/或在不涉及使用本地语言但我认为没有解决方案的消息周围找到另一种解决方案。b:找出一种解决方法,用于分解超过30行的文件,但是我90%确信它们不是有效的文件,或者在那一点上甚至还有一点要尝试,我的意思是---,我也可以尝试对NASAS原始计算机进行编程以驱动Tesla。太乱了。让我们忽略选项B。c:为该愚蠢的项目使用另一种语言,但这又是要以批处理(一种脚本语言)进行操作,因此让我们解决问题的局限性并坚持使用A。

在编译器中需要执行所有setlocal enabledelayedexpansion等操作,将一行分成参数,然后分别将其设置为%arg1%%arg2%%arg3%等。这是“编译器”中的相关代码。如果有人想查看完整文件,请给我发消息。

setlocal EnableDelayedExpansion
<"!file!" (
  for /f %%i in ('type "!file!" ^| find /c /v ""') do set /a n=%%i && for /l %%j in (1 1 %%i) do (
    set /p "line_%%j="
REM this just breaks the file into lines
  )
)
REM this then takes the first line from that respective variable and breaks it into arguments.
set i=1
set "arg!i!=%line_1: =" & set /A i+=1 & set "arg!i!=%"

在此之后,我的程序然后检查这些参数以表示各种事情(例如语句的结尾等),然后如果没有匹配项且args用于常规命令,它将执行相应的批处理脚本。从将其分解为args以来,它使用了编译器设置的相同参数(%arg1%等)。无需馈入下一个脚本参数,然后从%〜1设置它们,因为如果在彼此之间打开它们,变量将保留在脚本之间。完成这些脚本后,它们表示它们正在返回正在主动编译的脚本,打开编译器,编译器看到此内容,继续到下一行,然后使用上面的代码,然后重复该过程。

[如果我不得不猜测,因为实际上我所做的只是使用一个脚本打开一个脚本,然后打开第一个脚本,然后打开第一个脚本,而另一个脚本又打开了第一个脚本(等你明白了,这是一个很大的循环本身),由于我要遍历这些脚本而导致循环滥用,因此setlocal搞砸了。

我曾尝试将endlocal放置在该代码的最末尾,也正好在程序执行相应脚本之前,在编译器启动时以及在任何位置,脚本崩溃-立即关闭。该文件甚至没有从文件中读取任何命令或参数,我可以看到,因为我有一个日志,因此可以准确地看到该程序停止运行的位置。

关键问题:有趣的是-在执行代码以停止编译脚本的脚本(如其结尾所示)中,我放置了一个endlocal,并且它没有崩溃。如果setlocals是打开的,并且在同一终端中执行了另一个脚本,则它会关闭原始setlocal还是将它作为下一个脚本带到下一个脚本,直到整个过程都被赋予了quit命令或该性质的内容/用户关闭了?如果setlocal保持打开状态,是否意味着我可以在script1中打开setlocal,执行script2.bat,然后结束script1的setlocal语句?

[疲惫,我要强调这一点-当我说执行时,我从来不是说要通过启动命令在另一个cmd窗口中打开,而是要在同一运行的cmd窗口中打开。因此,多个脚本会将内容输出到同一窗口。

这些术语中的一些可能对此几乎矫kill过正,但我​​没有更好的术语,我很抱歉。

所以欢迎提出任何想法,希望这是有道理的,但我可能可以使用更好的术语。感谢您阅读的编码员!

此外,该项目是100%无意义的,并且在任何庄园中都是完全多余且无用的-但我想承担一些挑战,无论哪种方式都很酷,它都能发出命令并以正确的顺序正确执行命令变量和参数等。它的核心是一个非常简单的脚本,但是由于批处理的限制,它使用的某些方法只是一些代码繁重。

让我知道你们的想法!

[此外,如果我实际上只是个傻瓜,我可以告诉cmd不要输出任何精确命令导致消息抛出的结果吗?这些脚本仍然可以工作并得到编译,它们之间的消息只是被垃圾邮件散布了。因此,如果我可以继续进行而不必担心中断批处理和忽略消息,那将是很棒的。我试过> nul在一些命令上无济于事。

谢谢。我总是可以依靠stackoverflow来实现我之上的方法。

答案

setlocalendlocal的一些解释。

仅通过setlocal可以更改延迟扩展和扩展的模式。

setlocal EnableDelayedExpansion
setlocal EnableExtensions

每个setlocal将当前模式(扩展,delayedExpansion)和所有变量的副本推送到堆栈。

An endlocal从堆栈中弹出模式和变量。

但是CALL命令也使用此堆栈,因此,对于在同一调用级别中调用的endlocal,只能使用setlocal

并且exit / goto :eof将隐式执行当前呼叫级别的所有endlocals

针对您的问题:(我不理解!)

解决方案1:在脚本开始处仅使用一个setlocal EnableDelayedExpansion,这样可以在脚本的生命周期内进行延迟扩展。

解决方案2:setlocal / endlocal中的函数内部使用变量范围。

这有点棘手,因为许多函数必须在其范围之外修改至少一个变量。

以上是关于修复达到的最大setlocal递归级别的主要内容,如果未能解决你的问题,请参考以下文章

jdbc 查询5万条数据出现 ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01000: 超出打开游标的最大数

超出最大递归 SQL 级别数 (50)

使用 Pickle / cPickle 达到最大递归深度

Laravel 附加具有相关关系的属性将导致达到最大函数嵌套级别

“致命错误:已达到 '100' 的最大函数嵌套级别,正在中止!”的解决方案在 PHP 中

NC41 最长无重复子数组/NC133链表的奇偶重排/NC116把数字翻译成字符串/NC135 股票交易的最大收益/NC126换钱的最少货币数/NC45实现二叉树先序,中序和后序遍历(递归)(代码片段