我正在为客户端建立一个解决方案,使他们能够创建非常基本的代码,现在我已经完成了一些基本的语法验证,但我遇到了可变验证。

我知道 JSLint 使用 Javascript 来做到这一点,我想知道是否有人知道做到这一点的好方法。

例如,假设用户编写了代码

moose = "barry"
base = 0
if(moose == "barry"){base += 100}

然后,我试图找到一种方法来澄清“如果”表达式在正确的语法中,如果变量驼鹿已经初始化了等,但是我想在不按字符扫描的情况下执行此操作,代码是一种mini语言仅为此应用程序构建,因此非常基本,不需要管理内存或类似的内容。

我曾考虑过首先按回车符分割,然后按空格分割,但没有什么可以说用户不会写类似的东西 moose="barry" 或者 if(moose=="barry")没有什么可以说用户不会将条件的结果保持内联。

显然,编译器和解释器在更广泛的范围内这样做,但我不确定他们是否逐个字符地这样做,如果他们这样做,他们是如何优化的?

(另一种选择是我可以将其发送回 PHP 进行处理,然后浏览器将不再承担责任)

有什么建议么?

谢谢

用例是有限的,在这种情况下永远不会扩展语法,该语言是一种简单的脚本语言,使客户端能够根据用户输入创建唯一的成本,最终结果将由 PHP 处理,无论以确保计算最终用户无法调整并确保存在一定的一致性。

因此,例如,假设基本成本为1.00英镑,并且表格上有一个名为“额外成本”的字段,该语言将使他们操纵相对于“额外成本”字段的基本成本。

所以

base = 1;
if(additional > 100 && additional < 150){base += 50}
elseif(additional == 150){base *= 150}
else{base += additional;}

这是如何使用该语言的基本示例。


谢谢您的所有答案,我已经调查了一个解析器,并且创建一个要复杂得多,比在1000行的代码线上进行多个测试所要求的要复杂得多,并且发现字符逐个字符,即使在一个具有512MB内存的核心P4(远低于客户使用)

我决定构建一个基于 PHP 的语法检查器,它将检查信息并将变量等转换为有效的 PHP 代码,同时检查它(这样就可以稍后调用而无需重新编译)使用它而不是 javascript 这似乎更合适并将允许出现更复杂的代码而不妨碍验证过程

只花了一个小时,我的代码就能够检查 if 语句的有效性,并且不会被嵌套的 if、空格或奇怪的表达式所混淆,几乎没有什么需要检查的了,而解析器和成熟的脚本语言会花费更长的时间

你们给了我很多思考,我对相关答案进行了评分,谢谢

有帮助吗?

解决方案

如果你 真的 想这样做 - 我的意思是,如果您真的希望您的软件能够正常,可以预见,而没有一堆怪异的“不要这样”的特殊情况 - 您将不得不为您的真正解析器编写一个真正的解析器语。一旦拥有,您就可以将您的语言中的任何程序转换为数据结构。使用该数据结构,您将能够进行各种代码分析,包括至少称为使用定义和定义使用链分析的过程。

如果您炮制一种“编程语言”,可以在应用程序中进行一些脚本,那么无论您认为这是多么微不足道,都会有人最终编写一个令人震惊的大型程序。

我不知道会生成JavaScript解析器的任何容易获得的解析器。递归下降解析器并不难写,但是它们可能会变得丑陋,并且使延长语法变得有些困难(尤其是您在制作原始版本的经验不太经验的话)。

其他提示

您可能想看看 JS/CC 这是一个解析器生成器,可以为 Javascript 语法生成解析器。您需要弄清楚如何使用 BNF 和 EBNF 来描述您的语言。另外,JS/CC 有自己的语法(有点接近实际的 BNF/EBNF)来指定语法。给定语法,JS/CC 将为该语法生成​​一个解析器。

正如 Pointy 所说,你的另一个选择是从头开始编写你自己的词法分析器和递归下降解析器。一旦你有了 BNF/EBNF,一切就没那么难了。我最近用 Javascript 编写了一个基于 EBNF 的解析器(语法非常简单,所以编写一个 YMMV 并不难)。

解决您关于“特定于客户”的评论。我在这里也补充一下我自己的经验。如果您要提供脚本语言和脚本环境,那么没有比实际解析器更好的途径了。

通过一堆 if-else 处理特殊情况将是非常痛苦的,也是维护的噩梦。当我还是大学新生时,我尝试编写自己的语言。这是在我了解递归下降解析器或一般解析器之前。我自己发现代码可以分解为令牌。从那里,我使用一堆 if-else 编写了一个极其笨重的解析器,并且还按空格和其他字符分割标记(正是您所描述的)。最终的结果是可怕的。

一旦我读到了递归下降解析器,我就为我的语言编写了语法,并轻松地创建了一个解析器,所用时间是我编写原始解析器所需时间的十分之一。说真的,如果你想让自己避免很多痛苦,那就写一个 实际的 解析器。如果你沿着当前的路线走下去,你将永远解决问题。您将不得不处理人们将空间放在错误位置的情况,或者他们可能拥有太多(或太少)空间的情况。唯一的其他选择是提供一个极其刚性的结构(即你必须有 确切地 x 此语句后的空格数),这可能会使您的脚本环境变得非常没有吸引力。实际的解析器将自动解决所有这些问题。

JavaScript具有'eval'的函数。

var code = 'alert(1);';
eval(code);

它将显示警报。您可以使用“评估”执行基本代码。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top