IT練習ノート

IT関連で調べたこと(実際は嵌ったこと)を書いています。

JavaとHaskellのパースの違い

関数のパラメータ部分の解析を考えてみます。例えば、foo(1, 3, 4);`(1, 3, 4)の部分をパースすることを試してみます。

仕様としては、

  • 先頭にカッコ開き
  • 末尾にカッコ閉じ
  • 間に、カンマ区切りの数値

があるとします。

Javaの場合ですが、com.mysql.cj.xdevapi.ExprParserから引用してみました。whileループを使って、間に情報がない場合を場合分けしています。

List<Expr> parenExprList() {
     List<Expr> exprs = new ArrayList<>();
     consumeToken(TokenType.LPAREN);
     if (!currentTokenTypeEquals(TokenType.RPAREN)) {
         exprs.add(expr());
         while (currentTokenTypeEquals(TokenType.COMMA)) {
             consumeToken(TokenType.COMMA);
             exprs.add(expr());
         }
     }
     consumeToken(TokenType.RPAREN);
     return exprs;
}

Haskellの場合ですが、Attoparsecライブラリを使ったコードになります。上で言葉で書いた仕様に近いコードになります。

parenExprList :: Parser [PEx.Expr]     
parenExprList = do
  char '('
  x <- sepBy xParse $ char ','
  char ')'
  return x

調べてないですが、Javaでもライブラリを使えばHaskellと似た様に書けるのかもしれません。