題:
Java庫,可將數學公式轉換為AST
ComFreek
2014-06-17 19:00:39 UTC
view on stackexchange narkive permalink

我正在尋找一個可以將數學公式解析為AST(抽象語法樹)的Java庫。

更新
我願意接受Java以外的其他語言,前提是我可以從Java調用這些工具/庫。例如,可以使用 Rhino引擎嵌入JavaScript。

基本要求:

  1. 中綴表示法解析公式的功能。

  2. 保留未知變量的能力-我不是在尋找計算器。

  3. 可自定義的運算符和函數列表。 -in函數(例如 sin(x))。

  4. ol>

    非基本要求:

  • 該庫可以是開源的,但不是必須的。一個免費的圖書館就足夠了。
**注意:**儘管與此同時我發現了一個或多或少合適的JavaScript庫,但仍然歡迎更好的替代方法(最好是Java)!
六 答案:
ComFreek
2014-06-21 00:59:36 UTC
view on stackexchange narkive permalink

Math.js

JavaScript部分

“ Math.js是JavaScript和Node.js的擴展數學庫。”
項目自述文件

它提供了 parse()函數。
使用NodeJS環境的示例:

  var math = require('mathjs')(); var ast = math.parse('xy ^(1/2)'); / /完整記錄對象var util = require('util'); console.log(util.inspect(ast,{showHidden:false,depth:null}));  

輸出:

  {op:'^',fn:'pow',params:[{name:'xy'},{op:'/',fn:'divide',params:[{ valueType:'數字',值:'1'},{valueType:'數字',值:'2'}]}]}}  

Java部分

我使用 Java Nashorn VM(僅在Java> = 8中可用)執行JavaScript。

程序體系結構:

  User- ------------- > Java輸入形式| ---- > Nashorn ---- > math.js | < ---------------- ----- |用戶< ----------------- |  

使用Nashorn引擎非常簡單(省略了異常處理)

  ScriptEngine引擎= new ScriptEngineManager()。getEngineBy Name(“ nashorn”); engine.eval(readerInstancePointingToMathJsLibrary); engine.eval(readerInstancePointingToBridgeJavaScript);  

網橋的JavaScript代碼在很大程度上取決於AST節點的實現。我們利用Nashorn在JavaScript中創建Java對象並將其傳輸到Java的能力。示例:

  var math = mathjs(); function convert(formula){var ast = math.parse(formula); var javaAst = / *使用Java對象構建AST * / return javaAst;}  

我們現在可以從Java訪問該函數,甚至可以傳遞任意參數:

  Invocable inv =(Invocable)引擎; //表達式是我在Javaexpr中的AST節點類型=(Expression)inv.invokeFunction(“ convert”,FormulaFromUser);  

注意:我需要一種快速解析數學表達式的方法。解析器(手寫的或由解析器生成器生成的)始終是首選。儘管如此,上面的代碼顯示瞭如何輕鬆集成Java Nashorn。

Ionică Bizău
2014-06-20 23:15:34 UTC
view on stackexchange narkive permalink

JavaScript

幾個月前,我使用 Esprima來解析此類輸入。實際上,Esprima會解析任何JavaScript輸入(將其轉換為樹),因此它應適用於此類數學表達式。

包含Esprima後,您可以執行以下操作:

  esprima .parse(input);  

...,其中 input 是一個字符串,其中包含應解析的輸入(如果無效,則將引發錯誤) 。

示例

  esprima.parse(“ 1 + 2 * 3”) 

返回以下對象:

  {“ type”:“ Program”,“ body”:[{“ type”:“ ExpressionStatement”,“ expression”:{“ type”:“ BinaryExpression”, “ operator”:“ +”,“ left”:{“ type”:“ Literal”,“ value”:1,“ raw”:“ 1”},“ right”:{“ type”:“ BinaryExpression”,“運算符”:“ *”,“左”:{“類型”:“文字”, “ value”:2,“ raw”:“ 2”},“ right”:{“ type”:“ Literal”,“ value”:3,“ raw”:“ 3”}}}}]}}  

我修改了Esprima代碼,並將其用於一個實驗項目中,以在JavaScript中定義自定義運算符。該應用程序在GitHub上是開源的: http://ionicabizau.net/JavaScript-custom-operators/

Esprima似乎比我實際需要的功能強大得多,並且能夠解析功能。不過+1和您的運算符非常有趣。
Ionică Bizău
2014-06-23 21:59:19 UTC
view on stackexchange narkive permalink

Java

似乎 JEP 是一個數學表達式解析器。

JEP是Java API用於解析和評估數學表達式。使用該庫,您可以允許用戶輸入任意公式作為字符串,並立即對其進行評估。 JEP支持用戶定義的變量,常量和函數。

功能

  • 易於使用的軟件包,用於解析數學表達式
  • 小尺寸(僅作為jar歸檔文件為56kb)
  • 支持布爾表達式(!,&&,||,<,>,!=,==,> =和< =)
  • 快速求值(可以快速評估表達式中的不同變量值)
  • 包括常用的數學函數
  • 可通過用戶定義的函數擴展
  • 預定義常量,例如“ pi”和“ e'
  • 支持字符串,複數和向量
  • 支持隱式乘法(允許使用諸如“ 3x”而不是“ 3 * x”之類的表達式)
  • 允許在已聲明和未聲明的變量之間進行選擇
  • 與Java 1.1兼容(已通過Sun Java JDK 1.1.8和Microsoft Java VM測試)
  • 支持Unicode字符(包括希臘符號) )
  • 包括JavaCC語法,從中生成了n個類

它是 SourceForge上的開源代碼。

關於此主題還有一個SO問題: https://stackoverflow.com/q/4589951/1420197

最初的項目似乎已終止。 SourceForge項目頁面鏈接到[新的外部站點](http://www.singularsys.com/jep),該站點將Jep Java作為商業產品提供(二進製文件550美元,源代碼950美元)。
-1
Ira Baxter
2015-09-07 09:37:14 UTC
view on stackexchange narkive permalink

構建公式解析器/樹構建器是一個非常簡單的練習。您可以尋找一個庫,但是您最終總是會對其進行修改以產生所需的庫。取而代之的是,簡單地編寫所需的代碼可能會更容易。

  • 此StackOverflow鏈接提供了有關如何手動輕鬆構建此類解析器的說明。它還提供對第二個鏈接的訪問,該鏈接顯示瞭如何輕鬆地將此類解析器轉換為可生成AST的解析器。
  • 您可以輕鬆地自定義以包含所需的任何infix運算符,任何函數操作符(“ sin”)您可以使用標量值和變量名。
  • 您可以使用幾乎任何語言(包括Java)編寫此類解析器。

如果您想解析更多內容,可以使用它比表達式複雜,您可以推動這種解析器來執行此操作,但是在這種情況下,切換到解析器生成器通常更容易。

axelclk
2015-11-05 23:24:55 UTC
view on stackexchange narkive permalink

Java

Symja將數學表達式轉換為以下 Symja AST

Thorbjørn Ravn Andersen
2014-06-23 22:07:28 UTC
view on stackexchange narkive permalink

我已經使用javassist將Java表達式轉換為字節碼(如果要評估表達式,這可能是您最終要尋找的東西)。它甚至可以重新定義現有功能。

http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/

如果我誤解了您,請原諒我,但是Javassist如何讓我將用戶輸入(字符串)解析為樹結構(Java對象)?
可能不會。它允許您將表達式編譯成Java方法,然後可以直接調用以對其求值。這是因為我期望這是您的最終目標。如果這是編寫編譯器的一部分,那麼您應該手工完成:)


該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...