语法/逻辑检查器在Javascript中?

时间:2010-12-27 16:36:14

标签: javascript error-handling typechecking syntax-checking

我正在为客户构建一个解决方案,允许他们创建非常基本的代码, 现在我已经做了一些基本的语法验证,但我坚持进行变量验证。

我知道JSLint使用Javascript进行此操作,我想知道是否有人知道这样做的好方法。

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

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

然后我试图找到一种方法来澄清“if”表达式是否使用正确的语法,如果变量moose已经初始化等等 但我想这样做而不逐个字符扫描, 代码是专为此应用程序构建的迷你语言,因此非常基本,不需要管理内存或类似的东西。

我曾想过先通过Carriage Return然后再按Space分割,但没有什么可说的,用户不会写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,空格或奇数表达式混淆,只有很少的东西需要检查,而解析器和完整吹嘘的脚本语言需要更长的时间

你们都给了我很多思考,我已经给出了相关的答案谢谢

3 个答案:

答案 0 :(得分:4)

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

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

我不知道任何可用的生成JavaScript解析器的解析器生成器。递归下降解析器并不难写,但是它们可能难以维护,并且它们使得扩展语法变得有点困难(特别是如果你没有经验丰富的原始版本)。

答案 1 :(得分:2)

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

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

解决您对“客户特定”的评论。我还将在这里添加自己的经验。如果您提供脚本语言和脚本环境,那么没有比实际解析器更好的路由。

通过一堆if-elses处理特殊情况将是非常痛苦和维护的噩梦。当我还是大学新生时,我试着写自己的语言。这是在我对递归下降解析器或一般解析器一无所知之前。我自己想通了代码可以分解成代币。从那里开始,我使用一堆if-elses编写了一个非常笨拙的解析器,并且还用空格和其他字符(正如你所描述的那样)分割了令牌。最终结果很可怕。

一旦我读到递归下降解析器,我就为我的语言编写了一个语法,并且在我编写原始解析器的第10个时间内轻松地创建了一个解析器。说真的,如果你想节省很多痛苦,可以写一个实际解析器。如果你走下目前的路线,你将永远解决问题。您将不得不处理人们将空间放在错误位置的情况,或者他们可能有太多(或太少)空间。唯一的另一种选择是提供一种极其严格的结构(即,在此语句之后必须具有完全 x个空格数),这可能会使您的脚本环境极其缺乏吸引力。实际的解析器会自动解决所有这些问题。

答案 2 :(得分:1)

Javascript有一个'eval'函数。

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

它会显示警告。您可以使用'eval'来执行基本代码。