User State in Trifecta

I use the Trifecta parser-parser library, and my parsers output instances of the AST data type. I want each instance to have a unique identifier (which is a simple Int).

In Parsec, I would create a user state and increment the ID if necessary. How can we do this in Trifecta?

+6
source share
1 answer

You can enhance Parser monad with StateT monad transformer to get what you want. This works well with the rest of the library, as most combinators use type classes rather than specific types (this means that you don’t have to do much for the code to work). Here is a worthy example of this. It parses a grammar with identifiers and characters separated by spaces. Each identifier is assigned a unique number.

 module Main where import Text.Trifecta import Control.Monad.State import Control.Applicative import Data.Monoid data Identifier = Identifier String Int deriving (Show) identifier :: StateT Int Parser Identifier identifier = do name <- some letter newId <- get modify (+1) return $ Identifier name newId symbolToken :: Parser Char symbolToken = oneOf "+-*/" data Token = IdentifierToken Identifier | SymbolToken Char deriving (Show) singleToken :: StateT Int Parser Token singleToken = try (IdentifierToken <$> identifier) <|> (SymbolToken <$> lift symbolToken) parseTokens :: StateT Int Parser [Token] parseTokens = singleToken `sepBy1` spaces testParse :: String -> Result [Token] testParse = parseString (evalStateT parseTokens 0) mempty test1 :: Result [Token] test1 = testParse "these are identifiers and + some / symbols -" 

test1 results in:

 Success [IdentifierToken (Identifier "these" 0) ,IdentifierToken (Identifier "are" 1) ,IdentifierToken (Identifier "identifiers" 2) ,IdentifierToken (Identifier "and" 3) ,SymbolToken '+',IdentifierToken (Identifier "some" 4) ,SymbolToken '/',IdentifierToken (Identifier "symbols" 5),SymbolToken '-'] 
+5
source

Source: https://habr.com/ru/post/953837/


All Articles