All Projects → elm → Parser

elm / Parser

Licence: bsd-3-clause
A parsing library, focused on simplicity and great error messages

Programming Languages

elm
856 projects

Labels

Projects that are alternatives of or similar to Parser

Gelatin
Transform text files to XML, JSON, or YAML
Stars: ✭ 150 (-10.18%)
Mutual labels:  parser
Fast Float Rust
Super-fast float parser in Rust
Stars: ✭ 160 (-4.19%)
Mutual labels:  parser
Pegparser
💡 Build your own programming language! A C++17 PEG parser generator supporting parser combination, memoization, left-recursion and context-dependent grammars.
Stars: ✭ 164 (-1.8%)
Mutual labels:  parser
Grmtools
Rust grammar tool libraries and binaries
Stars: ✭ 153 (-8.38%)
Mutual labels:  parser
Rats
Movie Ratings Synchronization with Python
Stars: ✭ 156 (-6.59%)
Mutual labels:  parser
Json To Ast
JSON AST parser
Stars: ✭ 161 (-3.59%)
Mutual labels:  parser
Resumeparser
A simple resume parser used for extracting information from resumes
Stars: ✭ 150 (-10.18%)
Mutual labels:  parser
Php Mf2
php-mf2 is a pure, generic microformats-2 parser for PHP. It makes HTML as easy to consume as JSON.
Stars: ✭ 165 (-1.2%)
Mutual labels:  parser
Texsoup
fault-tolerant Python3 package for searching, navigating, and modifying LaTeX documents
Stars: ✭ 157 (-5.99%)
Mutual labels:  parser
Vue Styleguidist
Created from react styleguidist for Vue Components with a living style guide
Stars: ✭ 2,133 (+1177.25%)
Mutual labels:  parser
Postagga
A Library to parse natural language in pure Clojure and ClojureScript
Stars: ✭ 152 (-8.98%)
Mutual labels:  parser
Isobmff
C++ Library for ISO/IEC 14496-12 - ISO Base Media File Format (QuickTime, MPEG-4, HEIF, etc)
Stars: ✭ 157 (-5.99%)
Mutual labels:  parser
Mikrotik Hosts Parser
✂️ Mikrotik hosts parser
Stars: ✭ 162 (-2.99%)
Mutual labels:  parser
Forge
A lightweight, elegant scripting language with built-in Rust-FFI.
Stars: ✭ 153 (-8.38%)
Mutual labels:  parser
Query Translator
Query Translator is a search query translator with AST representation
Stars: ✭ 165 (-1.2%)
Mutual labels:  parser
Xml2lua
XML Parser written entirely in Lua that works for Lua 5.1+. Convert XML to and from Lua Tables 🌖💱
Stars: ✭ 150 (-10.18%)
Mutual labels:  parser
Ink
A fast and flexible Markdown parser written in Swift.
Stars: ✭ 2,049 (+1126.95%)
Mutual labels:  parser
Spypi
An (un-)ethical hacking-station based on Raspberry Pi and Python
Stars: ✭ 167 (+0%)
Mutual labels:  parser
Command Line Api
Command line parsing, invocation, and rendering of terminal output.
Stars: ✭ 2,418 (+1347.9%)
Mutual labels:  parser
Npeg
PEGs for Nim, another take
Stars: ✭ 163 (-2.4%)
Mutual labels:  parser

Parser

Regular expressions are quite confusing and difficult to use. This library provides a coherent alternative that handles more cases and produces clearer code.

The particular goals of this library are:

  • Make writing parsers as simple and fun as possible.
  • Produce excellent error messages.
  • Go pretty fast.

This is achieved with a couple concepts that I have not seen in any other parser libraries: parser pipelines, backtracking, and tracking context.

Parser Pipelines

To parse a 2D point like ( 3, 4 ), you might create a point parser like this:

import Parser exposing (Parser, (|.), (|=), succeed, symbol, float, spaces)

type alias Point =
  { x : Float
  , y : Float
  }

point : Parser Point
point =
  succeed Point
    |. symbol "("
    |. spaces
    |= float
    |. spaces
    |. symbol ","
    |. spaces
    |= float
    |. spaces
    |. symbol ")"

All the interesting stuff is happening in point. It uses two operators:

  • (|.) means “parse this, but ignore the result”
  • (|=) means “parse this, and keep the result”

So the Point function only gets the result of the two float parsers.

The theory is that |= introduces more “visual noise” than |., making it pretty easy to pick out which lines in the pipeline are important.

I recommend having one line per operator in your parser pipeline. If you need multiple lines for some reason, use a let or make a helper function.

Backtracking

To make fast parsers with precise error messages, all of the parsers in this package do not backtrack by default. Once you start going down a path, you keep going down it.

This is nice in a string like [ 1, 23zm5, 3 ] where you want the error at the z. If we had backtracking by default, you might get the error on [ instead. That is way less specific and harder to fix!

So the defaults are nice, but sometimes the easiest way to write a parser is to look ahead a bit and see what is going to happen. It is definitely more costly to do this, but it can be handy if there is no other way. This is the role of backtrackable parsers. Check out the semantics page for more details!

Tracking Context

Most parsers tell you the row and column of the problem:

Something went wrong at (4:17)

That may be true, but it is not how humans think. It is how text editors think! It would be better to say:

I found a problem with this list:

    [ 1, 23zm5, 3 ]
         ^
I wanted an integer, like 6 or 90219.

Notice that the error messages says this list. That is context! That is the language my brain speaks, not rows and columns.

Once you get comfortable with the Parser module, you can switch over to Parser.Advanced and use inContext to track exactly what your parser thinks it is doing at the moment. You can let the parser know “I am trying to parse a "list" right now” so if an error happens anywhere in that context, you get the hand annotation!

This technique is used by the parser in the Elm compiler to give more helpful error messages.

Comparison with Prior Work

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].