Giter VIP home page Giter VIP logo

parser's Introduction

Parser

Build Status

An attempt to implement parser combinators in Kotlin, inspired by Parsec.

Parsers

Basic parsers

  • space - any whitespace
  • upper - any uppercase letter
  • lower - any lowercase letter
  • letter - any letter
  • digit - any digit 0..9
  • alphaNum - any letter or digit
  • uint/int - an integer (unsigned or signed)
  • ulong/long - a long (unsigned or signed)
  • ufloat/float - a floating-point number (decimal or e-notation, unsigned or signed)
  • unumber/number - a floating-point or integer number
  • eof - end of input
  • skipSpaces - skip arbitrary number of spaces

Configurable parsers

  • oneOf(list) - any character in the provided list
  • noneOf(list) - character should not be in the provided list
  • char(ch) - character equal to the provided one
  • string(str) - string equal to the provided one
  • satisfy(pred) - character for which provided predicate returns true

Combinators

  • List/Pair/Triple(parsers).chain() - inverts the structure and returns a parser of List/Pair/Triple with chained results
  • count(number, parser) - repeats parser as many times as stated
  • choice(list) - tries list of parsers in order, returning the first success
  • chain(parsers) - executes a list of parsers and returns a list of their results
  • between(open, close, parser) - runs open, then parser and close, returning the result of parser
  • many(parser) - repeats parser 0+ times until error occurs
  • many1(parser) - repeats parser 1+ times until error occurs
  • skipMany(parser) - repeats parser 0+ times but does not return any result
  • skipMany1(parser) - repeats parser 1+ times but does not return any result
  • parser sepBy sep - repeats parser 0+ times, separated by sep
  • parser sepBy1 sep - repeats parser 1+ times, separated by sep
  • parser endBy sep - like sepBy, but input must also end with sep
  • parser endBy1 sep - like sepBy1, but input must also end with sep
  • just(value) - always returns value
  • fail(message) - always fails with message
  • option(value, parser) - returns value if parser fails
  • optional(parser) - tries to run parser but does not return any result (does not fail)
  • lookahead(parser) - executes parser without consuming any input
  • pA and pB - returns both results of parsers pA and pB as a pair
  • pA andF pB - (and-flat) returns both results of parsers pA and pB flattened to a list without Units
  • pA andL pB - (and-left) returns result of pA (left parser) only if pB succeeds
  • pA andR pB - (and-right) returns result of pB (right parser) only if pA succeeds
  • pA or pB - tries to run pA and if fails, returns result of pB
  • parser.map { ... } - apply function to the result of parser
  • parser.flatMap { ... } - use the successful result of parser and return a new parser
  • parser.recoverWith { ... } - use the error of parser and return a new parser

Misc

  • parser % "Error message" - returns a parser with "Error message" for error

How to use

In order to parse a string with some parser, parse(parser, input) function should be used. It returns a Result<T> which can be either a Success (contains the parsed value and rest of the input) or an Error (contains error message).

val input = "ABCD1234"
val result = parse(letter, input)

when (result) {
    is Error   -> println(result.message)
    is Success -> println(result.value)
}
// should print 'A'

Another possibility is to use run(parser, input) that directly returns the value (if succeeded) or null (if error).

val input = "42A"
val result = run(int, input)
// should be 42
val tail = oneOf('+', '-', '*', '/') andF number
val tails = many1(tail).map { it.flatten() }
val expr = number andF tails

val result = run(expr, "12+6.5")
// should be [12, '+', 6.5]

Parser builder

In addition to the combinators and/andL/andR/or, as well as the modifier map, there is a way to build parsers in declarative style.

buildParser creates a context which takes care of passing the rest of the input from one parser to the other upon calling .ev(), all while tracking the return value (Success or Error) of each one. In case of the latter, execution is stopped and the error is returned.

Example

This parser would take two numbers and sum them together.

val sum = buildParser {
    val a = int.ev()
    char('+').ev()
    val b = uint.ev()
    a + b
}

val result = parse(sum, "3+4")
// should be Success(value=7, rest=)

Expression parser builder

There is a possibility to create a parser for an expression that also evaluates it. It is only necessary to provide an operators table where all operators are listed and their functions defined. Operators table is a list of Operator lists ordered in descending precedence.

Example

In this example we support incrementation, multiplication and addition/subtraction, with ++ having the highest precedence.

val table: OperatorTable<Int> = listOf(
    listOf( postfix("++") { it + 1 } ),
    listOf( binary("*", Assoc.Left) { x, y -> x * y } ),
    listOf(
        binary("+", Assoc.Left) { x, y -> x + y },
        binary("-", Assoc.Left) { x, y -> x - y }
    )
)

val expr = buildExpressionParser(table, uint)
run(expr, "1+2*3") // should be 7
run(expr, "2++") // should be 3

parser's People

Contributors

fintara avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 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.