parsing - Haskell:如何将语义空白集成到解析器中?
问题描述
我目前正在用 Haskell 编写一种语言https://github.com/EdONeill1/HENRYGCL
,并且在弄清楚如何允许将程序编写在多行上时遇到了麻烦。采用以下循环,将 1 加到 x 上,直到达到 10。
Henry > x := 1
Henry > if <x<10> [] x := <x+1> [] x := <x+10>
我希望该程序在某种程度上采用以下形式:
Henry > x := 1
Henry > if <x<10>
[] x := <x+1>
[] x := <x+10>
我考虑过使用该功能space
或newline
从Text.ParserCombinators.Parsec.Char
模块。这将使我能够识别(我认为)换行符\n
。使用它时,以下解析器功能:
ifStmt :: Parser HenryVal
ifStmt =
do
reserved "if"
cond <- bExpression <|>
do
_ <- char '<'
x <- try parseBinary
_ <- char '>'
return x
some (space <|> newline)
reserved "[]"
stmt1 <- statement
some (space <|> newline)
reserved " []"
stmt2 <- statement
return $ If cond stmt1 stmt2
当我尝试以下操作时收到以下错误:
Henry > x:=1
1
Henry > if <x<10>
Parse error at "Henry" (line 1, column 10):
unexpected end of input
expecting space or lf new-line
Henry > if <x<10>
Parse error at "Henry" (line 1, column 12):
unexpected end of input
expecting space, lf new-line or "[]"
Henry >
第一个错误是在我完成输入时按 Enter 引起>
的,第二个错误是按 Space 一次然后按 Enter 引起的。在这两种情况下,都没有更正换行符。我不确定lf
inlf new-line
实际意味着什么,因为据我了解,不应该按 Enter 给你一个换行符吗?
在我的代码的另一部分中,我有以下内容,whiteSpace = Token.whiteSpace lexer
. 当我some (space <|> newline)
用 this 替换 并在 之后按 enterif <x<10>
时,实际上会创建一个换行符。然而,尽管能够编写一个完整的 if 语句,但没有终止,它只是让我可以无限期地继续写作。
我很困惑如何从这里开始。我认为我的逻辑使用some (space <|> newline)
是正确的,就好像程序遇到至少一个空格或换行符,一个空格或换行符,但我知道我的实现是不正确的。我认为这可能whiteSpace
会导致某个地方,但似乎这是另一个死胡同。
解决方案
解析器看起来不错。这里的问题是main
当前一次在一行上运行解析器。您需要在运行解析器之前累积整个输入。
推荐阅读
- c++ - 动态数组和指针表示法
- php - 在收到字段后尝试将我的 PHP 表单重定向到另一个页面时出现错误
- javascript - 将函数设置为已弃用
- android - 如何解决:无法解决:com.mapbox.mapboxsdk:mapbox-android-sdk:9.5.0
- if-statement - If 语句和输入变量的值 - Pine 脚本 - Tradingview
- css - 使用 CSS Grid Full Bleed 布局获取“下一个/图像”?
- python - 无法从控制台发送消息到不和谐
- php - 我有这个 PHP 表单处理文件,它可以工作,但有 2 个我无法解决的问题
- heroku - 如何使用 Heroku 创建数据库
- python - 更改日期熊猫