私は幸せで単純なマークアップ言語のパーサーを書こうとしています。現在、無限ループとネストされた要素に問題があります。
私のマークアップ言語は、基本的に 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
'*'