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