Skip to content

Commit

Permalink
Restructure API, update documentation
Browse files Browse the repository at this point in the history
Change structure of API to have more descriptive names.
Move abstracts and typedefs to separate files so now they
are children of main parsihax package.
Update README documentation.

Signed-off-by: Tomas Slusny <[email protected]>
  • Loading branch information
deathbeam committed Feb 13, 2017
1 parent 530a9ce commit 23edf51
Show file tree
Hide file tree
Showing 13 changed files with 290 additions and 280 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*.n
/.vscode/
/bin/
/dump/
/dump/
.zip
37 changes: 19 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# Parsihax
[![TravisCI Build Status](https://api.travis-ci.org/deathbeam/parsihax.svg?branch=master)](https://travis-ci.org/deathbeam/parsihax)
[![TravisCI Build Status][travis-img]][travis]

Parsihax is a small library for writing big parsers made up of lots of little parsers. The API is inspired by
[parsec][], [Promises/A+][promises-aplus] and [Parsimmon][parsimmon] (originally, Parsihax was just supposed to be
Parsimmon rewrite in Haxe).
[parsec][] and [Parsimmon][parsimmon] (originally, Parsihax was just supposed to be Parsimmon rewrite in Haxe).

### Installation

Install the library via [haxelib](http://lib.haxe.org/p/parsihax) (library manager that comes with any Haxe distribution).
Install the library via [haxelib][] (library manager that comes with any Haxe distribution).

```
haxelib install parsihax
Expand All @@ -16,7 +15,7 @@ haxelib install parsihax
## API Documentation

Haxe-generated API documentation is available at [documentation website][docs], or see the
[annotated source of `parsi.Hax.hx`.][parsihax]
[annotated source of `parsihax.Parser.hx`.][parsihax]

## Examples

Expand All @@ -26,12 +25,13 @@ See the [test][] directory for annotated examples of parsing JSON, simple Lisp-l
To use nice sugar syntax, simply add this to your Haxe file

```haxe
import parsi.Hax.*;
using parsi.Hax;
import parsihax.*;
import parsihax.Parser.*;
using parsihax.Parser;
```

A `Hax.Parser` parser is an abstract that represents an action on a stream of text, and the promise of either an
object yielded by that action on success or a message in case of failure. For example, `Hax.string('foo')` yields
A `ParseObject` parser is an abstract that represents an action on a stream of text, and the promise of either an
object yielded by that action on success or a message in case of failure. For example, `Parser.string('foo')` yields
the string `'foo'` if the beginning of the stream is `'foo'`, and otherwise fails.

The method `.map` is used to transform the yielded value. For example,
Expand Down Expand Up @@ -65,22 +65,23 @@ var result = a | b + c;
// operator to as
```

Getting `parse` from a `Hax.Parser` (or explicitly casting it to `Hax.Function` returns parsing function
`String -> ?Int -> Result<A>` (or just `Hax.Function`), that parses the string and returns a `Hax.Result`
Getting `apply` from a `ParseObject` (or explicitly casting it to `ParseFunction` returns parsing function
`String -> ?Int -> Result<A>` (or just `ParseFunction`), that parses the string and returns a `Hax.Result`
with a boolean `status` flag, indicating whether the parse succeeded. If it succeeded, the `value` attribute will
contain the yielded value. Otherwise, the `index` and `expected` attributes will contain the offset of the parse error,
and a sorted, unique array of messages indicating what was expected.

The error object can be passed along with the original source to `Hax.formatError` to obtain
The error object can be passed along with the original source to `Parser.formatError` to obtain
a human-readable error string.

Changing `Hax.Parser.parse` value changes `Hax.Parser` behaviour, but still keeps it's reference, what is
Changing `ParseObject.apply` value changes `ParseObject` behaviour, but still keeps it's reference, what is
really usefull in recursive parsers.

[docs]: https://deathbeam.github.io/parsihax/parsi/Hax.html
[parsihax]: https://github.com/deathbeam/parsihax/blob/master/src/parsi/Hax.hx
[test]: https://github.com/deathbeam/parsihax/tree/master/test/parsi

[promises-aplus]: https://promisesaplus.com/
[travis]: https://travis-ci.org/deathbeam/parsihax
[travis-img]: https://api.travis-ci.org/deathbeam/parsihax.svg?branch=master
[haxelib]: http://lib.haxe.org/p/parsihax
[docs]: https://nondev.io/parsihax/parsihax/Parser.html
[parsihax]: https://github.com/deathbeam/parsihax/blob/master/src/parsihax/Parser.hx
[test]: https://github.com/deathbeam/parsihax/tree/master/test/parsihax
[parsec]: https://hackage.haskell.org/package/parsec
[parsimmon]: https://github.com/jneen/parsimmon
4 changes: 2 additions & 2 deletions build.hxml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
-lib monax
-lib buddy
-dce full
-main Test
-main parsihax.Test
--each

-dce std
Expand Down Expand Up @@ -42,4 +42,4 @@
-java bin/java

--next
-cs bin/cs
-cs bin/cs
5 changes: 4 additions & 1 deletion doc.hxml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
-lib monax
-dce std
-cp src
parsi.Hax
parsihax.ParseFunction
parsihax.ParseObject
parsihax.ParseResult
parsihax.Parser
-xml bin/parsihax.xml
--next
-cmd haxelib run dox -o bin/api -i bin --title "Parsihax - API documentation" -D source-path https://github.com/deathbeam/parsihax/blob/master/src/
4 changes: 2 additions & 2 deletions haxelib.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"license": "MIT",
"tags": ["parser", "parsing", "cross", "utility"],
"description": "A monadic LL(infinity) parser combinator library for Haxe.",
"version": "1.0.0",
"version": "2.0.0",
"classPath": "src/",
"releasenote": "Fix global scope, simplify API, add operator overloading",
"releasenote": "Restructure API, update documentation",
"contributors": [ "deathbeam" ]
}
6 changes: 6 additions & 0 deletions src/parsihax/ParseFunction.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package parsihax;

/**
Parsing function created by chaining Parser combinators.
**/
typedef ParseFunction<A> = String -> ?Int -> ParseResult<A>;
55 changes: 55 additions & 0 deletions src/parsihax/ParseObject.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package parsihax;

import haxe.ds.Vector;

/**
The ParseObject object is a wrapper for a parser function.
Externally, you use one to parse a string by calling
`var result = SomeParseObject.apply('Me Me Me! Parse Me!');`
**/
abstract ParseObject<T>(Vector<ParseFunction<T>>) {
inline function new() this = new Vector(1);
@:to inline function get_apply() : ParseFunction<T> return this[0];
inline function set_apply(param : ParseFunction<T>) return this[0] = param;

/**
Getting `ParseObject.apply` from a parser (or explicitly casting it to
`ParseFunction` returns parsing function `String -> ?Int -> ParseResult<A>`
(or just `ParseFunction`), that parses the string and returns `ParseResult<A>`.
Changing `ParseObject.apply` value changes parser behaviour, but still keeps it's
reference, what is really usefull in recursive parsers.
**/
public var apply(get, set): ParseFunction<T>;

/**
Creates `ParseObject` from `ParseFunction`
**/
@:noUsing @:from static inline public function to<T>(v : ParseFunction<T>) : ParseObject<T> {
var ret = new ParseObject();
ret.apply = v;
return ret;
}

/**
Same as `Hax.then(l, r)`
**/
@:noUsing @:op(A + B) static inline public function opAdd<A, B>(l: ParseObject<A>, r: ParseObject<B>): ParseObject<B> {
return Parser.then(l, r);
}

/**
Same as `Hax.or(l, r)`
**/
@:noUsing @:op(A | B) static inline public function opOr<A>(l: ParseObject<A>, r: ParseObject<A>): ParseObject<A> {
return Parser.or(l, r);
}

/**
Same as `Hax.as(l, r)`
**/
@:noUsing @:op(A / B) static inline public function opDiv<A>(l: ParseObject<A>, r: String): ParseObject<A> {
return Parser.as(l, r);
}

}
38 changes: 38 additions & 0 deletions src/parsihax/ParseResult.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package parsihax;

/**
A structure with a boolean `status` flag, indicating whether the parse
succeeded. If it succeeded, the `value` attribute will contain the yielded
value. Otherwise, the `index` and `expected` attributes will contain the
offset of the parse error, and a sorted, unique array of messages indicating
what was expected.
The error structure can be passed along with the original source to
`Parser.formatError` to obtain a human-readable error string.
**/
typedef ParseResult<T> = {
/**
Flag, indicating whether the parse succeeded
**/
var status : Bool;

/**
Offset of the parse error (in case of failed parse)
**/
var index : Int;

/**
Yielded value of `Parser` (in case of successfull parse)
**/
var value : T;

/**
Offset of last parse
**/
var furthest : Int;

/**
A sorted, unique array of messages indicating what was expected (in case of failed parse)
**/
var expected : Array<String>;
}
Loading

0 comments on commit 23edf51

Please sign in to comment.