13

のすべてのパーサーは、トークンの後に空白を食べるためにText.Parsec.Token丁寧に使用します。lexeme残念ながら、空白には新しい行が含まれています。これを式のターミネータとして使用したいと思います。lexeme新しい行を残すように説得する方法はありますか?

4

4 に答える 4

6

いいえそうではありません。関連するコードは次のとおりです。

Text.Parsec.Tokenから:

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 に変換します。

于 2011-04-17T15:53:16.253 に答える
3

改行が式のターミネータである場合、改行ごとに入力を分割し、各行を単独で解析することが理にかなっています。

于 2011-04-15T07:14:32.163 に答える
1

不可能であるという他の回答は正しいですが、char パーサーは語彙素パーサーを使用していないことを指摘したいと思います。
parsec を使用して、いくつかの html 口ひげテンプレートを分析します。その分析では空白が重要です。私がしたことは、単に ">" と "}}" の文字列をText.Parsec.Char.string.
タグ内ではなくタグ間の空白に関心があるため、語彙素パーサーは末尾の空白のみを消費するため、予約済み演算子を使用して「<」や「{{」などを解析できます。

于 2012-12-06T17:24:15.730 に答える