2

私は幸せで単純なマークアップ言語のパーサーを書こうとしています。現在、無限ループとネストされた要素に問題があります。

私のマークアップ言語は、基本的に 2 つの要素で構成されています。1 つは「通常の」テキスト用で、もう 1 つは太字/強調テキスト用です。

data Markup
    = MarkupText   String
    | MarkupEmph   [Markup]

たとえば、次のようなテキストはFoo *bar*として解析される必要があります[MarkupText "Foo ", MarkupEmph [MarkupText "bar"]]

その例の字句解析は正常に機能しますが、解析すると無限ループが発生します-そして、私には理由がわかりません。これは私の現在のアプローチです:

-- The main parser: Parsing a list of "Markup"
Markups     :: { [Markup] }
            : Markups Markup                    { $1 ++ [$2] }
            | Markup                            { [$1]       }

-- One single markup element
Markup      :: { Markup }
            : '*' Markups1 '*'                  { MarkupEmph $2 }
            | Markup1                           { $1            }

-- The nested list inside *..*
Markups1    :: { [Markup] }
            : Markups1 Markup1                  { $1 ++ [$2] }
            | Markup1                           { [$1]       }

-- Markup which is always available:
Markup1     :: { Markup }
            : String                            { MarkupText $1 }

そのアプローチの何が問題なのですか?どうすれば解決できますか?

更新:申し訳ありません。Lexing が期待どおりに機能していませんでした。無限ループはレクサー内にありました。ごめん。:)

更新 2:リクエストに応じて、これをレクサーとして使用しています。

lexer :: String -> [Token]
lexer [] = []
lexer str@(c:cs)

    | c == '*'              = TokenSymbol "*"   : lexer cs
    -- ...more rules...
    | otherwise             = TokenString val   : lexer rest

  where (val, rest) = span isValidChar str
        isValidChar = (/= '*')

の最初のルールのlexer str代わりに があったため、無限再帰が発生しました。私の実際のコードはもう少し複雑だったので、それを見ませんでした。:)lexer cs'*'

4

1 に答える 1

1

パーサージェネレーターを扱ってからしばらく経ちました。

Happy かどうかわからない LR(1) パーサーが必要なようです。これを書いたら、誰かが私を訂正できると確信しています。

パーサーが先を見通すことができない場合、パーサーはこのステートメントに永久に留まります

Markups1    :: { [Markup] }
        : Markups1 Markup1 
        | Markup1

Markups1 を検索し、Markups1 を検索します。私が推測できる最善の方法は、Markup1 を先読みして文字列かどうかを確認することではありません。

このように書き換えてみてください

Markups1    :: { [Markup] }
        : Markup1 Markups1
        | 

基本的に、最初に文字列を見つけてから、別の文字列を探してみてください。見つからない場合は、そのステートメントを終了する必要があります。

于 2011-01-02T18:02:43.253 に答える