parsing - Trifecta 中的自定义状态

标签 parsing haskell monads parser-combinators trifecta

我正在使用Trifecta解析器组合器库和我的解析器输出 AST 数据类型的实例。我希望每个实例都有唯一的 ID(简单的 Int)。

在秒差距中,我将创建自定义状态并在需要时增加 ID。我们如何在 Trifecta 中做到这一点?

最佳答案

您可以使用 StateT monad 转换器增强 Parser monad 以获得您想要的内容。这与库的其余部分集成得很好,因为大多数组合器使用类型类而不是具体类型(这意味着您不必为代码工作做太多的提升)。这是一个很好的例子。它使用由空格分隔的标识符和符号来解析语法。每个标识符都有一个唯一的编号。

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 结果:

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 '-']

关于parsing - Trifecta 中的自定义状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18806586/

相关文章:

haskell - 使用 Data.Tree.Zipper 遍历玫瑰树

haskell - 与分数相关的类型错误

haskell - 动态类型语言中的 IO Monad

java - 为什么不能所有 Functor 都是 Monad?

parsing - 底层秒差距单子(monad)

html - 使用 Swift 解析网站源 HTML 文件

php - 使用正则表达式解析 SQL,排除带引号的文字

python - 如何使用 Python HTML Parser 提取特定链接

parsing - 正确设置 Cup/JLex 解析

list - 通过分布 [] 来简化代码