Parsec コンビネータ getInput, getPosition
Parsec の入力は入力バッファにコピーされ、パーサによる構文解析が行われる。普通に構文解析するときは、入力バッファの状態を気にすることはないが、getInput 関数と、getPosition 関数を使うと入力バッファの消費されていない部分の文字列と、キャラクタポインタの位置を知ることができる。getInput
まず、入力を受けたあと全くパターンマッチによる消費が行われていない場合を実験してみる。パーサを利用せずに getInput と getPosition のみを利用するのだ。
Prelude Text.Parsec> parseTest (getInput) "hello, world" "hello, world"Prelude Text.Parsec> parseTest (getPosition) "hello, world" (line 1, column 1)
そこで、stirng "hello" を実行したあとの入力バッファの状態を getInput 関数によって表示させる。確かに、マッチした "hello" が消費されているのが分かる。
Prelude Text.Parsec> parseTest (string "hello" >> getInput) "hello, world" ", world"
getPosition
また、キャラクタポインタの位置を getPosition で表示させてみる。
Prelude Text.Parsec> parseTest (string "hello" >> getPosition) "hello, world" (line 1, column 6)
入力バッファを操作する関数については、この他にも setPosition, setInput などの他、入力バッファを操作する多くの関数があるが、詳細は省略する。それらは、Text.Parsec.Pos モジュールに定義されており、このモジュールをインポートすると実験することができる。
これまでの記事でつぎに示す Text.Parsec の関数はだいたい調べることができた。次の目標は、実際のパーサを参考に使い方を学習することになるが、ちょっと休憩。
module Text.Parsec ( -- * Parsers ParsecT , Parsec , token , tokens , runParserT , runParser , parse , parseTest , getPosition , getInput , getState , putState , modifyState -- * Combinators , (<|>) , (<?>) , label , labels , try , unexpected , choice , many , many1 , skipMany , skipMany1 , count , between , option , optionMaybe , optional , sepBy , sepBy1 , endBy , endBy1 , sepEndBy , sepEndBy1 , chainl , chainl1 , chainr , chainr1 , eof , notFollowedBy , manyTill , lookAhead , anyToken -- * Character Parsing , module Text.Parsec.Char -- * Error messages , ParseError , errorPos -- * Position , SourcePos , SourceName, Line, Column , sourceName, sourceLine, sourceColumn , incSourceLine, incSourceColumn , setSourceLine, setSourceColumn, setSourceName -- * Debugging -- -- | As a more comprehensive alternative for debugging Parsec parsers, -- there's also the [parsec-free](http://hackage.haskell.org/package/parsec-free) -- package. -- , parserTrace, parserTraced -- * Low-level operations , manyAccum , tokenPrim , tokenPrimEx , runPT , unknownError , sysUnExpectError , mergeErrorReply , getParserState , setParserState , updateParserState , Stream (..) , runParsecT , mkPT , runP , Consumed (..) , Reply (..) , State (..) , setPosition , setInput -- * Other stuff , setState , updateState , parsecMap , parserReturn , parserBind , parserFail , parserZero , parserPlus ) whereimport Text.Parsec.Pos import Text.Parsec.Error import Text.Parsec.Prim import Text.Parsec.Char import Text.Parsec.Combinator