lambda-phi/parser/1.0.0

Formerly davidcavazos/parser. Search finds this package by either name.

Parser.Common

Common and other useful parsers.

int : Parser Int

Matches an integer value as an Int.

import Parser exposing (parse)
import Parser.Error


-- You can parse integers as `Int` instead of `String`.
parse "123" int --> Ok 123


-- It also works with negative numbers.
parse "-123" int --> Ok -123


-- A decimal number is _not_ an integer :)
parse "3.14" int
    |> Result.mapError Parser.Error.message
--> Err "1:2: I was expecting an integer value. I got stuck when I got the character '.'."


-- But not with invalid numbers.
parse "abc" int
    |> Result.mapError Parser.Error.message
--> Err "1:1: I was expecting an integer value. I got stuck when I got the character 'a'."
number : Parser Float

Matches a decimal value as a Float.

import Parser exposing (parse)
import Parser.Error


-- You can parse numbers as `Float` instead of `String`.
parse "12" number --> Ok 12.0
parse "12." number --> Ok 12.0
parse "12.34" number --> Ok 12.34
parse ".12" number --> Ok 0.12


-- It also works with negative numbers.
parse "-12.34" number --> Ok -12.34
parse "-.12" number --> Ok -0.12


-- But not with invalid numbers.
parse "." number
    |> Result.mapError Parser.Error.message
--> Err "1:1: I was expecting a digit [0-9]. I got stuck when I got the character '.'."


parse "abc" number
    |> Result.mapError Parser.Error.message
--> Err "1:1: I was expecting a digit [0-9]. I got stuck when I got the character 'a'."
text : String -> Parser String

Matches a specific text string. This is case sensitive.

import Parser exposing (parse)


-- Match an exact text, case sensitive.
parse "abcdef" (text "abc") --> Ok "abc"


-- But anything else makes it fail.
import Parser.Error


text "abc"
    |> parse "abCDEF"
    |> Result.mapError Parser.Error.message
--> Err "1:3: I was expecting the text 'abc'. I got stuck when I got the character 'C'."
textNoCase : String -> Parser String

Matches a specific text string. This is case insensitive.

import Parser exposing (parse)


-- Match an exact text, case insensitive.
parse "abcdef" (textNoCase "abc") --> Ok "abc"
parse "ABCDEF" (textNoCase "abc") --> Ok "ABC"


-- But anything else makes it fail.
import Parser.Error


textNoCase "abc"
    |> parse "ab@"
    |> Result.mapError Parser.Error.message
--> Err "1:3: I was expecting the text 'abc' (case insensitive). I got stuck when I got the character '@'."
digits : Parser String

Matches one or more digit.

ℹ️ Equivalent regular expression: [0-9]+ or \d+

import Parser exposing (parse)


-- Match many digits.
parse "123abc" digits --> Ok "123"


-- But anything else makes it fail.
import Parser.Error


digits
    |> parse "abc123"
    |> Result.mapError Parser.Error.message
--> Err "1:1: I was expecting one or more digits [0-9]+. I got stuck when I got the character 'a'."
letters : Parser String

Matches one or more letter. This is case insensitive.

ℹ️ Equivalent regular expression: [a-zA-Z]+

import Parser exposing (parse)


-- Match many letters, case insensitive.
parse "abc123" letters --> Ok "abc"
parse "ABC123" letters --> Ok "ABC"


-- But anything else makes it fail.
import Parser.Error


letters
    |> parse "123abc"
    |> Result.mapError Parser.Error.message
--> Err "1:1: I was expecting one or more letters [a-zA-Z]+. I got stuck when I got the character '1'."
spaces : Parser String

Matches zero or more Unicode blank spaces, including new lines.

ℹ️ Equivalent regular expression: [ \t\n\r\f]* or \s*

import Parser exposing (parse)


-- Match many spaces.
parse "    abc" spaces --> Ok "    "


parse "\n\t abc" spaces --> Ok "\n\t "


-- Including zero spaces :)
parse "abc" spaces --> Ok ""
line : Parser String

Matches a line from the input text, delimited by '\n'.

import Parser exposing (parse)
import Parser.Error
import Parser.Sequence exposing (zeroOrMore)


-- A line could be delimited by the newline character '\n'.
parse "abc\ndef" line --> Ok "abc"


-- Or this could also be the last line.
parse "abc" line --> Ok "abc"


-- An empty line still counts.
parse "\n" line --> Ok ""


-- But not an empty file.
line
    |> parse ""
    |> Result.mapError Parser.Error.message
--> Err "1:0: I was expecting a line. I reached the end of the input text."


-- So we can parse multiple lines.
zeroOrMore line
    |> parse "abc\ndef\nghi"
--> Ok [ "abc", "def", "ghi"]
token : Parser a -> Parser a

Matches a parser as a token that can be preceded and followed by zero or more spaces.

import Parser exposing (map3, parse)
import Parser.Char exposing (char)


parse "1+2" (map3 (\x _ y -> x + y) int (token (char '+')) int) --> Ok 3
parse "1 + 2" (map3 (\x _ y -> x + y) int (token (char '+')) int) --> Ok 3
parse "1  +  2" (map3 (\x _ y -> x + y) int (token (char '+')) int) --> Ok 3