gpt4 book ai didi

elm - 函数式编程 : understand parser combinator

转载 作者:行者123 更新时间:2023-12-04 19:00:24 26 4
gpt4 key购买 nike

我试图使用解析器组合器解决问题。我尝试了以下方法:

备注 :以下代码使用 combinator library

styleParserItalic : Bool -> Parser ( List (List Char , Style))
styleParserItalic bolded =
let
style = if bolded then Italic else Unstyled
in
(end `andThen` always ( succeed ( [] )))
<|> (string "(!ITALIC!)" `andThen` \_ -> styleParserItalic ( not bolded ) )
<|> ( anyChar `andThen` \c -> styleParserItalic bolded `andThen` \cs -> succeed ((c :: [],style) :: cs) )

styleParserItalic 以来,我一直在努力理解这个解析器是如何运行的。在解析器成功之前调用解析器。

有人可以解释解析器在给定字符串时如何工作吗?

如果有人对解析器的用途和完整代码感兴趣, here是我之前的问题。

这是我迄今为止所了解的

解析器将首先检查它是否是行尾,如果不是,它将尝试解析字符串 (!ITALIC!)如果是这种情况,那么它将使用参数 True 或 false 调用解析器(如果为 false 则将使其成为 true ..)

如果解析器没有找到字符串 (!ITALIC!),它将尝试解析任何字符,然后它会再次调用解析器。

让我困惑的是,只要解析器成功解析任何字符,解析器就会继续调用自己!

编辑:* 注意下面不是问题的一部分,如果有人感兴趣,只是为了分享代码

感谢所有回复,我已经更新了解析器以解析粗斜体下划线...,根据下面的屏幕截图 enter image description here
type Style = Bold| Unstyled | Italic | Coded | Lined | Titled | Marked     | Underline

styleParser : Bool ->Bool ->Bool ->Bool-> Bool-> Bool->Bool
-> Parser ( List (List Char , (Style,Style,Style,Style,Style,Style,Style)))
--(bold,italic ,code,line ,Titled,mark)
styleParser bolded italiced coded lined titled marked underlined=
let
style = (
if bolded then Bold else Unstyled
,if italiced then Italic else Unstyled
,if coded then Coded else Unstyled
,if lined then Lined else Unstyled
,if titled then Titled else Unstyled
,if marked then Marked else Unstyled
,if underlined then Underline else Unstyled
)
in
(end `andThen` always ( succeed ( [] )))
<|> (string "//" `andThen` \_ -> styleParser bolded italiced coded lined titled marked (not underlined))
<|> (string "**" `andThen` \_ -> styleParser (not bolded) italiced coded lined titled marked underlined)
<|> (string "*" `andThen` \_ -> styleParser bolded (not italiced) coded lined titled marked underlined)
<|> (string "`" `andThen` \_ -> styleParser bolded italiced (not coded) lined titled marked underlined)
<|> (string "/br" `andThen` \_ -> styleParser bolded italiced coded (not lined) titled marked underlined)
<|> (string "/*" `andThen` \_ -> styleParser bolded italiced coded lined (not titled) marked underlined)
<|> (string "{-" `andThen` \_ -> styleParser bolded italiced coded lined titled (not marked) underlined)
<|> ( anyChar `andThen` \c -> styleParser bolded italiced coded lined titled marked underlined `andThen` \cs -> succeed ((c :: [],style) :: cs) )


foldStyleHtml : List ( List Char , ( Style,Style,Style,Style,Style,Style,Style) ) -> List (Html Msg)
foldStyleHtml lst =
List.map styleToHtml lst


styleToHtml : ( List Char, (Style ,Style,Style,Style,Style,Style,Style)) -> Html Msg
styleToHtml (a,b) =
case b of
(Bold,Italic,_,_,_,_,Unstyled) -> strong [] [em [][ text (String.fromList a)]]
(Bold,Italic,_,_,_,_,Underline) -> u[][ strong [] [em [][ text (String.fromList a)]]]
(Bold,Unstyled,_,_,_,_,Underline) -> u[][ strong [] [text (String.fromList a)]]
(Unstyled,Italic,_,_,_,_,Underline) -> u[][ em [] [text (String.fromList a)]]
(Unstyled,Italic,_,_,_,_,_) -> em[] [text (String.fromList a)]
(Bold,Unstyled,_,_,_,_,_) -> strong [][ text (String.fromList a)]
(_,_,Coded,_,_,_,_) -> code [codeStyle ][text (String.fromList a)]
(_,_,_,Lined,_,_,_) -> br [][text " "]
-- (_,_,_,_,Titled,_,_) -> div [][text (String.fromList a)]
(_,_,_,_,_,Marked,_) -> mark [][text (String.fromList a)]
(_,_,_,_,_,_,Underline) -> u [][text (String.fromList a)]
(_,_,_,_,_,_,_) -> text (String.fromList a)

htmlParser : Parser (List (Html Msg))
htmlParser =
styleParser False False False False False False False `andThen` (succeed << foldStyleHtml )

runParser : Parser (List (Html Msg)) -> String -> Html Msg
runParser parser str =
case parse parser str of
(Ok htmls,_)-> div [] htmls
(Err err, _) -> div [ style [("color", "red")] ] [ text <| toString <| err]

最佳答案

解析器组合器(通常)在成功时消耗输入。在这个库中,如果 string "(!ITALIC!)"失败,它不会消耗任何输入。自 <|>使用组合器,然后它尝试使用以 anyChar 开头的代码的下一部分.

anyChar成功,它使用该单个字符并在 c 中捕获它后 andThen .然后,当递归调用 anyChar 时,剩余的字符串(除了 styleParserItalic bolded 捕获的字符之外的所有内容)被“爬行”。制作。那第二个andThen将递归组合器的输出捕获到 cs 中并将捕获的字符添加到来自递归调用的字符列表的其余部分。

我认为要记住的重要部分是组合器在成功时消耗输入,并且(通常)在失败时不消耗输入。

关于elm - 函数式编程 : understand parser combinator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38659344/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com