lambda-phi / parser / Parser.Char

Parsers for characters.

anyChar : Parser Char

Matches any single character.

ℹ️ Equivalent regular expression: .

import Parser exposing (parse)

-- We can match any character.
parse "abc" anyChar --> Ok 'a'
parse "#hashtag" anyChar --> Ok '#'

-- This can only fail if we run out of inputs.
import Parser.Error

anyChar
    |> parse ""
    |> Result.mapError Parser.Error.message
--> Err "1:0: I was expecting a character. I reached the end of the input text."

char : Char -> Parser Char

Matches a specific single character. This is case sensitive.

import Parser exposing (parse)

-- Match a specific character, case sensitive.
parse "abc" (char 'a') --> Ok 'a'

-- It fails if it's not _exactly_ the same.
import Parser.Error

char 'a'
    |> parse "ABC"
    |> Result.mapError Parser.Error.message
--> Err "1:1: I was expecting the character 'a'. I got stuck when I got the character 'A'."

charNoCase : Char -> Parser Char

Matches a specific single character. This is case insensitive.

import Parser exposing (parse)

-- Match a specific character, case insensitive.
parse "abc" (charNoCase 'a') --> Ok 'a'
parse "ABC" (charNoCase 'a') --> Ok 'A'

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

charNoCase 'a'
    |> parse "123"
    |> Result.mapError Parser.Error.message
--> Err "1:1: I was expecting the character 'a' (case insensitive). I got stuck when I got the character '1'."

digit : Parser Char

Matches exactly one digit character.

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

import Parser exposing (parse)

-- Match a digit.
parse "123" digit --> Ok '1'
parse "3.14" digit --> Ok '3'

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

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

letter : Parser Char

Matches exactly one letter character. This is case insensitive.

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

import Parser exposing (parse)

-- Match any letter, case insensitive.
parse "abc" letter --> Ok 'a'
parse "ABC" letter --> Ok 'A'

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

letter
    |> parse "123"
    |> Result.mapError Parser.Error.message
--> Err "1:1: I was expecting a letter [a-zA-Z]. I got stuck when I got the character '1'."

lowercase : Parser Char

Matches exactly one lowercase letter character. This is case sensitive.

ℹ️ Equivalent regular expression: [a-z]

import Parser exposing (parse)

-- Match a lowercase letter.
parse "abc" lowercase --> Ok 'a'

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

lowercase
    |> parse "ABC"
    |> Result.mapError Parser.Error.message
--> Err "1:1: I was expecting a lowercase letter [a-z]. I got stuck when I got the character 'A'."

uppercase : Parser Char

Matches exactly one uppercase letter character. This is case sensitive.

ℹ️ Equivalent regular expression: [A-Z]

import Parser exposing (parse)

-- Match an uppercase letter.
parse "ABC" uppercase --> Ok 'A'

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

uppercase
    |> parse "abc"
    |> Result.mapError Parser.Error.message
--> Err "1:1: I was expecting an uppercase letter [A-Z]. I got stuck when I got the character 'a'."

alphaNum : Parser Char

Matches exactly one letter or digit character. This is case insensitive.

ℹ️ Equivalent regular expression: [a-zA-Z0-9]

import Parser exposing (parse)

-- Match a letter or number.
parse "abc" alphaNum --> Ok 'a'
parse "ABC" alphaNum --> Ok 'A'
parse "123" alphaNum --> Ok '1'

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

alphaNum
    |> parse "_abc"
    |> Result.mapError Parser.Error.message
--> Err "1:1: I was expecting a letter or a digit [a-zA-Z0-9]. I got stuck when I got the character '_'."

space : Parser Char

Matches a Unicode blank space character, including new lines. A blank space can be a regular space ' ', tab '\t', new line '\n', carriage return '\r', or form feed '\f'.

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

import Parser exposing (parse)

-- Match a space space.
parse "    abc" space --> Ok ' '
parse "\n\t abc" space --> Ok '\n'

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

parse "abc" space
    |> Result.mapError Parser.Error.message
--> Err "1:1: I was expecting a blank space or new line. I got stuck when I got the character 'a'."

punctuation : Parser Char

Matches an ASCII punctuation character. A punctuation character can be any of !, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, ], ^, _, \``,{,}, or~`.

ℹ️ Equivalent regular expression: [!"#$%&'()*+,-./:;<=>?@[\]^_\\{}~]

import Parser exposing (parse)

-- Match a punctuation character.
parse "#hashtag" punctuation --> Ok '#'
parse "=123" punctuation --> Ok '='

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

punctuation
    |> parse "abc"
    |> Result.mapError Parser.Error.message
--> Err "1:1: I was expecting a punctuation character. I got stuck when I got the character 'a'."

except : Parser Char -> Parser Char

Matches any character except the parser provided.

ℹ️ It's a good idea to use expecting alongside this function to improve the error messages.

import Parser exposing (parse)
import Parser.Error

-- Anything except a letter is okay.
parse "123" (except letter) --> Ok '1'
parse "-123" (except letter) --> Ok '-'

-- But a letter is not.
except letter
    |> parse "abc"
    |> Result.mapError Parser.Error.message
--> Err "1:1: I was expecting a different character. I got stuck when I got the character 'a'."