You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Trifecta doesn't show the unexpected token in the error message like parsec does in the following example:
Program
importText.Parser.TokenimportText.Parser.CharimportText.Parser.CombinatorsimportText.Parser.Token.HighlightimportqualifiedText.ParsecasParsingLib-- import qualified Text.Trifecta as ParsingLibimportControl.ApplicativeimportData.HashSet (fromList)
identStyle::CharParsingm=>IdentifierStylem
identStyle =IdentifierStyle
{ _styleName ="identifier"
, _styleStart = letter
, _styleLetter = letter
, _styleReserved = fromList ["if", "then", "else"]
, _styleHighlight =Identifier
, _styleReservedHighlight =ReservedIdentifier
}
dataTerm=IfTermTermTerm
| IdStringderivingShowidentifier:: (Monadm, TokenParsingm) =>mString
identifier = ident identStyle <?>"identifier"reserved:: (Monadm, TokenParsingm) =>String->m()
reserved = reserve identStyle
ifExpr:: (Monadm, TokenParsingm) =>mTerm
ifExpr =If<$> (reserved "if"*> term) <*> (reserved "then"*> term) <*> (reserved "else"*> term)
term:: (Monadm, TokenParsingm) =>mTerm
term = ifExpr <|> (Id<$> identifier)
main::IO()
main =doParsingLib.parseTest term "if true then false else null"putStrLn"--"ParsingLib.parseTest term "if true then false then false"putStrLn"--"ParsingLib.parseTest term "else"
Parsec
If (Id "true") (Id "false") (Id "null")
--
parse error at (line 1, column 20):
unexpected "t"
expecting "else"
--
parse error at (line 1, column 5):
unexpected reserved identifier "else"
expecting identifier
Trifecta
If (Id "true") (Id "false") (Id "null")
--
(interactive):1:20: error: expected: "else"
if true then false then false<EOF>
^
--
(interactive):1:1: error: expected: "if", identifier
else<EOF>
^
The unexpected token is very useful in this case because it shows the reason why else is not a valid identifier (because it is reserved).
The text was updated successfully, but these errors were encountered:
I think the reason for this behaviour is the definition of ident from parsers:
ident:: (TokenParsingm, Monadm, IsStrings) =>IdentifierStylem->ms
ident s =fmap fromString $ token $ try $do
name <- highlight (_styleHighlight s)
((:)<$> _styleStart s <*> many (_styleLetter s) <?> _styleName s)
when (HashSet.member name (_styleReserved s)) $ unexpected $"reserved "++ _styleName s ++""++show name
return name
My guess is that when trifecta reaches the unexpected call, it backtracks (because of the try) and thus looses the reason given to unexpected.
Parsec has a different behaviour and preserves the error message when backtracking in some way.
Yes, the fact that the unexpected is inside of the try block is what kills the message here. try erases all the information about the error. We might try using LookAheadParsing to grab the word, then parse it twice, once to check for keywords, and once to take the value, but this will result in a clunkier more expensive parse with a worse type signature.
Trifecta doesn't show the unexpected token in the error message like parsec does in the following example:
Program
Parsec
Trifecta
The unexpected token is very useful in this case because it shows the reason why
else
is not a valid identifier (because it is reserved).The text was updated successfully, but these errors were encountered: