Scala 解析器组合器可选部分

Scala 解析器组合器可选部分,scala,parser-combinators,Scala,Parser Combinators,这是我第一次使用scala的解析器组合器。 在这种情况下,我有一个“类型”列表,它们可以扩展其他类型,也可以不扩展。 如果他们这样做,我只是在类型和其父类型之间创建一个映射。 如果不是,我只是将类型映射到“object”。(类型只是字符串名称) 它们是这样写的: type1 type2 type3 - parentType 或 在这种情况下,它们将隐含为-object 我试图用下面的方法实现它,但它不是编译的。它说它需要一个选项[~List[String,String],它找到了~[a,b]。

这是我第一次使用scala的解析器组合器。 在这种情况下,我有一个“类型”列表,它们可以扩展其他类型,也可以不扩展。 如果他们这样做,我只是在类型和其父类型之间创建一个映射。 如果不是,我只是将类型映射到“object”。(类型只是字符串名称)

它们是这样写的:

type1 type2 type3 - parentType

在这种情况下,它们将隐含为
-object

我试图用下面的方法实现它,但它不是编译的。它说它需要一个选项[~List[String,String],它找到了~[a,b]。它还说它无法在第一个选项中找到值名以便理解,而事实上它是在case模式匹配中指定的。现在有点困惑到底发生了什么

def type_list = ((name+) ~ ("-" ~> parent_type)?) ^^ {
  case names ~ parent_type => for (name <- names) yield name -> parent_type
  case names => for (name <- names) yield name -> "object"
}

 def name = """[a-zA-Z\d]+""".r
def type_list=((名称+)(“-”~>父类型)?)^{
案例名称~parent\u type=>for(名称parent\u type
案例名称=>for(名称为“对象”
}
def name=“”[a-zA-Z\d]+”。r
实际上,我只想让它返回一个
映射[String,String]
,如果
父类型
丢失,它应该默认为“object”。
如何最好地处理这个问题?

这里有几件事

首先,~和?的优先级意味着,不是将(name+)作为解析器[List[String]]与(“-”~>parent\u type”)作为解析器[Option[String]]相结合,而是将整个内容包装在一起,从而获得解析器[Option[~[List[String],String]]

最简单的解决方案是使用一组额外的括号

因此,您要从以下内容开始:

def type_list = ((name+) ~ (("-" ~> parent_type)?))
然后在映射函数中,您将收到一个~[List[String],Option[String]],其中包含名称列表和可选的父类型。 在模式匹配方面,您总是得到name~parent_type,其中后者是一个选项[String]。 所以基本上你的第二个模式是无效的

所以你可以这样做:

def type_list = ((name+) ~ (("-" ~> parent_type)?)) ^^ {
   case names ~ Some(parent_type) => for (name <- names) yield name -> parent_type
   case names ~ None => for (name <- names) yield name -> "object"
}
def type_list=((名称+)(“-”~>父类型)?)^{
案例名称~Some(parent_type)=>for(name parent_type
案例名称~None=>for(名称为“object”
}
或者您可以将其简化为:

def type_list = ((name+) ~ (("-" ~> parent_type)?)) ^^ {
   case names ~ parent_type => for (name <- names) yield name -> parent_type.getOrElse("object)
}
def type_list=((名称+)(“-”~>父类型)?)^{
案例名称~parent_type=>for(名称parent_type.getOrElse(“对象”)
}

这里发生了一些事情

首先,~和?的优先级意味着,不是将(name+)作为解析器[List[String]]与(“-”~>parent\u type”)作为解析器[Option[String]]相结合,而是将整个内容包装在一起,从而获得解析器[Option[~[List[String],String]]

最简单的解决方案是使用一组额外的括号

因此,您要从以下内容开始:

def type_list = ((name+) ~ (("-" ~> parent_type)?))
然后在映射函数中,您将收到一个~[List[String],Option[String]],其中包含名称列表和可选的父类型。 在模式匹配方面,您总是得到name~parent_type,其中后者是一个选项[String]。 所以基本上你的第二个模式是无效的

所以你可以这样做:

def type_list = ((name+) ~ (("-" ~> parent_type)?)) ^^ {
   case names ~ Some(parent_type) => for (name <- names) yield name -> parent_type
   case names ~ None => for (name <- names) yield name -> "object"
}
def type_list=((名称+)(“-”~>父类型)?)^{
案例名称~Some(parent_type)=>for(name parent_type
案例名称~None=>for(名称为“object”
}
或者您可以将其简化为:

def type_list = ((name+) ~ (("-" ~> parent_type)?)) ^^ {
   case names ~ parent_type => for (name <- names) yield name -> parent_type.getOrElse("object)
}
def type_list=((名称+)(“-”~>父类型)?)^{
案例名称~parent_type=>for(名称parent_type.getOrElse(“对象”)
}

这里发生了一些事情

首先,~和?的优先级意味着,不是将(name+)作为解析器[List[String]]与(“-”~>parent\u type”)作为解析器[Option[String]]相结合,而是将整个内容包装在一起,从而获得解析器[Option[~[List[String],String]]

最简单的解决方案是使用一组额外的括号

因此,您要从以下内容开始:

def type_list = ((name+) ~ (("-" ~> parent_type)?))
然后在映射函数中,您将收到一个~[List[String],Option[String]],其中包含名称列表和可选的父类型。 在模式匹配方面,您总是得到name~parent_type,其中后者是一个选项[String]。 所以基本上你的第二个模式是无效的

所以你可以这样做:

def type_list = ((name+) ~ (("-" ~> parent_type)?)) ^^ {
   case names ~ Some(parent_type) => for (name <- names) yield name -> parent_type
   case names ~ None => for (name <- names) yield name -> "object"
}
def type_list=((名称+)(“-”~>父类型)?)^{
案例名称~Some(parent_type)=>for(name parent_type
案例名称~None=>for(名称为“object”
}
或者您可以将其简化为:

def type_list = ((name+) ~ (("-" ~> parent_type)?)) ^^ {
   case names ~ parent_type => for (name <- names) yield name -> parent_type.getOrElse("object)
}
def type_list=((名称+)(“-”~>父类型)?)^{
案例名称~parent_type=>for(名称parent_type.getOrElse(“对象”)
}

这里发生了一些事情

首先,~和?的优先级意味着,不是将(name+)作为解析器[List[String]]与(“-”~>parent\u type”)作为解析器[Option[String]]相结合,而是将整个内容包装在一起,从而获得解析器[Option[~[List[String],String]]

最简单的解决方案是使用一组额外的括号

因此,您要从以下内容开始:

def type_list = ((name+) ~ (("-" ~> parent_type)?))
然后在映射函数中,您将收到一个~[List[String],Option[String]],其中包含名称列表和可选的父类型。 在模式匹配方面,您总是得到name~parent_type,其中后者是一个选项[String]。 所以基本上你的第二个模式是无效的

所以你可以这样做:

def type_list = ((name+) ~ (("-" ~> parent_type)?)) ^^ {
   case names ~ Some(parent_type) => for (name <- names) yield name -> parent_type
   case names ~ None => for (name <- names) yield name -> "object"
}
def type_list=((名称+)(“-”~>父类型)?)^{
案例名称~Some(parent_type)=>for(name parent_type
案例名称~None=>for(名称为“object”
}
或者您可以将其简化为:

def type_list = ((name+) ~ (("-" ~> parent_type)?)) ^^ {
   case names ~ parent_type => for (name <- names) yield name -> parent_type.getOrElse("object)
}
def type_list=((名称+)(“-”~>父类型)?)^{
案例名称~parent_type=>for(名称parent_type.getOrElse(“对象”)
}

谢谢……这些单子仍然让我偏离正轨。也谢谢更简单的版本。谢谢……这些单子仍然让我偏离正轨。也谢谢更简单的版本。谢谢……这些单子仍然让我偏离正轨。也谢谢更简单的版本。谢谢……这些单子仍然让我偏离正轨