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

wir*_*dis 1 parsing scala parser-combinators

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

  • aba1
  • A.0

表达式必须以字母开头(不包括t),并且可以在第一个字母后面加上任意数量的字母(以"."分隔).Expression必须以数字结尾(为简单起见,我现在选择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 //^^ {  }
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,def expr :Parser[Any]我试图将结果作为列表返回,因为Scala中的列表非常容易使用(在我看来).这是如何将Parser [Any]结果转换为List的正确方法吗?任何人都可以给我任何关于如何做到这一点的提示def simpleExpression:Parser[Any].

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

gre*_*ghz 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)
  }
}
Run Code Online (Sandbox Code Playgroud)

有了这个例子,这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)
Run Code Online (Sandbox Code Playgroud)