Huy Vo Huy Vo - 2 months ago 60
Scala Question

Scala parser combinator: Failure - eol (end of line) expected

I want to parses a LOLCODE script using Scala parser combinators. Here is what I got by far:

class ValuePT(val value: String) extends ExpressionPT {
override def toString = value
}

def value: Parser[ValuePT] = (numericLit | stringLit) ^^ {
case a => new ValuePT(a)
}
def expression: Parser[ExpressionPT] = (...| id | value) ^^ {
case a => a
}

def statement: Parser[StatementPT] = (...|expression|...|loop) <~ eol ^^ {case a => a}

def condition: Parser[LoopConditionPT] = (value <~ "YR") ~ id ~ opt(("TIL"|"WILE") ~ expression) ^^ {
case a ~ b ~ Some(c ~ d) => new LoopConditionPT(a toString, b, Option(c -> d))
case a ~ b ~ None => new LoopConditionPT(a toString, b, Option("None" -> new IdentPT("-1")))
}

def loop: Parser[LoopPT] = ("IM IN YR" ~> id ~ opt(condition) <~ eol) ~ rep(statement) <~ "IM OUTTA YR" <~ id ^^ {
case a ~ b ~ c => new LoopPT(a, b, c)
}


My testcase looks like this:

HAI 1.2
IM IN YR UntilLoop UPPIN YR Var TIL BOTH SAEM Var AN 3
VISIBLE "UntilLoop " Var
IM OUTTA YR UntilLoop

IM IN YR WhileLoop bla YR Var
VISIBLE "WhileLoop " Var
IM OUTTA YR WhileLoop

I HAS A x ITZ 1
I HAS A y ITZ 1
IM IN YR NestedLoop
IM IN YR InnerLoop
VISIBLE "NestedLoop " x " " y
GTFO
IM OUTTA YR InnerLoop
GTFO
IM OUTTA YR NestedLoop
KTHXBYE


But my function doesn't work, it raises an error:

[2.24] failure: eol expected

IM IN YR UntilLoop UPPIN YR Var TIL BOTH SAEM Var AN 3

^


I don't understand and I don't know what causes the error, is it says that I was missing
eol
before UPPIN?

Answer

What is clear from the code is that condition is failing to match, which is fine from the parser's perspective because its opt(condition). But when it fails, it is expecting an eol next.

It looks like you are expecting condition to match the rest of the line. Because you get the error at eol, that means that condition fails on the first token, because otherwise Scala would have reported the error from the branch that made further progress. Without the definition of value, it is impossible to tell what exactly is failing, but a general rule for debugging opt parsers is to remove the opt when testing examples. This way, you always get an error from the inside of opt rather than letting opt quietly match nothing.

Comments