SCALA:如何将Parser Combinator结果转换为Scala List [String]?

时间:2016-08-05 16:50:55

标签: scala parsing parser-combinators

我正在尝试为与Milner的CCS非常相似的语言编写解析器。基本上我到目前为止解析的是以下类型的表达式:

  • a.b.a.1
  • A.0

表达式必须以字母开头(不包括t),并且可以在第一个字母后面加上任意数量的字母(以“。”分隔)。表达式必须以数字结束(为简单起见,我现在选择0到2之间的数字)。我想为Scala使用Parser Combinators,但这是我第一次使用它们。这就是我到目前为止所做的:

import scala.util.parsing.combinator._

class SimpleParser extends RegexParsers {
  def alpha: Parser[String] = """[^t]{1}""".r ^^ { _.toString }
  def digit: Parser[Int] = """[0-2]{1}""".r ^^ { _.toInt }

  def expr: Parser[Any] = alpha ~ "." ~ digit ^^ {
    case al ~ "." ~ di => List(al, di)
  }

  def simpleExpression: Parser[Any] = alpha ~ "." ~ rep(alpha ~ ".") ~ digit //^^ {  }
}

正如您在def expr :Parser[Any]中看到的那样,我试图将结果作为列表返回,因为Scala中的列表非常容易使用(在我看来)。这是如何将Parser [Any]结果转换为List的正确方法吗?任何人都可以向我提供有关如何为def simpleExpression:Parser[Any]执行此操作的任何提示。

我想使用Lists的主要原因是因为在解析和Expression之后我希望能够使用它。例如,给定表达式 ab1 ,如果我得到'a',我想使用表达式以最终得到一个新表达式: b.1 (即 ab1 - >(a) - > b.1 )。这背后的想法是模拟有限状态自动机。关于如何改进我的实施的任何提示都表示赞赏。

1 个答案:

答案 0 :(得分:5)

为了保证事物类型安全,我建议使用一个解析器来生成字符串列表和int的元组。也就是说,输入a.b.a.1将被解析为(List("a", "b", "a"), 1)。另请注意,修改了alpha的正则表达式以排除任何不是小写字母的内容(除了t)。

class SimpleParser extends RegexParsers {
  def alpha: Parser[String] = """[a-su-z]{1}""".r ^^ { _.toString }
  def digit: Parser[Int] = """[0-2]{1}""".r ^^ { _.toInt }

  def repAlpha: Parser[List[String]] = rep1sep(alpha, ".")

  def expr: Parser[(List[String], Int)] = repAlpha ~ "." ~ digit ^^ {
    case alphas ~ _ ~ num =>
      (alphas, num)
  }
}

使用此SimpleParser的实例,这是我得到的输出:

println(parser.parse(parser.expr, "a.b.a.1"))
// [1.8] parsed: (List(a, b, a),1)

println(parser.parse(parser.expr, "a.0"))
// [1.4] parsed: (List(a),0)