Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing Parsec:处理重叠的解析器_Parsing_Haskell_Parsec - Fatal编程技术网

Parsing Parsec:处理重叠的解析器

Parsing Parsec:处理重叠的解析器,parsing,haskell,parsec,Parsing,Haskell,Parsec,我对Haskell中的解析非常陌生,但它基本上是有意义的 我正在构建一个模板程序,主要是为了更好地学习解析;模板可以通过{{value}}符号插入值 这是我当前的解析器 data Template a = Template [Either String a] data Directive = Directive String templateFromFile :: FilePath -> IO (Either ParseError (Template Directive)) templa

我对Haskell中的解析非常陌生,但它基本上是有意义的

我正在构建一个模板程序,主要是为了更好地学习解析;模板可以通过
{{value}}
符号插入值

这是我当前的解析器

data Template a = Template [Either String a]
data Directive = Directive String

templateFromFile :: FilePath -> IO (Either ParseError (Template Directive))
templateFromFile = parseFromFile templateParser

templateParser :: Parser (Template Directive)
templateParser = do
  tmp <- template
  eof
  return tmp

template :: Parser (Template Directive)
template = Template <$> many (dir <|> txt)
    where
      dir = Right <$> directive
      txt = Left <$> many1 (anyChar <* notFollowedBy directive)

directive :: Parser Directive
directive = do
  _ <- string "{{"
  txt <- manyTill anyChar (string "}}")
  return $ Directive txt
当我使用
templateFromFile./template.txt“
运行此命令时,我得到错误:

Left "./template.txt" (line 5, column 17):
unexpected Directive " expression "
为什么会发生这种情况?我如何修复它

我的基本理解是
many1(anyChar

当在中间解析文本时,它将在最后的<代码> t>代码>停止,在指令未被消耗之前留下新行(因为它是一个字符,后面跟着一个指令)。,因此,在下一次迭代中,您尝试解析一个指令,但失败。然后在该换行符上重试

txt
,解析器希望它后面没有一个指令,但它找到了一个,因此出现了错误


当在中间解析文本时,它将在最后的<代码> t>代码>停止,在指令未被消耗之前留下新行(因为它是一个字符,后面跟着一个指令)。,因此下一次迭代,您尝试解析一个指令,但失败了。然后在该换行符上重试

txt
,解析器希望它后面没有一个指令,但它找到了一个,因此出现了错误。

您有几个问题。首先,在Parsec中,如果解析器使用任何输入,然后失败,这就是一个错误。因此,当解析器:

anyChar <* notFollowedBy directive
let p1 = many1 (anyChar <* notFollowedBy directive)
如果遇到指令,将永远不会成功。例如:

parse p1 "" "okay"   -- works
parse p1 "" "oops {{}}"  -- will fail after consuming "oops "
您可以通过插入
try
子句来解决此问题:

let p2 = many1 (try (anyChar <* notFollowedBy directive))
parse p2 "" "okay {{}}"
它首先检查,在当前位置,在抓取字符之前,我们没有查看指令。不需要
try
子句,因为如果失败,它将在不使用输入的情况下失败。(
notfollowerdby
从不使用输入,如文档所示。)

因此,以您最初的示例为例:

txt = Left <$> many1 (notFollowedBy directive *> anyChar)
txt=Left many1(不遵循指令*>anyChar)

应该可以正常工作。

您有几个问题。首先,在Parsec中,如果解析器使用任何输入,然后失败,那就是一个错误。因此,当解析器:

anyChar <* notFollowedBy directive
let p1 = many1 (anyChar <* notFollowedBy directive)
如果遇到指令,将永远不会成功。例如:

parse p1 "" "okay"   -- works
parse p1 "" "oops {{}}"  -- will fail after consuming "oops "
您可以通过插入
try
子句来解决此问题:

let p2 = many1 (try (anyChar <* notFollowedBy directive))
parse p2 "" "okay {{}}"
它首先检查,在当前位置,在抓取字符之前,我们没有查看指令。不需要
try
子句,因为如果失败,它将在不使用输入的情况下失败。(
notfollowerdby
从不使用输入,如文档所示。)

因此,以您最初的示例为例:

txt = Left <$> many1 (notFollowedBy directive *> anyChar)
txt=Left many1(不遵循指令*>anyChar)
应该没问题。

是一个用于执行搜索并替换为解析器的库 搜索和替换功能不可用 , 它可以找到您的
{{value}}
模式,然后替换为其他文本

streamEdit
是从通用版本构建的 调用的
模板
函数的

import Replace.Megaparsec
导入文本.Megaparsec
导入Text.Megaparsec.Char
导入数据.Char
输入=未线
[“{{value}}”
, ""
,“这是普通文本”
, ""
,“{{expression}}”
]
指令::Parsec无效字符串
指令=do
_
是一个用于执行搜索并替换为解析器的库
搜索和替换功能不可用
,
它可以找到您的
{{value}}
模式,然后替换为其他文本

streamEdit
是从通用版本构建的 调用的
模板
函数的

import Replace.Megaparsec
导入文本.Megaparsec
导入Text.Megaparsec.Char
导入数据.Char
输入=未线
[“{{value}}”
, ""
,“这是普通文本”
, ""
,“{{expression}}”
]
指令::Parsec无效字符串
指令=do

_有意义;我如何才能最好地修复它以实现我的期望?
txt=many1(notFollowedBy directive*>anyChar)
是最简单的修复,尽管它每个指令运行两次
directive
。有意义;我如何才能最好地修复它以实现我的期望?
txt=many1(notFollowedBy directive*>anyChar)
是最简单的修复方法,尽管每个指令运行两次
指令。