Giter VIP home page Giter VIP logo

vom's Introduction

vom

GitHub contributors GitHub issues PRs Welcome HitCount

vom is a rewrite of nom, which is a parser combinator library. It is written in V, hence the name.

Example

Hexadecimal color parser:

module main

import vom { is_hex_digit, tag, take_while_m_n, tuple }

struct Color {
        red   u8
        green u8
        blue  u8
}

fn from_hex(input string) u8 {
        return '0x${input}'.u8()
}

fn hex_primary(input string) !(string, string, int) {
        parser := take_while_m_n(2, 2, is_hex_digit)
        return parser(input)
}

fn hex_color(input string) !(string, Color) {
        discard := tag('#')
        hex_part, _, _ := discard(input)!
        parser := tuple([hex_primary, hex_primary, hex_primary])
        rest, output, _ := parser(hex_part)!
        red, green, blue := from_hex(output[0]), from_hex(output[1]), from_hex(output[2])
        return rest, Color{red, green, blue}
}

fn main() {
        _, color := hex_color('#2F14DF')!
        assert color == Color{47, 20, 223}
        println(color)
}

When will it reach 1.0?

There are some features I both need and want working in V before I will complete this library:

Generic return type for closures returned from functions

This is the only feature I absolutely need in order to finish this library. Without it, we're stuck with returning ?(string, string) instead of ?(string, T) from each parser, and thus can't construct an Ast with the library alone. That's currently something you need to do manually.

Generic type aliases

Currently this isn't implemented yet. Although it's not required in order to implement the features that are missing, it will make the codebase look horrible without because almost all of the functions depend on following:

type Fn = fn (string) ?(string, string)
type FnMany = fn (string) ?(string, []string)

And I need the last argument to be generic, because parsers could return other types such as int, token, []token etc. Although I could search and replace each entry manually, I'm too lazy to do that.

Functions that return closure that captures functions from function parameter

This is not a necessary issue either, but it would remove lots of boilerplate in the current code, for instance from sequence.v.

Adding this would turn following:

pub fn minimal(cond fn (int) bool) fn (int) bool {
	functions := [cond]
	return fn [functions] (input int) bool {
		cond := functions[0]
		return cond(input)
	}
}

Into this:

pub fn minimal(cond fn (int) bool) fn (int) bool {
	return fn [cond] (input int) bool {
		return cond(input)
	}
}

Call closure returned from function immediately

This is again not a mandatory feature for this library to work, but would be a nice addition. Instead of following code:

fn operator(input string, location Location) ?(string, Token) {
	parser := alt([tag('+'), tag('-'), tag('<')])
	rest, output := parser(input) ?
	return rest, Token{output, location, .operator}
}

We could write this instead, which is a very common pattern in nom:

fn operator(input string, location Location) ?(string, Token) {
	rest, output := alt([tag('+'), tag('-'), tag('<')])(input) ?
	return rest, Token{output, location, .operator}
}

Install

v install --git https://github.com/knarkzel/vom

Then import in your file like so:

import vom
rest, output := vom.digit1('123hello') ?
assert output == '123'
assert rest == 'hello'

There are examples in the examples/ folder.

Why use vom?

  • The parsers are small and easy to write
  • The parsers components are easy to reuse
  • The parsers components are easy to test separately
  • The parser combination code looks close to the grammar you would have written
  • You can build partial parsers, specific to the data you need at the moment, and ignore the rest

Resources

vom's People

Contributors

knarkzel avatar kbkpbot avatar spytheman avatar

Stargazers

André Luiz avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.