2

現在、Scala 2.9.2 で Scala PackratParsers を使用しています。プロダクションは次のようになります。

  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何ですか?演算子の 1 つのオカレンスだけを正確に一致させるにはどうすればよいでしょうか?

私が書いているパーサーは、式を 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]() )から「うん!」Expression は空であるため、"x &" および "& x" は正常に解析されます。したがって、私のパーサーは貪欲に見えます。

質問を言い換えましょう。relativeExpression少なくとも 1 つ含まれていることを確認するにはどうすればよいQNameですか?

基本的に、一連の文字列( "x" , "/x", "x/y", "/x/y", ... )は有効な XPath のような式である必要がありますが、""?ではありません。;-)

4

1 に答える 1

3

"&""|"単一の文字のみに一致します。私が考えることができる唯一の説明はexpression、それが空であるか、それ自体&または|.

于 2012-07-25T22:33:31.417 に答える