3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

48時間でSchemeを書こう/構文解析

Last updated at Posted at 2015-06-29

参考URL

48時間でSchemeを書こう/構文解析

#ソース
https://github.com/0zawa/scheme_in_48_hours/blob/master/parsing.hs

Parsec

Haskellのパーサライブラリです。
パーサを作るのにいろいろと便利な機能があるようです。
以降、Parsecの機能を使ってSchemeパーサを実装していきます。

Parsecのインポート

import Text.ParserCombinators.Parsec

とします。

今回はspaces関数の衝突防止のため下記のようにして
spacesを除いてimportします。

import Text.ParserCombinators.Parsec hiding (spaces)

Parser型

パースを行う関数はParser aを返します。
aは任意の型です。

ここではParserの詳細は深く追わず、Parser aは

  • String型の入力を受け取る。
  • パース結果(a型)を返す。
  • パースされなかった文字列もどこかに保持している。

ものだと仮定して進めます。

記号の認識

Parsecに用意されているoneOf関数を使って、指定した記号を認識する関数を作成します。

symbol :: Parser Char
symbol = oneOf "!#$%&|*+-/:<=>?@^_~"

oneOf関数は指定した文字列(ここでは"!#$%&|*+-/:<=>?@^_~")が
入力文字列の先頭に含まれるかどうかパースし、
含まれていればその文字を(Parserに入れて)返します。

こうして作成したパース関数はParsecのparse関数と
組み合わせて使います。

parse関数は

  • Parser型を返すパース関数
  • パーサーの名前
  • 入力文字列(String型)

を引数に取り、Either型を返します。

パース関数にoneOfを指定する場合は

parse (oneOf "#!$") "test" "#123"

のようにします。
上記の結果Either型のRightに"#"が入ったものが戻り値になります。

Schemeで使用可能な記号を認識する

oneOf関数を使って定義したsymbolとparseを使ってSchemeで使用可能な記号をパースする関数を作ります。

readExpr :: String -> String
readExpr input = case parse symbol "lisp" input of
    Left err -> "No match: " ++ show err
    Right val -> "Found value"

symbolで定義した記号が入力文字列の先頭に含まれていなかった場合、
parse関数はEither型のLeftにエラーを入れて返します。

結果としてreadExpr関数は
入力した文字列の先頭に

  • symbolで定義した記号が含まれれば"Found Value"
  • 含まれていなければ"No match: (エラー理由)"

の文字列を返す関数になります。

この関数に標準入力で取得した文字列を渡すようにして、

main :: IO ()
main = do args <- getArgs
          putStrLn (readExpr (args !! 0))

ビルドして実行すると挙動を確認できます。

% ghc parsing.hs
% ./parsing $
Found value
% ./parsing a
No match: "lisp" (line 1, column 1):
unexpected "a"

ここまでがパーサーの入門的な基本説明です。
このあとLispの型を定義して本格的なパーサーの作成に進んでいきます。

48時間でSchemeを書こう/構文解析2

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?