Skip to content

Commit

Permalink
🚧 wip refactor how subparsers behave
Browse files Browse the repository at this point in the history
  • Loading branch information
nabeelvalley committed Jul 19, 2024
1 parent 32e4fe6 commit 2ef3e6f
Show file tree
Hide file tree
Showing 12 changed files with 364 additions and 252 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
# parsing
# parz

> Learning about Parser Combinators using [The YouTube Series by Low Byte Productions](https://www.youtube.com/playlist?list=PLP29wDx6QmW5yfO1LAgO8kU3aQEj8SIrU)
[![Package Version](https://img.shields.io/hexpm/v/parsing)](https://hex.pm/packages/parsing)
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/parsing/)
[![Package Version](https://img.shields.io/hexpm/v/parz)](https://hex.pm/packages/parz)
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/parz/)

```sh
gleam add parsing
gleam add parz
```

```gleam
import parsing
import parz
pub fn main() {
// TODO: An example of the project in use
}
```

Further documentation can be found at <https://hexdocs.pm/parsing>.
Further documentation can be found at <https://hexdocs.pm/parz>.

## Development

Expand Down
2 changes: 1 addition & 1 deletion gleam.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name = "parsing"
name = "parz"
version = "1.0.0"

# Fill out these fields if you intend to generate HTML documentation or publish
Expand Down
233 changes: 0 additions & 233 deletions src/parsing.gleam

This file was deleted.

3 changes: 3 additions & 0 deletions src/parz.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub fn run(parser, input) {
parser(input)
}
106 changes: 106 additions & 0 deletions src/parz/combinators.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import gleam/list
import parz/types.{type Parser, type ParserState, ParserState}
import parz/util.{tap}

fn sequence_rec(parsers, state, acc) {
case parsers {
[] -> Ok([])
[first, ..rest] ->
case first(state) {
Error(err) -> Error(err)
Ok(ok) ->
case sequence_rec(rest, ok, acc) {
Error(err) -> Error(err)
Ok(rec) -> Ok([ok, ..rec])
}
}
}
}

pub fn sequence(parsers) {
fn(state) { sequence_rec(parsers, state, []) }
}

pub fn choice(parsers: List(Parser)) {
fn(state) {
case parsers {
[] -> Error("No more choices provided")
[first, ..rest] ->
case first(state) {
Ok(ok) -> Ok(ok)
Error(err) ->
case rest {
[] -> Error(err)
_ -> choice(rest)(state)
}
}
}
}
}

pub fn right(l: Parser, r: Parser) -> Parser {
fn(state) {
case l(state) {
Error(err) -> Error(err)
Ok(okl) ->
case r(okl.remaining) {
Error(err) -> Error(err)
Ok(okr) -> Ok(ParserState(okr.matched, okr.remaining))
}
}
}
}

pub fn left(l: Parser, r: Parser) -> Parser {
fn(state) {
case l(state) {
Error(err) -> Error(err)
Ok(okl) ->
case r(okl.remaining) {
Error(err) -> Error(err)
Ok(okr) -> Ok(ParserState(okl.matched, okr.remaining))
}
}
}
}

pub fn between(l: Parser, keep: Parser, r: Parser) -> Parser {
fn(state) {
case l(state) {
Error(err) -> Error(err)
Ok(okl) ->
case left(keep, r)(okl.remaining) {
Error(err) -> Error(err)
Ok(okr) -> Ok(ParserState(okr.matched, okr.remaining))
}
}
}
}

fn many_rec(parser: Parser, state, acc) {
case parser(state) {
Error(err) -> Error(err)
Ok(ok) -> {
case many_rec(parser, ok.remaining, acc) {
Error(_) -> Ok(#([ok.matched], ok.remaining))
Ok(rec) -> {
let #(matches, remaining) = rec
Ok(#([ok.matched, ..matches], remaining))
}
}
}
}
}

pub fn many1(parser: Parser) {
fn(state) { many_rec(parser, state, []) }
}

pub fn many(parser: Parser) {
fn(state) {
case many1(parser)(state) {
Error(_) -> Ok(#([], state))
Ok(ok) -> Ok(ok)
}
}
}
Loading

0 comments on commit 2ef3e6f

Please sign in to comment.