GithubHelp home page GithubHelp logo

shellyln / takenoco Goto Github PK

View Code? Open in Web Editor NEW
9.0 1.0 1.0 119 KB

A parser combinator library for Go.

License: MIT License

Makefile 4.19% Go 94.43% HTML 0.80% JavaScript 0.59%
parser-combinator parser-framework parser-library golang go parser production-rules production-rules-engine lexer lexer-parser

takenoco's Introduction

๐ŸŽ‹ Takenoco

Parser Combinator Library for Go.
A framework for making easy use of parser combinators and production rules.

Test release Go version

logo


๐Ÿช„ Introduction

Introduction to takenoco, a parser combinator library for Go

๐Ÿงญ Examples

๐Ÿš€ Getting started

Define the parser:

package csv

import (
    "errors"
    "strconv"

    . "github.com/shellyln/takenoco/base"
    . "github.com/shellyln/takenoco/string"
)

var (
    // Comma and line break characters
    cellBreakCharacters []string
    documentParser      ParserFn
)

func init() {
    cellBreakCharacters = make([]string, 0, len(LineBreakCharacters)+1)
    cellBreakCharacters = append(cellBreakCharacters, ",")
    cellBreakCharacters = append(cellBreakCharacters, LineBreakCharacters...)
    documentParser = document()
}

// Remove the resulting AST.
func erase(fn ParserFn) ParserFn {
    return Trans(fn, Erase)
}

// Whitespaces
func sp() ParserFn {
    return erase(ZeroOrMoreTimes(WhitespaceNoLineBreak()))
}

func quotedCell() ParserFn {
    return Trans(
        OneOrMoreTimes(
            FlatGroup(
                sp(),
                erase(Seq("\"")),
                ZeroOrMoreTimes(
                    First(
                        erase(Seq("\"\"")),
                        CharClassN("\""),
                    ),
                ),
                First(
                    erase(Seq("\"")),
                    FlatGroup(End(), Error("Unexpected EOF")),
                ),
                sp(),
            ),
        ),
        Concat,
    )
}

func cell() ParserFn {
    return Trans(
        ZeroOrMoreTimes(CharClassN(cellBreakCharacters...)),
        Trim,
    )
}

// Convert AST to array data. (line)
func lineTransform(_ ParserContext, asts AstSlice) (AstSlice, error) {
    w := make([]string, len(asts))
    length := len(asts)

    for i := 0; i < length; i++ {
        w[i] = asts[i].Value.(string)
    }

    return AstSlice{{
        ClassName: "*Line",
        Type:      AstType_Any,
        Value:     w,
    }}, nil
}

func line() ParserFn {
    return Trans(
        FlatGroup(
            ZeroOrMoreTimes(
                First(quotedCell(), cell()),
                erase(Seq(",")),
            ),
            First(quotedCell(), cell()),
        ),
        lineTransform,
    )
}

// Convert AST to array data. (Entire document)
func documentTransform(_ ParserContext, asts AstSlice) (AstSlice, error) {
    length := len(asts)
    w := make([][]string, length)

    for i := 0; i < length; i++ {
        w[i] = asts[i].Value.([]string)
    }
    for i := length - 1; i >= 0; i-- {
        if len(w[i]) == 0 || len(w[i]) == 1 && w[i][0] == "" {
            w = w[:i]
        } else {
            break
        }
    }

    return AstSlice{{
        ClassName: "*Document",
        Type:      AstType_Any,
        Value:     w,
    }}, nil
}

func document() ParserFn {
    return Trans(
        FlatGroup(
            ZeroOrMoreTimes(
                line(),
                erase(OneOrMoreTimes(LineBreak())),
            ),
            line(),
            End(),
        ),
        documentTransform,
    )
}

func Parse(s string) ([][]string, error) {
    out, err := documentParser(*NewStringParserContext(s))
    if err != nil {
        return nil, err
    } else {
        if out.MatchStatus == MatchStatus_Matched {
            return out.AstStack[0].Value.([][]string), nil
        } else {
            return nil, errors.New("Parse failed at " + strconv.Itoa(out.SourcePosition.Position))
        }
    }
}

Use the parser:

package main

import (
    "fmt"
    "os"

    csv "github.com/shellyln/takenoco/_examples/csv"
)

func main() {
    x, err := csv.Parse("0,1,2,3,4,5,6,7,8,9\n0,1,2,3,4,5,6,7,8,9")
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(-1)
    }
    fmt.Println(x)

    y := csv.ToCsv(x)
    fmt.Println(y)

    os.Exit(0)
}

Run on go playground

๐Ÿ“ฆ Build the example app

๐ŸชŸ Windows prerequirements:

choco install make
# or
# scoop install make

๐Ÿ”น Build to native executable

make

๐Ÿ”น Build to WebAssembly (Go)

make wasm

๐Ÿ”น Build to WebAssembly (TinyGo; experimental)

๐ŸชŸ Windows prerequirements:

scoop install tinygo
scoop install binaryen

๐Ÿง Linux prerequirements:

๐ŸŽ Mac prerequirements:

Build:

make tinywasm

๐Ÿงฉ Contributing

Prerequirements:

go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest
go install honnef.co/go/tools/cmd/staticcheck@latest

โš–๏ธ License

MIT
Copyright (c) 2021 Shellyl_N and Authors.

takenoco's People

Contributors

shellyln avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

woshizilong

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.