Skip to content

Commit

Permalink
Update README
Browse files Browse the repository at this point in the history
  • Loading branch information
J-F-Liu committed Aug 4, 2020
1 parent 286828f commit dbbe517
Showing 1 changed file with 44 additions and 43 deletions.
87 changes: 44 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,46 +38,47 @@ Aside from build issues (and the usual issues around error messages and debuggab

## List of predefined parsers and combinators

|Basic Parsers|Description|
| --- | --- |
|empty()|Always succeeds, consume no input.|
|end() |Match end of input.|
|sym(t)|Match a single terminal symbol *t*.|
|seq(s) |Match sequence of symbols.|
|list(p,s) |Match list of *p*, separated by *s*.|
|one_of(set) |Success when current input symbol is one of the set.|
|none_of(set)|Success when current input symbol is none of the set.|
|is_a(predicate) |Success when predicate return true on current input symbol.|
|not_a(predicate)|Success when predicate return false on current input symbol.|
|take(n)|Read *n* symbols.|
|skip(n)|Skip *n* symbols.|
|call(pf)|Call a parser factory, can be used to create recursive parsers.|

|Parser Combinators|Description|
| --- | --- |
| p | q | Match p or q, return result of the first success. |
| p + q | Match p and q, if both succeed return a pair of results. |
| p - q | Match p and q, if both succeed return result of p. |
| p * q | Match p and q, if both succeed return result of q. |
| p >> q | Parse p and get result P, then parse q and return result of q(P). |
| -p | Success when p succeeds, doesn't consume input. |
| !p | Success when p fails, doesn't consume input. |
|p.opt()|Make parser optional. Returns an `Option`.|
|p.repeat(m..n)| `p.repeat(0..)` repeat p zero or more times<br>`p.repeat(1..)` repeat p one or more times<br>`p.repeat(1..4)` match p at least 1 and at most 3 times<br>`p.repeat(5)` repeat p exactly 5 times|
|p.map(f)|Convert parser result to desired value.|
|p.convert(f)|Convert parser result to desired value, fails in case of conversion error.|
|p.pos() |Get input position after matching p.|
|p.collect()|Collect all matched input symbols.|
|p.discard()|Discard parser output.|
|p.name(_)|Give parser a name to identify parsing errors.|
|p.expect(_)|Mark parser as expected, abort early when failed in ordered choice.|
| Basic Parsers | Description |
| ---------------- | --------------------------------------------------------------- |
| empty() | Always succeeds, consume no input. |
| end() | Match end of input. |
| sym(t) | Match a single terminal symbol _t_. |
| seq(s) | Match sequence of symbols. |
| list(p,s) | Match list of _p_, separated by _s_. |
| one_of(set) | Success when current input symbol is one of the set. |
| none_of(set) | Success when current input symbol is none of the set. |
| is_a(predicate) | Success when predicate return true on current input symbol. |
| not_a(predicate) | Success when predicate return false on current input symbol. |
| take(n) | Read _n_ symbols. |
| skip(n) | Skip _n_ symbols. |
| call(pf) | Call a parser factory, can be used to create recursive parsers. |

| Parser Combinators | Description |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| p &#124; q | Match p or q, return result of the first success. |
| p + q | Match p and q, if both succeed return a pair of results. |
| p - q | Match p and q, if both succeed return result of p. |
| p \* q | Match p and q, if both succeed return result of q. |
| p >> q | Parse p and get result P, then parse q and return result of q(P). |
| -p | Success when p succeeds, doesn't consume input. |
| !p | Success when p fails, doesn't consume input. |
| p.opt() | Make parser optional. Returns an `Option`. |
| p.repeat(m..n) | `p.repeat(0..)` repeat p zero or more times<br>`p.repeat(1..)` repeat p one or more times<br>`p.repeat(1..4)` match p at least 1 and at most 3 times<br>`p.repeat(5)` repeat p exactly 5 times |
| p.map(f) | Convert parser result to desired value. |
| p.convert(f) | Convert parser result to desired value, fails in case of conversion error. |
| p.pos() | Get input position after matching p. |
| p.collect() | Collect all matched input symbols. |
| p.discard() | Discard parser output. |
| p.name(\_) | Give parser a name to identify parsing errors. |
| p.expect(\_) | Mark parser as expected, abort early when failed in ordered choice. |

The choice of operators is established by their operator precedence, arity and "meaning".
Use `*` to ignore the result of first operand on the start of an expression, `+` and `-` can fulfill the need on the rest of the expression.

For example, `A * B * C - D + E - F` will return the results of C and E as a pair.

## Example code

```rust
extern crate pom;
use pom::parser::*;
Expand All @@ -89,6 +90,7 @@ assert_eq!(output, Ok( (b'b', vec![b'd', b'e']) ) );
```

### Example JSON parser

```rust
extern crate pom;
use pom::parser::*;
Expand Down Expand Up @@ -175,27 +177,28 @@ fn main() {
println!("{:?}", json().parse(input));
}
```

You can run this example with the following command:

```
cargo run --example json
```

## Benchmark

| Parser | Time to parse the same JSON file |
|------------------|----------------------------------|
| pom: json_byte | 621,319 ns/iter (+/- 20,318) |
| pom: json_char | 627,110 ns/iter (+/- 11,463) |
| [pest](https://github.com/dragostis/pest): json_char | 13,359 ns/iter (+/- 811)|

| Parser | Time to parse the same JSON file |
| ---------------------------------------------------- | -------------------------------- |
| pom: json_byte | 621,319 ns/iter (+/- 20,318) |
| pom: json_char | 627,110 ns/iter (+/- 11,463) |
| [pest](https://github.com/dragostis/pest): json_char | 13,359 ns/iter (+/- 811) |

### Lifetimes and files

String literals have a static lifetime so they can work with the static version of Parser
imported from `pom::Parser`. Input read from a file has a shorter lifetime. In this case you
should import `pom::parser::Parser` and declare lifetimes on your parser functions. So

```javascript
```rust
fn space() -> Parser<u8, ()> {
one_of(b" \t\r\n").repeat(0..).discard()
}
Expand All @@ -204,10 +207,8 @@ fn space() -> Parser<u8, ()> {

would become

```javascript
```rust
fn space<'a>() -> Parser<'a, u8, ()> {
one_of(b" \t\r\n").repeat(0..).discard()
}
```


0 comments on commit dbbe517

Please sign in to comment.