2
目前我使用Scala的PackratParsers斯卡拉2.9.2 生产看起来是这样的:斯卡拉PacktRat分析器限制操作正好一个
lazy val andExpression: PackratParser[Expression] = equalityExpression | expression ~ "&" ~ expression ^^ {
case x ~"&"~y => AndExpr(x,y)
}
lazy val orExpression: PackratParser[Expression] = andExpression | (expression ~ "|" ~ expression) ^^ {
case x ~"|"~y => OrExpr(x,y)
}
它与下面的输入
"a & b", "a | c", "(a & b) | c"
的伟大工程
但是,我刚发现我的解析器太贪婪了。
"a && b", "a &&& b", "a ||||| b"
它解析得很好。我相信我只是在组合器上缺少一个明确的匹配器。那究竟是什么说e ~ "&".{1} ~ e
?如何恰好匹配运营商的一个事件,只有一件事,而不是什么?
,我同样对待写作的表达,以一个XPath
lazy val absolutePath: PackratParser[NodePath] = "/" ~ relativePath ^^ {
case "/" ~ rel => NodePath(rel.nodeExpr, true);
}
lazy val relativePath: PackratParser[NodePath] = repsep(nodeExpression , "/") ^^ {
case x =>
if (debug) printf("x=%s NodePath\n",x);
NodePath(x , false)
而且你是正确的解析器。
lazy val nodeExpression: PackratParser[Token] = qname | variable | step
lazy val expression = orExpression | nodeExpression | variable | literal | function | ...
既然你可以有空NodePath(List[QName]())
那么“是啊!”表达式是empy,因此“x &”和“& x”被成功解析。因此我的解析器显得贪婪。
让我换个问题,我如何确保relativeExpression
包含至少一个QName
?
本质上,字符串集合("x" , "/x", "x/y", "/x/y", ...)
应该是有效的XPath类似表达式,但不是""
? ;-)
'expression'的值是什么? – drstevens 2012-07-25 15:08:46
表达式可以像XPath一样 – 2012-07-26 11:03:13
好的!我想到了。 lazy val relativePath:PackratParser [NodePath] = rep1sep(nodeExpression,“/”) - 允许一个或多个“nodeExpressions” – 2012-07-26 14:48:05