解析器替代算子|失败

时间:2014-11-24 14:54:31

标签: scala parsing

使用Scala解析器的扩展,我希望解析两种不同类型的信息 - 模式和过滤器。这些模式和过滤器可以按任何顺序出现。

分别在变量patternfilter中定义了模式和过滤器的格式,我想将它们联合起来,以便可以按任何顺序提供过滤器和模式:

val patternRepetition: Parser[List[ParsedPattern]] = {
  rep1sep(pattern, ".") <~ opt(".")
}

val patternOrFilter: Parser[List[ParsedPattern]] = {
  patternRepetition | rep1(filterSpec)
}

val patternList: Parser[List[ParsedPattern]] = {
  rep1(patternOrFilter) ^^ {
    _.flatten
  }
}

作为参考,patternfilter的代码显示在本文末尾。


patternList应匹配的一些示例:

?A ?C ?B .
?A ?C ?B .
FILTER(?A > ?B)
?A ?C ?B .
?A ?C ?B
FILTER(?A > ?B)
?A ?C ?B
FILTER(?A > ?B)
?A ?C ?B

一旦出现过滤器,解析器就会抱怨意外的(字符。但是,在|中将~更改为patternOrFilter将成功解析后跟过滤器的模式列表(例如在第二个和第三个示例中),因此我认为存在问题我使用替代运算符|

因此,我的问题是:为什么|运算符无法识别过滤器?


模式目前定义如下:

val pattern: Parser[ParsedPattern] = {
  "?A" ~! "?C" ~! "?B" ^^ {
    case s ~ p ~ o =>
      ParsedPattern(s, p, o)
  }
}

这显然符合:

?A ?C ?B

使用以下代码定义过滤器

val filter: Parser[ParsedPattern] = {
  "FILTER(" ~> "?A" ~ ">" ~ "?B") <~ ")"  ^^ {
    case lhs ~ comp ~ rhs =>
      ParsedPattern(lhs, comp, rhs) 
  }
}

这匹配以下行:

FILTER(?A > ?B)

1 个答案:

答案 0 :(得分:1)

|仅解析一方(模式OR过滤但不是两者)。

尝试使用新规则(更改类型,我使用_):

def patternOrFilterAll: Parser[_] = {
  rep1(patternOrFilter)
}

您可能需要更改patternRepetitionpatternOrFilter以获得所需的返回值。

修改

由于~!的使用,您的Parser无法正常工作。如果您使用~代替解析器,那么您的示例将起作用(例如http://scalafiddle.net/console/97ea3cfb64eeaa1edba65501d0bb3c86)。

原因:解析器使用回溯,~!将禁用它。解析器需要回溯,因为url正则表达式可能会失败。