15

我正在开发一个基于 html 的计算器,我想渲染一个表达式,然后评估它,所有这些都必须在 Javascript 中完成。我更喜欢用 LaTeX 编写表达式,并且可以交互地编辑呈现的表达式,但其他语言也可以工作。

我之前尝试过的是使用 MathQuill 以交互方式呈现表达式,然后使用 MathJS 对其进行评估。然而,这在某种程度上是可行的,因为这两个包的设计目标不同(MathQuill 呈现 LaTeX,而 MathJS 具有自定义数学语法),它不能很好地工作(例如,如果用户输入\frac{5}{17*x}并假设它是正确的语法,然后评估它并从 MathJS 中得到一个错误)。

目前,我看到了三种方法:

  • 继续我所拥有的(或者切换到 MathJax- 哪个更好?)。
  • 找到一个同时进行渲染和评估的工具(无论是乳胶还是其他语言)
  • 找到两个使用接近(如果不相同)语法进行渲染和评估的工具
  • 按照这里的建议编写我自己的渲染和评估工具。我宁愿不这样做,因为它看起来有点乏味,而且我不想重新发明轮子。

这样做的最糟糕的方法是什么?

更新 1:查看altJS提供的替代语言列表后,我想我可以使用 Python、Ruby 或 Basic 作为用户输入的语言。如果我这样做了,它将为渲染它打开很多可能性(从技术上讲,它不是“渲染”,而是想想那里有多少语法荧光笔)。但是,我不希望用户访问这些语言的更高级的元素,因为这会给我的用户带来混乱,而且它也可能不安全(比如使用eval)。我只希望用户能够使用数学运算、变量(仅我指定他们可以使用的以及用户创建的)和函数(仅我指定他们可以使用的以及用户定义的)。有没有办法限制可以使用的语言子集?

更新 2:我在 altJS 页面上查看了更多内容,并意识到几乎所有语言都旨在将语言 XYZ 编译为 JavaScript,然后在页面上运行 JavaScript,而不是在页面上运行语言XYZ。我没有仔细研究过每一个,但他们中的大多数似乎都是这样的。其他的,如 Brython,似乎被设计为在浏览器中运行语言 XYZ,但作为 JavaScript 的替代/补充,而不是作为用户的输入语言。是否有一些解决方法,以便我可以使用这些方法作为输入?

更新 3:感谢@SpaceDog 提供这些信息,并指出我没有具体说明用户应该能够实现什么。所以,这是我想要实现的功能:

  1. 基本运算(加法、减法、乘法、除法/分数、取幂、根、模)
  2. 函数(三角函数、对数等)
  3. 常数(e、pi 等)
  4. 变量(赋值、重新赋值和使用它们)
  5. 用户定义函数

LaTeXCalc似乎满足所有这些要求,除了最后一个。此外,它似乎不在 Javascript 中。

这让我想到了另一个想法:使用类似 MathJax 的东西进行演示,然后使用Wolfram Alpha API来实际处理计算。好处是它将为输入和输出提供更高级的选项。但是,该应用程序将变得无用(为什么不直接使用 wolframalpha.com,如果计算器实际上只是一个克隆?),它需要花钱,并且该应用程序无法离线工作(它是一个桌面应用程序,用 HTML 编写/CSS/JS)。对此有什么想法?

4

1 回答 1

8

似乎您想做两件不同的事情,很好地显示方程式并对其进行评估。因此,您需要一个兼具两者的工具。Latex 更侧重于演示而不是评估,尽管至少可以对一个子集进行评估(参见这个答案: Is there a calculator with LaTeX-syntax? )。

这在很大程度上取决于您想要制作计算器的复杂程度——您想要允许哪些操作。如果您使用的是一个小子集(听起来像您),那么手动编写转换器会很容易。我会研究具有表示和语义标记的MathML以及许多可用的工具。但是,对于您的用户来说,它可能不是最容易掌握的。

如果用户熟悉乳胶,并且包含的​​符号子集很小,那么将乳胶解析成可以直接评估的格式就很容易了。

我认为您需要准确定义您允许用户访问的内容,以便任何人都可以提供更好的示例来说明什么是“最佳”。

编辑——响应您的更新

好吧,您已经危险地接近编写一门完整的编程语言(您所需要的只是条件和循环——或标签)。所以重新发明轮子听起来不是一个好主意。在这种情况下,我绝对不认为您希望将 LaTeX 作为输入语言,理想情况下您希望用户更熟悉的东西。

接下来是我会做什么,如果我要这样做,我会从哪里开始这不是一个明确的答案,在开始确保我没有重复努力之前,我会做更多的研究。

我会构建一个使用 JavaScript 子集的解析器,这个解析器会做两件事(或者会有两个解析器),一个是将代码翻译成 LaTeX 或 MathML,第二个是评估/执行代码。

在 C 语言中离线执行此操作时,我会求助于 Lex 和 Yacc(或 Flex 和 Bison 等),快速谷歌显示有一个 Javascript 等价物:Jison。这将为您提供语言解析器的支柱,您可以对其进行修改。

或者从现有的 JS 解析器开始可能会有所帮助,试试这个答案:JavaScript parser in JavaScript。吨

一旦你有了解析主干,你就可以一开始就保持简单——翻译成可显示的语言应该相当容易,并且评估你可能会冒险使用eval——因为解析器已经确保输入只使用你的东西'重新允许。但是,我建议不要在生产版本中这样做(这对测试很好),并且将令牌映射到内部函数不需要太多额外的工作。

之后,您可能想要改进显示的输出,也许您想尝试简化输入或重新排序以使其更有意义。这将需要从您的解析器中获取内部表示并对其进行一些巧妙的处理。但首先要开始工作。

您希望它可以离线工作,因此我对托管您引用的其他一些示例程序的服务器的另一个想法是行不通的(并且在那里使用 Wolfram Alpha 或 Google 是一个不错的选择-但是,正如您所说,什么是那么程序的要点)。但是您可能还会考虑是否可以更好地开始使用不同的基础语言编写此代码——尽管我猜您想要 HTML/JS/CSS 的可移植性。

您链接的其他内容都是其他可能的想法,我只是认为在内部拥有自己的解析器而不是依赖于每个应用程序的第三方代码会获得更多好处。使用您自己的解析器,您可以在以后轻松添加功能或语言特性。

最后的想法,你不一定要限制使用 Javascript 作为这种方法的输入。如果您认为您的用户将处理反向波兰表示法,那么手动编写解析器很容易——但您必须做一些工作来很好地格式化它以供输出。

于 2013-12-09T09:14:17.790 回答