Skip to content

Commit

Permalink
move section of Parsby.new to bottom...
Browse files Browse the repository at this point in the history
since it probably raises more questions than it answers.
  • Loading branch information
jolmg committed Sep 25, 2020
1 parent 3bad3cb commit 26ca984
Showing 1 changed file with 30 additions and 30 deletions.
60 changes: 30 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ Parser combinator library for Ruby, based on Haskell's Parsec.
- [Introduction](#introduction)
- [Some commonly used combinators](#some-commonly-used-combinators)
- [Defining combinators](#defining-combinators)
- [`Parsby.new`](#parsbynew)
- [Defining parsers as modules](#defining-parsers-as-modules)
- [`ExpectationFailed`](#expectationfailed)
- [Cleaning up the parse tree for the trace](#cleaning-up-the-parse-tree-for-the-trace)
- [`splicer.start` combinator](#splicerstart-combinator)
- [Recursive parsers with `lazy`](#recursive-parsers-with-lazy)
- [Parsing left-recursive languages with `reduce` combinator](#parsing-leftrecursive-languages-with-reduce-combinator)
- [`Parsby.new`](#parsbynew)
- [Parsing from a string, a file, a pipe, a socket, ...](#parsing-from-a-string-a-file-a-pipe-a-socket-)
- [Comparing with Haskell's Parsec](#comparing-with-haskells-parsec)
- [Development](#development)
Expand Down Expand Up @@ -199,35 +199,6 @@ between(lit("<"), lit(">"), lit("foo")).label.to_s
=> "<unknown>"
```

## `Parsby.new`

Now, normally one ought to be able to define parsers using just
combinators, but there are times when one might need more control. For
those times, the most raw way to define a parser is using `Parsby.new`.

Here's `lit` as an example:

```ruby
define_combinator :lit, wrap: false do |e, case_sensitive: true|
Parsby.new do |c|
a = c.bio.read e.length
if case_sensitive ? a == e : a.to_s.downcase == e.downcase
a
else
raise ExpectationFailed.new c
end
end
end
```

It takes a string argument for what it `e`xpects to parse, and returns what
was `a`ctually parsed if it matches the expectation.

The block parameter `c` is a `Parsby::Context`. `c.bio` holds a
`Parsby::BackedIO`. The `parse` method of `Parsby` objects accepts ideally
any `IO` (and `String`s, which it turns into `StringIO`) and then wraps
them with `BackedIO` to give the `IO` the ability to backtrack.

## Defining parsers as modules

The typical pattern I use is something like this:
Expand Down Expand Up @@ -635,6 +606,35 @@ returning the result of the last successful parse.
In effect, we're parsing left operands bottom-up and right operands
top-down.

## `Parsby.new`

Normally one ought to be able to define parsers using just combinators, but
there are times when one might need more control. For those times, the most
raw way to define a parser is using `Parsby.new`.

Here's `lit` as an example:

```ruby
define_combinator :lit, wrap: false do |e, case_sensitive: true|
Parsby.new do |c|
a = c.bio.read e.length
if case_sensitive ? a == e : a.to_s.downcase == e.downcase
a
else
raise ExpectationFailed.new c
end
end
end
```

It takes a string argument for what it `e`xpects to parse, and returns what
was `a`ctually parsed if it matches the expectation.

The block parameter `c` is a `Parsby::Context`. `c.bio` holds a
`Parsby::BackedIO`. The `parse` method of `Parsby` objects accepts ideally
any `IO` (and `String`s, which it turns into `StringIO`) and then wraps
them with `BackedIO` to give the `IO` the ability to backtrack.

## Parsing from a string, a file, a pipe, a socket, ...

Any `IO` ought to work (unit tests currently have only checked pipes,
Expand Down

0 comments on commit 26ca984

Please sign in to comment.