Spørgsmål:
Java-bibliotek til at omdanne en matematisk formel til en AST
ComFreek
2014-06-17 19:00:39 UTC
view on stackexchange narkive permalink

Jeg leder efter et Java-bibliotek, der kan analysere matematiske formler i et AST (abstrakt syntaks-træ).

UPDATE:
Jeg er åben for alternativer i andre sprog end Java, forudsat at jeg kan kalde disse værktøjer / biblioteker fra Java.
JavaScript kan for eksempel indlejres ved hjælp af Rhino-motoren.

Essential Krav:

  1. Evnen til at analysere formler i infixnotation.

  2. evne til at bevare ukendte variabler - Jeg leder ikke efter en lommeregner.

  3. En brugerdefineret liste over operatører og funktioner.
    Det ville også være fremragende, hvis man kunne fjerne allerede bygget -in-funktioner (f.eks. s(x)).

Ikke-væsentlige krav:

  • Biblioteket kan være open source, men det behøver det ikke være. Et gratis bibliotek er tilstrækkeligt.
** Bemærk: ** Selvom jeg i mellemtiden fandt et mere eller mindre passende JavaScript-bibliotek, er bedre alternativer (helst i Java) stadig velkomne!
Seks svar:
ComFreek
2014-06-21 00:59:36 UTC
view on stackexchange narkive permalink

Math.js

JavaScript-delen

“Math.js er et omfattende matematikbibliotek til JavaScript og Node.js.”
- Projekt readme

Det giver en parse () -funktion.
Eksempel ved anvendelse af NodeJS-miljøet:

  var math = require ('mathjs') (); var ast = math.parse ('xy ^ (1/2)'); / / Log objektet fuldt ud util = kræve ('util'); console.log (util.inspect (ast, {showHidden: false, depth: null}));  

Output:

  {op: '^', fn: 'pow', params: [{name: 'xy'}, {op: '/', fn: 'divide', params: [{ valueType: 'number', value: '1'}, {valueType: 'number', value: '2'}]}]}  

Java-delen

Jeg bruger Java Nashorn VM (kun tilgængelig i Java> = 8) til at udføre JavaScript.

Programarkitektur:

  Bruger - ------------- > Java input formla | ---- > Nashorn ---- > math.js | < ---------------- ----- | Bruger < ----------------- |  

Brug af Nashorn-motoren er ret enkel (undtagelseshåndtering udeladt)

  ScriptEngine engine = ny ScriptEngineManager (). getEngineBy Navn ("nashorn"); engine.eval (readerInstancePointingToMathJsLibrary); engine.eval (readerInstancePointingToBridgeJavaScript);  

Broens JavaScript-kode afhænger meget af din implementering af AST-noder. Vi udnytter Nashorns evne til at oprette og overføre Java-objekter i JavaScript til Java. Eksempel:

var matematik = mathjs (); funktionskonvertering (formel) {var ast = matematik.parse (formel); var javaAst = / * opbyg din AST med Java-objekter * / returner javaAst;}

Vi kan nu få adgang til denne funktion fra Java og endda videregive vilkårlige argumenter:

  Invocable inv = (Invocable) -motor; // Expression er min AST-nodetype i Javaexpr = (Expression) inv.invokeFunction ("convert", formulaFromUser);  

Bemærk: Jeg havde brug for en hurtig måde at analysere matematiske udtryk på. En parser (enten håndskrevet eller genereret af en parsergenerator) foretrækkes altid. Ikke desto mindre viser koden ovenfor, hvordan Java Nashorn let kan integreres.

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

JavaScript

For få måneder siden brugte jeg Esprima til at analysere sådanne input. Faktisk analyserer Esprima alle JavaScript-input (konverterer det til et træ), så det skal fungere for sådanne matematiske udtryk.

Når du har inkluderet Esprima, kan du gøre:

  esprima .parse (input);  

... hvor input er en streng, der indeholder den input, der skal parses (hvis den er ugyldig, kastes en fejl) .

Eksempel

  esprima.parse ("1 + 2 * 3")  

returnerer følgende objekt:

  {"type": "Program", "body": [{"type": "ExpressionStatement", "expression": {"type": "BinaryExpression", "operator": "+", "left": {"type": "Literal", "value": 1, "raw": "1"}, "right": {"type": "BinaryExpression", " operator ":" * "," left ": {" type ":" Literal ", "værdi": 2, "rå": "2"}, "højre": {"type": "Bogstavelig", "værdi": 3, "rå": "3"}}}]}  kode > 

Jeg ændrede Esprima-koden og brugte den i et eksperimentelt projekt til at definere brugerdefinerede operatorer i JavaScript. Applikationen er open source på GitHub: http://ionicabizau.net/JavaScript-custom-operators/

Esprima ser ud til at være langt mere kraftfuld og i stand til at analysere funktioner, end jeg faktisk har brug for. Ikke desto mindre er +1 og dine operatører meget interessante.
Ionică Bizău
2014-06-23 21:59:19 UTC
view on stackexchange narkive permalink

Java

Det ser ud til, at JEP er en matematisk udtryksparser.

JEP er en Java API til parsing og evaluering af matematiske udtryk. Med dette bibliotek kan du give dine brugere mulighed for at indtaste en vilkårlig formel som en streng og straks evaluere den. JEP understøtter brugerdefinerede variabler, konstanter og funktioner. En række almindelige matematiske funktioner og konstanter er inkluderet.

Funktioner

  • Brugervenlig pakke til analyse af matematiske udtryk
  • Lille størrelse (kun 56kb som jar-arkiv)
  • Understøtter boolske udtryk (!, &&, ||, <, >,! =, ==, > =, og < =)
  • Hurtig evaluering ( udtrykket kan evalueres hurtigt for forskellige variable værdier)
  • Inkluderer almindelige matematiske funktioner
  • Kan udvides gennem brugerdefinerede funktioner
  • Foruddefinerede konstanter såsom 'pi' og ' e '
  • Understøttelse af strenge, komplekse tal og vektorer
  • Understøttelse af implicit multiplikation (tillader brug af udtryk som "3x" i stedet for "3 * x")
  • Tillader valg mellem deklarerede og sort angivne variabler
  • Java 1.1-kompatible (testet med Sun Java JDK 1.1.8 og Microsoft Java VM)
  • Understøtter Unicode-tegn (inklusive græske symboler )
  • Omfatter JavaCC-grammatik, hvorfra mai n klasser genereres

Det er open source på SourceForge.

Der er også et SO spørgsmål om dette emne: https://stackoverflow.com/q/4589951/1420197

Det oprindelige projekt ser ud til at være afbrudt. SourceForge-projektsiden linker til et [nyt eksternt sted] (http://www.singularsys.com/jep), der tilbyder Jep Java som et kommercielt produkt ($ 550 for binære filer, $ 950 for kildekoden).
@ComFreek Du har ret. Alligevel synes jeg, at det oprindelige projekt skulle dække det, du har brug for. Tak for dusør! :-)
Ira Baxter
2015-09-07 09:37:14 UTC
view on stackexchange narkive permalink

Bygningsformel parsers / træbyggere er en ret simpel øvelse. Du kan jage efter et bibliotek, men du vil altid ende med at ændre det for at producere præcis, hvad du vil have. I stedet er det sandsynligvis lettere at blot kode det, du vil have.

  • Dette StackOverflow-link giver anvisninger om, hvordan man nemt bygger parsere som denne i hånden. Det giver også adgang til et andet link, der viser, hvordan man nemt konverterer sådanne parsere til dem, der producerer AST'er.
  • Du kan nemt tilpasse til at inkludere de infix-operatorer, du kan lide, uanset funktionsoperatoer ("sin") du kan lide, skalarværdier og variabelnavne.
  • Du kan kode denne type parsere på stort set ethvert sprog, inklusive Java.

Hvis du vil analysere noget betydeligt mere kompleks end et udtryk, kan du skubbe denne type parser til at gøre det, men det er generelt lettere at skifte til parsergenerator i så fald.

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

Java

Symja omdanner et matematisk udtryk til følgende Symja AST.

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

Jeg har brugt javassist til at konvertere Java-udtryk til byte-kode (hvilket måske er det, du i sidste ende leder efter, hvis du vil evaluere udtrykket). Det kan endda omdefinere eksisterende funktioner.

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

Tilgiv mig, hvis jeg misforståede dig, men hvordan lader Javassist mig analysere brugerinput (streng) i en træstruktur (Java-objekter)?
Sikkert ikke. Det giver dig mulighed for at kompilere dit udtryk til en Java-metode, du kan derefter ringe direkte til for at få det evalueret. Dette skyldes, at jeg forventede, at dette var dit endelige mål. Hvis dette er en del af en øvelse i at skrive en kompilator, skal du gøre det manuelt i stedet :)


Denne spørgsmål og svar blev automatisk oversat fra det engelske sprog.Det originale indhold er tilgængeligt på stackexchange, som vi takker for den cc by-sa 3.0-licens, den distribueres under.
Loading...