首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在使用megaparsec进行解析后出现错误包

在使用megaparsec进行解析后出现错误包
EN

Stack Overflow用户
提问于 2019-01-30 06:05:59
回答 1查看 257关注 0票数 2

我目前有一个在megaparsec中工作的解析器,在那里我为我的程序构建了一个AST。现在,我希望在AST上执行一些除草操作,同时能够使用与解析器相同类型的错误。虽然这一阶段是在解析之后,我想知道是否有兆秒这样做的一般做法。有没有办法让我提取每一行和注释(在捆绑包中使用),并将其添加到我的AST中的每个项目?人们有没有其他方法来解决这个问题呢?

如果这听起来是开放式的,我提前道歉,但我主要想知道有没有比自己获取行号和创建捆绑包更好的想法。我对haskell还是个新手,所以我还不能正确浏览所有的源代码。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-05 06:21:58

兆秒开发人员here回答了这个问题。

总之,解析器有一个返回当前字符索引的getOffset函数。您可以将其与初始PosState一起使用来创建一个错误包,稍后可以漂亮地打印出来。

我有一个样例项目within the github thread,并再次粘贴到这里:

代码语言:javascript
复制
module TestParser where

import           Data.List.NonEmpty as NonEmpty
import qualified Data.Maybe         as Maybe
import qualified Data.Set           as Set
import           Data.Void
import           Parser
import           Text.Megaparsec

data Sample
  = Test Int
         String
  | TestBlock [Sample]
  | TestBlank
  deriving (Show, Eq)

sampleParser :: Parser Sample
sampleParser = do
  l <- many testParser
  return $ f l
  where
    f []  = TestBlank
    f [s] = s
    f p   = TestBlock p

testParser :: Parser Sample
testParser = do
  offset <- getOffset
  test <- symbol "test"
  return $ Test offset test

fullTestParser :: Parser Sample
fullTestParser = baseParser testParser

testParse :: String -> Maybe (ParseErrorBundle String Void)
testParse input =
  case parse (baseParser sampleParser) "" input of
    Left e -> Just e
    Right x -> do
      (offset, msg) <- testVerify x
      let initialState =
            PosState
              { pstateInput = input
              , pstateOffset = 0
              , pstateSourcePos = initialPos ""
              , pstateTabWidth = defaultTabWidth
              , pstateLinePrefix = ""
              }
      let errorBundle =
            ParseErrorBundle
              { bundleErrors = NonEmpty.fromList [TrivialError offset Nothing Set.empty]
                            -- ^ A collection of 'ParseError's that is sorted by parse error offsets
              , bundlePosState = initialState
                            -- ^ State that is used for line\/column calculation
              }
      return errorBundle

-- Sample verify; throw an error on the second test key
testVerify :: Sample -> Maybe (Int, String)
testVerify tree =
  case tree of
    TestBlock [_, Test a _, _] -> Just (a, "Bad")
    _                          -> Nothing

testMain :: IO ()
testMain = do
  testExample "test test test"
  putStrLn "Done"

testExample :: String -> IO ()
testExample input =
  case testParse input of
    Just error -> putStrLn (errorBundlePretty error)
    Nothing    -> putStrLn "pass"

有些部分来自其他文件,但重要的部分在代码中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54430335

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档