のすべてのパーサーは、トークンの後に空白を食べるためにText.Parsec.Token
丁寧に使用します。lexeme
残念ながら、空白には新しい行が含まれています。これを式のターミネータとして使用したいと思います。lexeme
新しい行を残すように説得する方法はありますか?
4 に答える
いいえそうではありません。関連するコードは次のとおりです。
lexeme p
= do{ x <- p; whiteSpace; return x }
--whiteSpace
whiteSpace
| noLine && noMulti = skipMany (simpleSpace <?> "")
| noLine = skipMany (simpleSpace <|> multiLineComment <?> "")
| noMulti = skipMany (simpleSpace <|> oneLineComment <?> "")
| otherwise = skipMany (simpleSpace <|> oneLineComment <|> multiLineComment <?> "")
where
noLine = null (commentLine languageDef)
noMulti = null (commentStart languageDef)
whitespace
その where 句で、唯一のオプションがコメントを処理していることに気付くでしょう。このlexeme
関数はwhitespace
を使用し、 の残りの部分で自由に使用されparsec.token
ます。
2015年9月28日更新
私にとっての究極の解決策は、適切な語彙アナライザー ( alex ) を使用することでした。Parsec は構文解析ライブラリとして非常に優れた仕事をしており、字句解析を行うために壊すことができるのは設計の功績ですが、小規模で単純なプロジェクトを除いて、すぐに扱いにくくなります。私は今、alex を使用してトークンの線形セットを作成し、Parsec がそれらを AST に変換します。
改行が式のターミネータである場合、改行ごとに入力を分割し、各行を単独で解析することが理にかなっています。
不可能であるという他の回答は正しいですが、char パーサーは語彙素パーサーを使用していないことを指摘したいと思います。
parsec を使用して、いくつかの html 口ひげテンプレートを分析します。その分析では空白が重要です。私がしたことは、単に ">" と "}}" の文字列をText.Parsec.Char.string
.
タグ内ではなくタグ間の空白に関心があるため、語彙素パーサーは末尾の空白のみを消費するため、予約済み演算子を使用して「<」や「{{」などを解析できます。