2012-03-02 21 views
1

私はHaskell Parsecライブラリを使用した文字列解析用にこのパーサを持っています。私の言語でParsecを使用した文字列トークンの字句解析

myStringLiteral = lexeme (
     do str <- between (char '\'') 
        (char '\'' <?> "end of string") 
        (many stringChar) 
        ; return (U.replace "''" "'" (foldr (maybe id (:)) "" str)) 

     <?> "literal string" 
     ) 

文字列は''(例:'this is my string')の内部アルファ-numが文字として定義されているが、これらの文字列はまた、それの内部'を含めることができます(この場合は'は別の'、EXでエスケープする必要があります。 'this is my string with '' inside of it')。

文字列の解析中に'が表示されたときに、次の文字列がある場合は、'があるかどうかを確認してください(そうでない場合は、文字列の末尾を返します)。しかし、私はそれを行う方法を知らない。何か案は?ありがとう!

答えて

5

、あなたは、エスケープ単一引用符のため

escapeOrStringChar :: Parser Char 
escapeOrStringChar = try (string "''" >> return '\'') <|> stringChar 

を特殊なケースを作ることができますし、そのためにstringLiteralを使用することができます

myStringLiteral = lexeme $ do 
    char '\'' 
    str <- many escapeOrStringChar 
    char '\'' <?> "end of string" 
    return str 
+0

優秀!ありがとう! –

-1

ParsecはLL(1)言語(details)のみを扱います。これは、パーサーが一度に1つのシンボルしか見ることができないことを意味します。あなたの言語はLL(2)です。あなたの言語を解析するためにあなた自身のFSMを書くことができます。または、解析する前にテキストを変換してLL(1)にすることができます。

実際、Parsecは語彙ではなく構文解析用に設計されています。良いアイデアは、他のツールを使って字句解析を行い、Parsecを使って文字のシーケンスの代わりに字句のシーケンスを解析することです。

構文はそれはそうと同じくらい簡単である場合
+2

Parsecは、 'try'コンビネータを使って非LL(1)文法を扱うことができます。 – bzn

+0

Parsecでは文字レベルのパーサが簡単です。したがって、_スキャナなしのパーサと考えることができます。別のレクサーを使用することも可能です(Daan Leijenのオリジナルのマニュアルでカバーされています)が、かなりの量のプレートが必要です。 –

+1

また、Parsecは文脈依存の解析(これはMonadであり、Applicativeではありません)を扱うことができるので、LL(1)よりも大きなクラスの文法を扱うことができます。 –

0

にそれを使用します。