{"id":13565414,"url":"https://github.com/petitparser/java-petitparser","last_synced_at":"2025-10-24T18:03:18.464Z","repository":{"id":2571396,"uuid":"3551455","full_name":"petitparser/java-petitparser","owner":"petitparser","description":"Dynamic parser combinators in Java.","archived":false,"fork":false,"pushed_at":"2025-10-06T16:05:17.000Z","size":2716,"stargazers_count":176,"open_issues_count":0,"forks_count":35,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-10-06T17:18:36.331Z","etag":null,"topics":["java","parser","parser-combinator","parser-framework","parser-library","parsing-expression-grammar","petitparser"],"latest_commit_sha":null,"homepage":"https://jitpack.io/#petitparser/java-petitparser","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/petitparser.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2012-02-26T11:07:18.000Z","updated_at":"2025-10-06T16:05:21.000Z","dependencies_parsed_at":"2023-12-25T13:04:26.032Z","dependency_job_id":"30c2b639-5e8d-43cb-9696-20e3b74f2bc9","html_url":"https://github.com/petitparser/java-petitparser","commit_stats":{"total_commits":350,"total_committers":10,"mean_commits":35.0,"dds":"0.10857142857142854","last_synced_commit":"159d1ec7bb52854060d9178a2ef76f2a22011ffd"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/petitparser/java-petitparser","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/petitparser%2Fjava-petitparser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/petitparser%2Fjava-petitparser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/petitparser%2Fjava-petitparser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/petitparser%2Fjava-petitparser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/petitparser","download_url":"https://codeload.github.com/petitparser/java-petitparser/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/petitparser%2Fjava-petitparser/sbom","scorecard":{"id":355279,"data":{"date":"2025-08-11","repo":{"name":"github.com/petitparser/java-petitparser","commit":"aa10548815e1865f16c75e7dc5c3584ae7c762af"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/maven.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 1/11 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/maven.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/petitparser/java-petitparser/maven.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/maven.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/petitparser/java-petitparser/maven.yml/main?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 20 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-18T09:23:06.187Z","repository_id":2571396,"created_at":"2025-08-18T09:23:06.187Z","updated_at":"2025-08-18T09:23:06.187Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280841249,"owners_count":26400401,"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","status":"online","status_checked_at":"2025-10-24T02:00:06.418Z","response_time":73,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["java","parser","parser-combinator","parser-framework","parser-library","parsing-expression-grammar","petitparser"],"created_at":"2024-08-01T13:01:46.465Z","updated_at":"2025-10-24T18:03:18.424Z","avatar_url":"https://github.com/petitparser.png","language":"Java","readme":"PetitParser for Java\n====================\n\n[![Release Status](https://jitpack.io/v/petitparser/java-petitparser.svg)](https://jitpack.io/#petitparser/java-petitparser)\n[![Java CI](https://github.com/petitparser/java-petitparser/actions/workflows/maven.yml/badge.svg)](https://github.com/petitparser/java-petitparser/actions/workflows/maven.yml)\n[![GitHub Issues](https://img.shields.io/github/issues/petitparser/java-petitparser.svg)](https://github.com/petitparser/java-petitparser/issues)\n[![GitHub Forks](https://img.shields.io/github/forks/petitparser/java-petitparser.svg)](https://github.com/petitparser/java-petitparser/network)\n[![GitHub Stars](https://img.shields.io/github/stars/petitparser/java-petitparser.svg)](https://github.com/petitparser/java-petitparser/stargazers)\n[![GitHub License](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/petitparser/java-petitparser/master/LICENSE)\n\nGrammars for programming languages are traditionally specified statically. They\nare hard to compose and reuse due to ambiguities that inevitably arise.\nPetitParser combines ideas\nfrom [scannnerless parsing](https://en.wikipedia.org/wiki/Scannerless_parsing)\n, [parser combinators](https://en.wikipedia.org/wiki/Parser_combinator)\n, [parsing expression grammars](https://en.wikipedia.org/wiki/Parsing_expression_grammar) (\nPEG) and packrat parsers to model grammars and parsers as objects that can be\nreconfigured dynamically.\n\nThis library is open source, stable and well tested. Development happens\non [GitHub](https://github.com/petitparser/java-petitparser). Feel free to\nreport issues or create a pull-request there. General questions are best asked\non [StackOverflow](http://stackoverflow.com/questions/tagged/petitparser+java).\n\n\nInstallation\n------------\n\nTo include the latest release in your Java project follow the instructions\nbelow.\n\n### Maven JitPack\n\nJitPack requires you to first append the repository to your `pom.xml` file:\n\n```xml\n\u003crepository\u003e\n  \u003cid\u003ejitpack.io\u003c/id\u003e\n  \u003curl\u003ehttps://jitpack.io\u003c/url\u003e\n\u003c/repository\u003e\n```\n\nTo depend on the core library, add the following dependency:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.github.petitparser.java-petitparser\u003c/groupId\u003e\n  \u003cartifactId\u003epetitparser-core\u003c/artifactId\u003e\n  \u003cversion\u003e2.4.2\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nTo also include the example grammars, use the following dependency:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.github.petitparser\u003c/groupId\u003e\n  \u003cartifactId\u003ejava-petitparser\u003c/artifactId\u003e\n  \u003cversion\u003e2.4.2\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nInstructions for alternative build systems such as Gradle, SBT, or Leiningen you\ncan find on [JitPack](https://jitpack.io/#petitparser/java-petitparser).\n\n### Bazel\n\nAlternatively, if you'd like the latest code clone the repository:\n\n```bash\ngit clone https://github.com/petitparser/java-petitparser.git\ncd java-petitparser\ngit checkout master\n```\n\nThen build with [Bazel](http://bazel.io/):\n\n```bash\nbazel build ...:all\nbazel test ...:all\n```\n\n### Maven Central (deprecated)\n\n\u003e [!WARNING]\n\u003e Version 2.4.0 is the last version of this package on Maven Central.\n\u003e Maintaining the Maven Central package is too much of a hassle, please\n\u003e migrate to one of the other options described above.\n\nTo depend on the core library, add the following dependency to your `pom.xml`\nfile:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.github.petitparser\u003c/groupId\u003e\n  \u003cartifactId\u003epetitparser-core\u003c/artifactId\u003e\n  \u003cversion\u003e2.4.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nTo also include the example grammars, use the following dependency:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.github.petitparser\u003c/groupId\u003e\n  \u003cartifactId\u003epetitparser\u003c/artifactId\u003e\n  \u003cversion\u003e2.4.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nInstructions for alternative build systems you can find\non [Maven Central](https://search.maven.org/artifact/com.github.petitparser/petitparser-core)\n\nTutorial\n--------\n\n### Writing a Simple Grammar\n\nWriting grammars with PetitParser is simple as writing Java code. For example,\nto write a grammar that can parse identifiers that start with a letter followed\nby zero or more letter or digits is defined as follows:\n\n```java\nimport static org.petitparser.parser.primitive.CharacterParser.*;\n\nclass Example {\n  public static void main(String[] arguments) {\n    Parser id = letter().seq(letter().or(digit()).star());\n    ...\n  }\n}\n```\n\nIf you look at the object `id` in the debugger, you'll notice that the code\nabove builds a tree of parser objects:\n\n- `SequenceParser`: This parser accepts a sequence of parsers.\n    - `CharacterParser`: This parser accepts a single letter.\n    - `PossessiveRepeatingParser`: This parser accepts zero or more times\n      another parser.\n        - `ChoiceParser`: This parser accepts a single word character.\n            - `CharacterParser`: This parser accepts a single letter.\n            - `CharacterParser`: This parser accepts a single digit.\n\n### Parsing Some Input\n\nTo actually parse a `String` we can use the method `Parser#parse(String)`:\n\n```java\nResult id1 = id.parse(\"yeah\");\nResult id2 = id.parse(\"f12\");\n```\n\nThe method `parse` returns `Result`, which is either an instance of `Success`\nor `Failure`. In both examples above we are successful and can retrieve the\nparse result using `Success#get()`:\n\n```java\nSystem.out.println(id1.get());  // ['y', ['e', 'a', 'h']]\n    System.out.\n\nprintln(id2.get());  // ['f', ['1', '2']]\n```\n\nWhile it seems odd to get these nested arrays with characters as a return value,\nthis is the default decomposition of the input into a parse tree. We'll see in a\nwhile how that can be customized.\n\nIf we try to parse something invalid we get an instance of `Failure` as an\nanswer and we can retrieve a descriptive error message\nusing `Failure#getMessage()`:\n\n```java\nResult id3 = id.parse('123');\nSystem.out.\n\nprintln(id3.getMessage());  // \"letter expected\"\n    System.out.\n\nprintln(id3.getPosition());  // 0\n```\n\nTrying to retrieve the parse result by calling `Failure#get()` would throw the\nexception `ParseError`. `Result#isSuccess()` and `Result#isFailure()` can be\nused to decide if the parse was successful.\n\nIf you are only interested if a given string matches or not you can use the\nhelper method `Parser#accept(String)`:\n\n```java\nSystem.out.println(id.accept(\"foo\"));  // true\n    System.out.\n\nprintln(id.accept(\"123\"));  // false\n```\n\n### Different Kinds of Parsers\n\nPetitParser provide a large set of ready-made parser that you can compose to\nconsume and transform arbitrarily complex languages. The terminal parsers are\nthe most simple ones. We've already seen a few of those:\n\n- `CharacterParser.of('a')` parses the character _a_.\n- `StringParser.of(\"abc\")` parses the string _abc_.\n- `CharacterParser.any()` parses any character.\n- `CharacterParser.digit()` parses any digit from _0_ to _9_.\n- `CharacterParser.letter()` parses any letter from _a_ to _z_ and _A_ to _Z_.\n- `CharacterParser.word()` parses any letter or digit.\n\nMany other parsers are available in `CharacterParser` and `StringParser`.\n\nSo instead of using the letter and digit predicate, we could have written our\nidentifier parser like this:\n\n```java\nParser id = letter().seq(word().star());\n```\n\nThe next set of parsers are used to combine other parsers together:\n\n- `p1.seq(p2)` parses `p1` followed by `p2` (sequence).\n- `p1.or(p2)` parses `p1`, if that doesn't work parses `p2` (ordered choice).\n- `p.star()` parses `p` zero or more times.\n- `p.plus()` parses `p` one or more times.\n- `p.optional()` parses `p`, if possible.\n- `p.and()` parses `p`, but does not consume its input.\n- `p.not()` parses `p` and succeed when p fails, but does not consume its input.\n- `p.end()` parses `p` and succeed at the end of the input.\n\nTo attach an action or transformation to a parser we can use the following\nmethods:\n\n- `p.map(value -\u003e ...)` performs the transformation given the function.\n- `p.pick(n)` returns the `n`-th element of the list `p` returns.\n- `p.flatten()` creates a string from the result of `p`.\n- `p.token()` creates a token from the result of `p`.\n- `p.trim()` trims whitespaces before and after `p`.\n\nTo return a string of the parsed identifier, we can modify our parser like this:\n\n```java\nParser id = letter().seq(word().star()).flatten();\n```\n\nTo conveniently find all matches in a given input string you can\nuse `Parser#matchesSkipping(String)`:\n\n```java\nList\u003cObject\u003e matches = id.matchesSkipping(\"foo 123 bar4\");\n    System.out.\n\nprintln(matches);  // [\"foo\", \"bar4\"]\n```\n\nThese are the basic elements to build parsers. There are a few more well\ndocumented and tested factory methods in the `Parser` class. If you want, browse\ntheir documentation and tests.\n\n### Writing a More Complicated Grammar\n\nNow we are able to write a more complicated grammar for evaluating simple\narithmetic expressions. Within a file we start with the grammar for a number (\nactually an integer):\n\n```java\nParser number = digit().plus().flatten().trim().map((String value) -\u003e Integer.parseInt(value));\n```\n\nThen we define the productions for addition and multiplication in order of\nprecedence. Note that we instantiate the productions with undefined parsers\nupfront, because they recursively refer to each other. Later on we can resolve\nthis recursion by setting their reference:\n\n```java\nSettableParser term = SettableParser.undefined();\nSettableParser prod = SettableParser.undefined();\nSettableParser prim = SettableParser.undefined();\n\nterm.\n\nset(prod.seq(of('+').\n\ntrim()).\n\nseq(term).\n\nmap((List\u003cInteger\u003e values) -\u003e{\n    return values.\n\nget(0) +values.\n\nget(2);\n}).\n\nor(prod));\n    prod.\n\nset(prim.seq(of('*').\n\ntrim()).\n\nseq(prod).\n\nmap((List\u003cInteger\u003e values) -\u003e{\n    return values.\n\nget(0) *values.\n\nget(2);\n}).\n\nor(prim));\n    prim.\n\nset((of('(').\n\ntrim().\n\nseq(term).\n\nseq(of(')').\n\ntrim())).\n\nmap((List\u003cInteger\u003e values) -\u003e{\n    return values.\n\nget(1);\n}).\n\nor(number));\n```\n\nTo make sure that our parser consumes all input we wrap it with the `end()`\nparser into the start production:\n\n```java\nParser start = term.end();\n```\n\nThat's it, now we can test our parser and evaluator:\n\n```java\nSystem.out.println(start.parse(\"1 + 2 * 3\").\n\nget());  // 7\n    System.out.\n\nprintln(start.parse(\"(1 + 2) * 3\").\n\nget());  // 9\n```\n\nAs an exercise we could extend the parser to also accept negative numbers and\nfloating point numbers, not only integers. Furthermore it would be useful to\nsupport subtraction and division as well. All these features\ncan be added with a few lines of PetitParser code.\n\n### Using the Expression Builder\n\nWriting such expression parsers is pretty common and can be quite tricky to get\nright. To simplify things, PetitParser comes with a builder that can help you to\ndefine such grammars easily. It supports the definition of operator precedence;\nand prefix, postfix, left- and right-associative operators.\n\nThe following code creates the empty expression builder:\n\n```java\nExpressionBuilder builder = new ExpressionBuilder();\n```\n\nThen we define the operator-groups in descending precedence. The highest\nprecedence are the literal numbers themselves. This time we accept floating\npoint numbers, not just integers. In the same group we add support for\nparenthesis:\n\n```java\nbuilder.group()\n  .\n\nprimitive(digit().\n\nplus().\n\nseq(of('.')\n      .\n\nseq(digit().\n\nplus()).\n\noptional())\n    .\n\nflatten().\n\ntrim().\n\nmap(Double::parseDouble))\n    .\n\nwrapper(of('(').\n\ntrim(),of(')').\n\ntrim(),\n      (\nList\u003cDouble\u003e values)-\u003evalues.\n\nget(1));\n```\n\nThen come the normal arithmetic operators. Note, that the action blocks receive\nboth, the terms and the parsed operator in the order they appear in the parsed\ninput:\n\n```java\n// negation is a prefix operator\nbuilder.group()\n  .\n\nprefix(of('-').\n\ntrim(), (\nList\u003cDouble\u003e values)-\u003e-values.\n\nget(1));\n\n// power is right-associative\n    builder.\n\ngroup()\n  .\n\nright(of('^').\n\ntrim(), (\nList\u003cDouble\u003e values)-\u003eMath.\n\npow(values.get(0),values.\n\nget(2)));\n\n// multiplication and addition are left-associative\n    builder.\n\ngroup()\n  .\n\nleft(of('*').\n\ntrim(), (\nList\u003cDouble\u003e values)-\u003evalues.\n\nget(0) *values.\n\nget(2))\n    .\n\nleft(of('/').\n\ntrim(), (\nList\u003cDouble\u003e values)-\u003evalues.\n\nget(0) /values.\n\nget(2));\n    builder.\n\ngroup()\n  .\n\nleft(of('+').\n\ntrim(), (\nList\u003cDouble\u003e values)-\u003evalues.\n\nget(0) +values.\n\nget(2))\n    .\n\nleft(of('-').\n\ntrim(), (\nList\u003cDouble\u003e values)-\u003evalues.\n\nget(0) -values.\n\nget(2));\n```\n\nFinally we can build the parser:\n\n```java\nParser parser = builder.build().end();\n```\n\nAfter executing the above code we get an efficient parser that correctly\nevaluates expressions like:\n\n```java\nparser.parse(\"-8\");      // -8\nparser.\n\nparse(\"1+2*3\");   // 7\nparser.\n\nparse(\"1*2+3\");   // 5\nparser.\n\nparse(\"8/4/2\");   // 1\nparser.\n\nparse(\"2^2^3\");   // 256\n```\n\nYou can find this example as test case\nhere: [ExamplesTest.java](petitparser-core/src/test/java/org/petitparser/ExamplesTest.java)\n\nMisc\n----\n\n### Examples\n\nThe package comes with a large collections of grammars and language experiments\nready to explore:\n\n- `petitparser-json` contains a complete JSON grammar and parser.\n- `petitparser-xml` contains a complete XML grammar and parser.\n- `petitparser-smalltalk` contains a complete Smalltalk parser.\n\n### History\n\nPetitParser was originally implemented\nin [Smalltalk](http://scg.unibe.ch/research/helvetia/petitparser). Later on, as\na mean to learn these languages, I reimplemented PetitParser\nin [Java](https://github.com/petitparser/java-petitparser)\nand [Dart](https://github.com/petitparser/dart-petitparser). The implementations\nare very similar in their API and the supported features. If possible, the\nimplementations adopt best practises of the target language.\n\n### Implementations\n\n- [Dart](https://github.com/petitparser/dart-petitparser)\n- [Java](https://github.com/petitparser/java-petitparser)\n- [PHP](https://github.com/mindplay-dk/petitparserphp)\n- [Smalltalk](http://scg.unibe.ch/research/helvetia/petitparser)\n- [Swift](https://github.com/philipparndt/swift-petitparser)\n- [TypeScript](https://github.com/mindplay-dk/petitparser-ts)\n\n### License\n\nThe MIT License,\nsee [LICENSE](https://raw.githubusercontent.com/petitparser/java-petitparser/master/LICENSE)\n.\n","funding_links":[],"categories":["Java","Projects built with Bazel","\u003ca name=\"Java\"\u003e\u003c/a\u003eJava"],"sub_categories":["Google projects"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpetitparser%2Fjava-petitparser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpetitparser%2Fjava-petitparser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpetitparser%2Fjava-petitparser/lists"}