{"id":22515313,"url":"https://github.com/scijava/parsington","last_synced_at":"2025-04-13T00:40:10.616Z","repository":{"id":27258371,"uuid":"30730824","full_name":"scijava/parsington","owner":"scijava","description":"Simple yet fancy infix-to-postfix parser for mathematical expressions. :bowtie:","archived":false,"fork":false,"pushed_at":"2024-10-20T19:38:23.000Z","size":380,"stargazers_count":59,"open_issues_count":0,"forks_count":15,"subscribers_count":17,"default_branch":"main","last_synced_at":"2025-04-13T00:40:04.544Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scijava.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-02-12T23:27:18.000Z","updated_at":"2025-02-27T09:13:33.000Z","dependencies_parsed_at":"2024-10-20T23:09:19.195Z","dependency_job_id":null,"html_url":"https://github.com/scijava/parsington","commit_stats":null,"previous_names":["scijava/scijava-expression-parser"],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scijava%2Fparsington","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scijava%2Fparsington/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scijava%2Fparsington/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scijava%2Fparsington/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scijava","download_url":"https://codeload.github.com/scijava/parsington/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248650414,"owners_count":21139671,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-07T03:29:38.901Z","updated_at":"2025-04-13T00:40:10.596Z","avatar_url":"https://github.com/scijava.png","language":"Java","readme":"[![](https://img.shields.io/maven-central/v/org.scijava/parsington.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.scijava%22%20AND%20a%3A%22parsington%22)\n[![](https://github.com/scijava/parsington/actions/workflows/build-main.yml/badge.svg)](https://github.com/scijava/parsington/actions/workflows/build-main.yml)\n\n# Parsington\n\nParsington is an infix-to-postfix and infix-to-syntax-tree expression parser\nfor mathematical expressions written in Java. It is simple yet fancy, handling\n(customizable) operators, functions, variables and constants in a similar way\nto what the Java language itself supports.\n\nParsington is part of the [SciJava](https://scijava.org/) project\nfor scientific computing in Java.\n\n## Example\n\nInfix input: `(-b + sqrt(b^2 - 4*a*c)) / (2*a)`  \n\u0026rarr; postfix output: `b - sqrt b 2 ^ 4 a * c * - (1) \u003cFn\u003e + (1) 2 a * (1) /`\n\n## Rationale\n\nExpression parsers are as old as the hills; what makes this one different?\n\n* __No dependencies.__\n* __[Available on Maven Central](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.scijava%22%20AND%20a%3A%22parsington%22).__\n* __Permissive BSD-2 license.__ See [LICENSE.txt](LICENSE.txt).\n* __Separation of concerns.__ Parsington's parser stands alone, giving you a\n  postfix queue or syntax tree from your infix expression, which you can then\n  process or evaluate however you see fit. Parsington also provides an [eval\n  subpackage](src/main/java/org/scijava/parsington/eval) that can evaluate\n  expressions involving objects of common types (`java.lang.Boolean`,\n  `java.lang.Number`, `java.lang.String`), and which is extensible to your own\n  needs\u0026mdash;there is no assumption that your variables will consist of any\n  particular data type, numerical or otherwise.\n* __Extensibility.__ The\n  [default operators](src/main/java/org/scijava/parsington/Operators.java), a\n  synthesis of Java and MATLAB syntax, work well. But if you need something\n  else, you can define your own unary and binary operators with whatever\n  symbols, precedence and associativity you desire.\n* __Clean, well-commented codebase with unit tests.__ Import the source into\n  your favorite IDE and watch Parsington in action by putting a breakpoint\n  [here](src/main/java/org/scijava/parsington/ParseOperation.java#L70-L72).\n\n## History\n\nThe [ImageJ Ops](https://github.com/imagej/imagej-ops) project needed an\nexpression parser so that it could be more awesome. But not one limited to\nprimitive doubles, or one that conflated parsing with evaluation, or one\nlicensed in a restrictive way. Just a simple infix parser: a nice shunting yard\nimplementation, or maybe some lovely recursive descent. Something on GitHub,\nwith no dependencies, available on Maven Central. But surprisingly, there was\nonly tumbleweed. So Parsington was born, and all our problems are now over!\n\n## Usage\n\nIn your POM `\u003cdependencies\u003e`:\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eorg.scijava\u003c/groupId\u003e\n  \u003cartifactId\u003eparsington\u003c/artifactId\u003e\n  \u003cversion\u003e3.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Postfix queues\n\nTo parse an infix expression to a postfix queue:\n```java\nLinkedList\u003cObject\u003e queue = new ExpressionParser().parsePostfix(\"a+b*c^f(1,2)'\");\n// queue = [a, b, c, f, 1, 2, (2), \u003cFn\u003e, ^, ', *, +]\n```\n\n### Syntax trees\n\nTo parse an infix expression to a syntax tree:\n```java\nSyntaxTree tree = new ExpressionParser().parseTree(\"a+b*c^f(1,2)'\");\n```\n```\n       +-------+\n       |   +   |\n       +---+---+\n           |\n    +------+------+\n    |             |\n+---+---+     +---+---+\n|   a   |     |   *   |\n+-------+     +---+---+\n                  |\n           +------+------+\n           |             |\n       +---+---+     +---+---+\n       |   b   |     |   '   |\n       +-------+     +---+---+\n                         |\n                         |\n                     +---+---+\n                     |   ^   |\n                     +---+---+\n                         |\n                  +------+------+\n                  |             |\n              +---+---+     +---+---+\n              |   c   |     | \u003cFn\u003e  |\n              +-------+     +---+---+\n                                |\n                         +------+------+\n                         |             |\n                     +---+---+     +---+---+\n                     |   f   |     |  (2)  |\n                     +-------+     +---+---+\n                                       |\n                                +------+------+\n                                |             |\n                            +---+---+     +---+---+\n                            |   1   |     |   2   |\n                            +-------+     +-------+\n```\n\n### Evaluation\n\nTo evaluate an expression involving basic types:\n```java\nObject result = new DefaultTreeEvaluator().evaluate(\"6.5*7.8^2.3\");\n```\n\n### Interactive console\n\nThere is also an [interactive console\nshell](src/main/java/org/scijava/parsington/Main.java) you can play with.\n\nRun it easily using [jgo](https://github.com/scijava/jgo):\n```\njgo org.scijava:parsington\n```\n\nOr run from source, after cloning this repository:\n```shell\nmvn\njava -jar target/parsington-*-SNAPSHOT.jar\n```\n\nSimple example invocations with the console's default evaluator:\n```\n\u003e 6.5*7.8^2.3\n732.3706691398969 : java.lang.Double\n\u003e 2*3,4\n      ^\nMisplaced separator or mismatched groups at index 4\n```\n\nThe `postfix` built-in function lets you introspect a parsed postfix queue:\n```\n\u003e postfix('6.5*7.8^2.3')\n6.5 : java.lang.Double\n7.8 : java.lang.Double\n2.3 : java.lang.Double\n^ : org.scijava.parsington.Operator\n* : org.scijava.parsington.Operator\n\u003e postfix('[1, 2f, 3d, 4., 5L, 123456789987654321, 9987654321234567899]')\n1 : java.lang.Integer\n2.0 : java.lang.Float\n3.0 : java.lang.Double\n4.0 : java.lang.Double\n5 : java.lang.Long\n123456789987654321 : java.lang.Long\n9987654321234567899 : java.math.BigInteger\n[7] : org.scijava.parsington.Group\n\u003e postfix('f(x, y) = x*y')\nf : org.scijava.parsington.Variable\nx : org.scijava.parsington.Variable\ny : org.scijava.parsington.Variable\n(2) : org.scijava.parsington.Group\n\u003cFn\u003e : org.scijava.parsington.Function\nx : org.scijava.parsington.Variable\ny : org.scijava.parsington.Variable\n* : org.scijava.parsington.Operator\n= : org.scijava.parsington.Operator\n\u003e postfix('math.pow(q) = q^q')\nmath : org.scijava.parsington.Variable\npow : org.scijava.parsington.Variable\n. : org.scijava.parsington.Operator\nq : org.scijava.parsington.Variable\n(1) : org.scijava.parsington.Group\n\u003cFn\u003e : org.scijava.parsington.Function\nq : org.scijava.parsington.Variable\nq : org.scijava.parsington.Variable\n^ : org.scijava.parsington.Operator\n= : org.scijava.parsington.Operator\n```\n\nThe `tree` function is another way to introspect, in syntax tree form:\n```\n\u003e tree('math.pow(q) = q^q')\n '='\n - '\u003cFn\u003e'\n  -- '.'\n   --- 'math'\n   --- 'pow'\n  -- '(1)'\n   --- 'q'\n - '^'\n  -- 'q'\n  -- 'q'\n : org.scijava.parsington.SyntaxTree\n```\n\n## Customization\n\nParsington supports various kinds of customization, including custom operators,\ncustom separator symbols, and even custom parsing of literals and/or other\nexpression elements. See the\n[TestExamples](src/test/java/org/scijava/parsington/TestExamples.java) for\nillustrations of these sorts of customizations in practice.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscijava%2Fparsington","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscijava%2Fparsington","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscijava%2Fparsington/lists"}