After watching Saša Jurić’s talk on the subject I built my own parser combinator library, Ergo, as a learning experience.
It’s reached a point of maturity that it’s worked quite well for the parsing tasks I’ve thrown at it, but now I’ve hit a problem I am struggling to think my way around.
Let’s say I have a parser for a value:
def value() do
choice([
number_value(),
boolean_value(),
string_value()
])
)
and now I want to deal with lists (I’m omitting to deal with whitespace for brevity):
def list_value() do
sequence([
char(?[),
value(),
many(
sequence([
char(?,)
value()
])
),
char(?])
])
)
def value() do
choice([
number_value(),
boolean_value(),
string_value(),
list_value()
])
end
and now I have a problem in that list_value()
and value()
are mutually, infinitely, recursive.
I’m about 25 years from my compiler class so I am very hazy about anything from here onwards. I don’t think this is a left-recursive grammar issue because you consume the [
token (i.e. this is not A -> A𝛼|β
). I think this is an artefact of building the parsers using function calls.
I’ve bent my brain around this problem and come up with nothing except that possibly this is one reason that NimbleParsec and ExSpirit use macros, rather than plain functions, so that recursion is possible.
Can anyone help me figure out what to do here?
Many thanks in advance.