前回の expr..hs では、数値と演算子の間にスペースが入るときちんと計算できなかった。余分なスペースをとったり、コメントを外したりする作業は一般には字句解析プログラム(lexical analizer) が受け持つ。Parsec にはこの字句解析プログラムを作る関数 makeTokenParser がある。makeTokenParser は、Text.ParserCombinators.Parsec.Token モジュールのなかにある。
makeTokenParser は引数に言語の様式をまとめたもの(LanguageDef)を引数にとり、パーサ関数を集めたレコードを返す。DefaultDef は Text.ParserCombinators.Parsec.Language のなかに記述されている。下の例では、Haskell タイプのコメントを処理できる haskellDef を用いている。 このあたりまで来ると管理人の知識も怪しくなってくるので、詳しくはParsec, a fast combinator parser を読んだ方がいいかもしれない。ただ、そのままでは動かなかったので動作確認した例を次に示す。モジュールの命令に forall が使われているので、-98 オプションで起動しないと動かない。Parsec を本格的に使うのなら GHC を使うのが王道だろう。何回も終了宣言をした Haskell だが、動脈のシミュレーションもやったし、Parsec の概要もわかったのでしばらく休憩(になると思う)。 import Text.ParserCombinators.Parsec import Text.ParserCombinators.Parsec.Expr import qualified Text.ParserCombinators.Parsec.Token as P import Text.ParserCombinators.Parsec.Language lexer :: P.TokenParser () lexer = P.makeTokenParser (haskellDef { reservedOpNames = ["*","/","+","-"] }) whiteSpace= P.whiteSpace lexer lexeme = P.lexeme lexer symbol = P.symbol lexer natural = P.natural lexer parens = P.parens lexer semi = P.semi lexer identifier= P.identifier lexer reserved = P.reserved lexer reservedOp= P.reservedOp lexer runLex :: Show a => Parser a -> String -> IO () runLex p input = parseTest (do{ whiteSpace ; x <- p ; eof ; return x }) input expr :: Parser Integer expr = buildExpressionParser table factor <?> "expression" table = [[op "*" (*) AssocLeft, op "/" div AssocLeft] ,[op "+" (+) AssocLeft, op "-" (-) AssocLeft] ] where op s f assoc = Infix (do{ reservedOp s; return f}) assoc factor = parens expr <|> natural <?> "simple expression" 実行例: $ hugs -98 -Evi __ __ __ __ ____ ___ _________________________________________ || || || || || || ||__ Hugs 98: Based on the Haskell 98 standard ||___|| ||__|| ||__|| __|| Copyright (c) 1994-2005 ||---|| ___|| World Wide Web: http://haskell.org/hugs || || Bugs: http://hackage.haskell.org/trac/hugs || || Version: September 2006 _________________________________________ Hugs mode: Restart with command line option +98 for Haskell 98 mode Type :? for help Hugs> :e expr.hs Hugs> :l expr.hs Main> runLex expr " 1 + (2 * 3) " 7
by tnomura9
| 2009-10-01 08:24
| Haskell
|
Comments(0)
|
カテゴリ
新型コロナウイルス 主インデックス Haskell 記事リスト 圏論記事リスト 考えるということのリスト 考えるということ ラッセルのパラドックス Haskell Prelude Ocaml ボーカロイド 圏論 jQuery デモ HTML Python ツールボックス XAMPP Ruby ubuntu WordPress 脳の話 話のネタ リンク 幸福論 キリスト教 心の話 メモ 電子カルテ Dojo JavaScript C# NetWalker ed と sed HTML Raspberry Pi C 言語 命題論理 以前の記事
最新のトラックバック
最新のコメント
ファン
記事ランキング
ブログジャンル
画像一覧
|
ファン申請 |
||