2014-11-24 104 views
0

使用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

|解析仅一侧(图案或过滤器而不是两者)。

试着像一个新的规则(变更类型,我用_):

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

您可能需要更改patternRepetitionpatternOrFilter得到你想要的返回值。

编辑

解析器不会因为~!使用的工作。如果您使用~代替解析器,那么您的示例将可用(例如,http://scalafiddle.net/console/97ea3cfb64eeaa1edba65501d0bb3c86)。

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

+0

哦,对了,我现在已经添加了这个问题描述。不幸的是,我的代码已经有了。 – ljacqu 2014-11-24 16:21:40

+0

你有一个小*非工作*例子吗? 这是一个基于你的问题的*工作*例子(我不得不删除一些代码,因为我没有ParsedPattern):http://scalafiddle.net/console/c359889a833e7612e0cff1dc69d272bc – planetenkiller 2014-11-25 07:33:10

+0

感谢您的时间。这是最短的,我可以得到它:http://scalafiddle.net/console/65d90fc6d307590b14e9e1800d4e8eab我道歉的长度。看来URL部分造成了麻烦。有了评论,我指出了三个地方省略了某些东西可以解决问题。 – ljacqu 2014-11-25 16:59:27