Parse a comma-separated list like [ 1, 2, 3 ]. You provide
a parser for the spaces and for the list items. So if you want
to parse a list of integers, you would say:
import Parser exposing (Parser)
import Parser.LanguageKit as Parser
intList : Parser (List Int)
intList =
Parser.list spaces Parser.int
spaces : Parser ()
spaces =
Parser.ignoreWhile (\char -> char == ' ')
-- run intList "[]" == Ok []
-- run intList "[ ]" == Ok []
-- run intList "[1,2,3]" == Ok [1,2,3]
-- run intList "[ 1, 2, 3 ]" == Ok [1,2,3]
-- run intList "[ 1 , 2 , 3 ]" == Ok [1,2,3]
-- run intList "[ 1, 2, 3, ]" == Err ...
-- run intList "[, 1, 2, 3 ]" == Err ...Note: If you want trailing commas, check out the
sequence function.
Help parse records like { a = 2, b = 2 }. You provide
a parser for the spaces and for the list items, you might say:
import Parser exposing ( Parser, (|.), (|=) )
import Parser.LanguageKit as Parser
record : Parser (List (String, Int))
record =
Parser.record spaces field
field : Parser (String, Int)
field =
Parser.succeed (,)
|= lowVar
|. spaces
|. Parser.symbol "="
|. spaces
|= int
spaces : Parser ()
spaces =
Parser.ignoreWhile (\char -> char == ' ')
-- run record "{}" == Ok []
-- run record "{ }" == Ok []
-- run record "{ x = 3 }" == Ok [ ("x",3) ]
-- run record "{ x = 3, }" == Err ...
-- run record "{ x = 3, y = 4 }" == Ok [ ("x",3), ("y",4) ]
-- run record "{ x = 3, y = }" == Err ...Note: If you want trailing commas, check out the
sequence function.
Handle things like lists and records, but you can customize the details however you need. Say you want to parse C-style code blocks:
import Parser exposing (Parser)
import Parser.LanguageKit as Parser exposing (Trailing(..))
block : Parser (List Stmt)
block =
Parser.sequence
{ start = "{"
, separator = ";"
, end = "}"
, spaces = spaces
, item = statement
, trailing = Mandatory -- demand a trailing semi-colon
}
-- spaces : Parser ()
-- statement : Parser StmtNote: If you need something more custom, do not be afraid to check out the implementation and customize it for your case. It is better to get nice error messages with a lower-level implementation than to try to hack high-level parsers to do things they are not made for.
What’s the deal with trailing commas? Are they Forbidden?
Are they Optional? Are they Mandatory? Welcome to shapes
club!
Create a custom whitespace parser. It will always chomp the
' ', '\r', and '\n' characters, but you can customize some
other things. Here are some examples:
elm : Parser ()
elm =
whitespace
{ allowTabs = False
, lineComment = LineComment "--"
, multiComment = NestableComment "{-" "-}"
}
js : Parser ()
js =
whitespace
{ allowTabs = True
, lineComment = LineComment "//"
, multiComment = UnnestableComment "/*" "*/"
}If you need further customization, please open an issue describing your
scenario or check out the source code and write it yourself. This is all
built using stuff from the root Parser module.
Are line comments allowed? If so, what symbol do they start with?
LineComment "--" -- Elm
LineComment "//" -- JS
LineComment "#" -- Python
NoLineComment -- OCamlAre multi-line comments allowed? If so, what symbols do they start and end with?
NestableComment "{-" "-}" -- Elm
UnnestableComment "/*" "*/" -- JS
NoMultiComment -- PythonIn Elm, you can nest multi-line comments. In C-like languages, like JS,
this is not allowed. As soon as you see a */ the comment is over no
matter what.
Create a parser for variables. It takes two
Charcheckers. The first one is for the first character. The second one is for all the other characters.In Elm, we distinguish between upper and lower case variables, so we can do something like this: