了解 Parsec 中的 SourceName
Understanding SourceName in Parsec
我对 Parsec
中 parse
函数中 SourceName
的含义有疑问。似乎我阅读的所有 books/blogs/tutorials 都只是跳过它是什么并使用 "stdin"
、"(stdin)"
或任意字符串,例如 "test parser"
。指定为 SourceName
有什么区别吗?
我看了Parsec
的source code,好像是用来建仓的。但是为什么它是什么来源很重要(确实是 String
)。听起来我在大多数情况下都不需要担心。
提前致谢!
在 Parsec 中,SourceName
是一个 String
,用于生成错误消息。在 REPL 中,这不是很重要:
λ> parse expression "<stdin>" ")"
Left "<stdin>" (line 1, column 1):
unexpected ")"
expecting expression
如果我们使用 "foo"
而不是 "<stdin>"
,如果看起来像这样:
Left "foo" (line 1, column 1):
unexpected ")"
expecting expression
这在编写将多个文件作为输入的程序(如编译器或解释器)时很有用。例如,在我的解释器中,我有以下功能:
runFile :: FilePath -> IO ()
runFile path = do code <- readFile path
start <- prelude
evalString path start code >>= putStrLn
在这里,我将 path
——您正在 运行 的文件的路径——传递给解析表达式的函数。这样,错误消息将告诉您 哪个 文件有解析错误,以及行号。
λ> runFile "/Users/tikhon/tmp/foo.tpl"
Error: "/Users/tikhon/tmp/foo.tpl" (line 1, column 1):
unexpected ')'
expecting expression or end of input!
我对 Parsec
中 parse
函数中 SourceName
的含义有疑问。似乎我阅读的所有 books/blogs/tutorials 都只是跳过它是什么并使用 "stdin"
、"(stdin)"
或任意字符串,例如 "test parser"
。指定为 SourceName
有什么区别吗?
我看了Parsec
的source code,好像是用来建仓的。但是为什么它是什么来源很重要(确实是 String
)。听起来我在大多数情况下都不需要担心。
提前致谢!
在 Parsec 中,SourceName
是一个 String
,用于生成错误消息。在 REPL 中,这不是很重要:
λ> parse expression "<stdin>" ")"
Left "<stdin>" (line 1, column 1):
unexpected ")"
expecting expression
如果我们使用 "foo"
而不是 "<stdin>"
,如果看起来像这样:
Left "foo" (line 1, column 1):
unexpected ")"
expecting expression
这在编写将多个文件作为输入的程序(如编译器或解释器)时很有用。例如,在我的解释器中,我有以下功能:
runFile :: FilePath -> IO ()
runFile path = do code <- readFile path
start <- prelude
evalString path start code >>= putStrLn
在这里,我将 path
——您正在 运行 的文件的路径——传递给解析表达式的函数。这样,错误消息将告诉您 哪个 文件有解析错误,以及行号。
λ> runFile "/Users/tikhon/tmp/foo.tpl"
Error: "/Users/tikhon/tmp/foo.tpl" (line 1, column 1):
unexpected ')'
expecting expression or end of input!