Scala 解析器组合器:失败 - 预期 eol(行尾)
Scala parser combinator: Failure - eol (end of line) expected
我想使用 Scala 解析器组合器解析 LOLCODE
脚本。这是我到目前为止得到的:
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)
}
我的测试用例是这样的:
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
但是我的函数不起作用,它引发了一个错误:
[2.24] failure: eol expected
IM IN YR UntilLoop UPPIN YR Var TIL BOTH SAEM Var AN 3
^
我不明白,我不知道是什么原因导致错误,它说我在 UPPIN
之前缺少 eol
吗?
从代码中可以清楚地看出 condition
无法匹配,从解析器的角度来看这很好,因为它是 opt(condition)
。但是当它失败时,它期待下一个 eol
。
您似乎希望 condition
与该行的其余部分匹配。因为您在 eol
处收到错误,这意味着 condition
在第一个标记上失败,否则 Scala 会从取得进一步进展的分支中报告错误。如果没有 value
的定义,就不可能知道到底是什么失败了,但是 调试 opt
解析器的一般规则是在测试示例时删除 opt
。这样,您总是会从 opt
内部得到错误,而不是让 opt
安静地匹配任何内容。
我想使用 Scala 解析器组合器解析 LOLCODE
脚本。这是我到目前为止得到的:
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)
}
我的测试用例是这样的:
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
但是我的函数不起作用,它引发了一个错误:
[2.24] failure: eol expected
IM IN YR UntilLoop UPPIN YR Var TIL BOTH SAEM Var AN 3
^
我不明白,我不知道是什么原因导致错误,它说我在 UPPIN
之前缺少 eol
吗?
从代码中可以清楚地看出 condition
无法匹配,从解析器的角度来看这很好,因为它是 opt(condition)
。但是当它失败时,它期待下一个 eol
。
您似乎希望 condition
与该行的其余部分匹配。因为您在 eol
处收到错误,这意味着 condition
在第一个标记上失败,否则 Scala 会从取得进一步进展的分支中报告错误。如果没有 value
的定义,就不可能知道到底是什么失败了,但是 调试 opt
解析器的一般规则是在测试示例时删除 opt
。这样,您总是会从 opt
内部得到错误,而不是让 opt
安静地匹配任何内容。