elm / parser

A parsing library, focused on simplicity and great error messages

Home Page:https://package.elm-lang.org/packages/elm/parser/latest

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Parser.multiComment does not chomp comment terminator in NotNestable mode

ianmackenzie opened this issue · comments

Build and run the following:

module Main exposing (..)

import Browser
import Html exposing (Html)
import Html.Attributes
import Parser exposing ((|.), (|=), Parser)


commentByItself : String
commentByItself =
    "/*abc*/"


commentWithTrailingText : String
commentWithTrailingText =
    "/*abc*/def"


nestable : Parser ()
nestable =
    Parser.multiComment "/*" "*/" Parser.Nestable |. Parser.end


notNestable : Parser ()
notNestable =
    Parser.multiComment "/*" "*/" Parser.NotNestable |. Parser.end


notNestableWorkaround : Parser ()
notNestableWorkaround =
    Parser.multiComment "/*" "*/" Parser.NotNestable
        |. Parser.token "*/"
        |. Parser.end


chompUntil : Parser ()
chompUntil =
    Parser.token "/*" |. Parser.chompUntil "*/" |. Parser.end


chompUntilWorkaround : Parser ()
chompUntilWorkaround =
    Parser.token "/*"
        |. Parser.chompUntil "*/"
        |. Parser.token "*/"
        |. Parser.end


main : Program () () ()
main =
    Browser.staticPage <|
        Html.table [ Html.Attributes.style "border-collapse" "collapse" ]
            [ Html.tr []
                [ Html.th borderAttributes [ Html.text "Parser" ]
                , Html.th borderAttributes [ Html.text commentByItself ]
                , Html.th borderAttributes [ Html.text commentWithTrailingText ]
                ]
            , exampleRow "nestable" nestable
            , exampleRow "notNestable" notNestable
            , exampleRow "notNestableWorkaround" notNestableWorkaround
            , exampleRow "chompUntil" chompUntil
            , exampleRow "chompUntilWorkaround" chompUntilWorkaround
            ]


exampleRow : String -> Parser () -> Html msg
exampleRow name parser =
    Html.tr []
        [ Html.td borderAttributes [ Html.text name ]
        , Html.td borderAttributes
            [ Html.text <|
                Debug.toString (Parser.run parser commentByItself)
            ]
        , Html.td borderAttributes
            [ Html.text <|
                Debug.toString (Parser.run parser commentWithTrailingText)
            ]
        ]


borderAttributes : List (Html.Attribute msg)
borderAttributes =
    [ Html.Attributes.style "border" "1px solid black" ]

You should see

Parser /*abc*/ /*abc*/def
nestable Ok () Err [{ col = 8, problem = ExpectingEnd, row = 1 }]
notNestable Err [{ col = 8, problem = ExpectingEnd, row = 1 }] Err [{ col = 8, problem = ExpectingEnd, row = 1 }]
notNestableWorkaround Ok () Err [{ col = 10, problem = ExpectingEnd, row = 1 }]
chompUntil Err [{ col = 8, problem = ExpectingEnd, row = 1 }] Err [{ col = 8, problem = ExpectingEnd, row = 1 }]
chompUntilWorkaround Ok () Err [{ col = 10, problem = ExpectingEnd, row = 1 }]

which has a couple issues:

  • nestable works as expected, notNestable and chompUntil do not
  • adding an extra |. Parser.token "*/" to notNestable 'fixes' the issue, but produces an incorrect error column number for the "/*abc*/def" case

I think the expected results should be:

Parser /*abc*/ /*abc*/def
nestable Ok () Err [{ col = 8, problem = ExpectingEnd, row = 1 }]
notNestable Ok () Err [{ col = 8, problem = ExpectingEnd, row = 1 }]
notNestableWorkaround Err [{ col = 8, problem = Expecting "*/", row = 1 }] Err [{ col = 8, problem = Expecting "*/", row = 1 }]
chompUntil Ok () Err [{ col = 8, problem = ExpectingEnd, row = 1 }]
chompUntilWorkaround Err [{ col = 8, problem = Expecting "*/", row = 1 }] Err [{ col = 8, problem = Expecting "*/", row = 1 }]

I'm on Windows 10.