Tôi đã cố gắng giải quyết vấn đề bằng trình kết hợp trình phân tích cú pháp. Tôi thử như sau:lập trình chức năng: hiểu trình phân tích cú pháp phân tích
Note: mã dưới đây sử dụng 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))
Tôi đang đấu tranh để hiểu làm thế nào phân tích cú pháp này chạy kể từ khi phân tích cú pháp styleParserItalic
được gọi trước khi phân tích cú pháp thành công.
Ai đó có thể giải thích cách trình phân tích cú pháp hoạt động khi nó được cung cấp một chuỗi ký tự?
Nếu ai đó quan tâm đến mục đích của trình phân tích cú pháp và mã đầy đủ, here là câu hỏi trước của tôi.
Dưới đây là những gì tôi đã hiểu vậy, đến nay
Các phân tích cú pháp sẽ kiểm tra đầu tiên nếu nó là kết thúc của một dòng, nếu không nó sẽ cố gắng phân tích cú pháp chuỗi (!ITALIC!)
nếu đó là trường hợp sau đó nó sẽ gọi trình phân tích cú pháp với tham số True hoặc false (nếu false thì sẽ làm cho nó đúng ..)
Nếu trình phân tích cú pháp không tìm thấy chuỗi (! ITALIC!) nó sẽ phân tích cú pháp bất kỳ ký tự nào, nó sẽ gọi trình phân tích cú pháp lần nữa.
Điều gây nhầm lẫn cho tôi là trình phân tích cú pháp sẽ tiếp tục gọi chính nó miễn là nó thành công với việc phân tích cú pháp bất kỳ ký tự nào!
chỉnh sửa: *LƯU Ý CÁC DƯỚI ĐÂY LÀ KHÔNG PHẢI LÀ MỘT PHẦN CỦA CÂU HỎI, chỉ để chia sẻ mã NẾU AI ĐÓ LÀ QUAN TÂM
nhờ cho tất cả các câu trả lời, tôi đã cập nhật các phân tích cú pháp để phân tích gạch dưới nghiêng Bold ..., theo ảnh chụp màn hình dưới đây
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]
Tôi khiêm nhường sẽ đề cập đến [một bài blot Tôi đã viết một vài năm trước đây] (https://oldfashionedsoftware.com/2008/08/16/easy-parsing-in-scala /) dưới dạng giới thiệu về các trình kết hợp phân tích cú pháp. –