Trying something to get rid of so much try/choice.

This commit is contained in:
Igor Ranieri 2025-09-28 22:15:45 +02:00
parent f9423d4af0
commit 9ee5a6317d

View file

@ -7,7 +7,7 @@ module Lexer (
) )
where where
import Control.Monad (mfilter, void) import Control.Monad (guard, mfilter, void)
import Data.Char (ord, toLower) import Data.Char (ord, toLower)
import Data.Functor (($>)) import Data.Functor (($>))
import Data.Text (Text, intercalate) import Data.Text (Text, intercalate)
@ -87,39 +87,39 @@ lexText = go
rest <- go rest <- go
pure (toks <> rest) pure (toks <> rest)
{- FOURMOLU_DISABLE -} topLevel = do
topLevel = -- check for start-of-line markup first
-- backtracking here so we always have a chance to try "other", the "catch-all-leave-to-parser-to-deal-with" choice lineStart <-
-- TODO: is this desirable? do we throw lexer error at all? optionMaybe $
try choice
( choice [ try expression
, try birdTrack
, headers
]
case lineStart of
Just toks -> pure toks
Nothing ->
choice $
-- Sorted in -- Sorted in
-- - longest to shortest parse path -- - longest to shortest parse path
-- - highest frequency to lowest frequency (for performance?) -- - highest frequency to lowest frequency (for performance?)
-- - more exact to more freeform (the latter can be the former but not vice versa) -- - more exact to more freeform (the latter can be the former but not vice versa)
[ spaceToken [ spaceToken
, newlineToken , newlineToken
, try module_ , try module_
, quotes , quotes
, try expression , -- starts with "\"
, birdTrack try mathMultiline
-- starts with "\"
, try mathMultiline
, try mathInline , try mathInline
, escape , escape
, headers
, labeledLink , labeledLink
, link , link
, anchor , anchor
, numericEntity , numericEntity
, textElement , textElement
, other
] ]
)
<|> other
{- FOURMOLU_ENABLE -}
-- Tokens -- Tokens
@ -174,11 +174,7 @@ eol = void "\n" <|> void "\r\n" <|> Parsec.eof
-- Start of line // start of file -- Start of line // start of file
sol :: Parser () sol :: Parser ()
sol = do sol = getPosition >>= guard . (== 1) . sourceColumn
p <- getPosition
if sourceColumn p == 1
then pure ()
else fail "Not at start of line/document"
header1 :: Lexer header1 :: Lexer
header1 = delimitedNoTrailing "= " eol (Header One) header1 = delimitedNoTrailing "= " eol (Header One)