Haskell Parsec没有使用所有输入?

Haskell Parsec没有使用所有输入?,haskell,parsec,Haskell,Parsec,我正在编写一些代码来解析中定义的简单命令式语言中的命令 编程语言理论(Reynolds,1998) 我有一个lexer模块,给定一个字符串,如果它是一个有效的语言表达式,则从中提取标记,然后将该标记列表传递给解析器,解析器应该构建命令的内部表示(定义为代数数据类型) 这些是我的代币: ——解析器的标记 数据令牌=Kw关键字 |Num Int |运算运算符 |Str字符串 |符号 衍生节目 我在使用二进制运算符时遇到问题。我将把和作为一个例子,但它们的情况都是一样的,不管是布尔数还是整数 例如,

我正在编写一些代码来解析中定义的简单命令式语言中的命令 编程语言理论(Reynolds,1998)

我有一个lexer模块,给定一个字符串,如果它是一个有效的语言表达式,则从中提取标记,然后将该标记列表传递给解析器,解析器应该构建命令的内部表示(定义为代数数据类型)

这些是我的代币:

——解析器的标记
数据令牌=Kw关键字
|Num Int
|运算运算符
|Str字符串
|符号
衍生节目
我在使用二进制运算符时遇到问题。我将把和作为一个例子,但它们的情况都是一样的,不管是布尔数还是整数

例如,如果我运行程序解析“x:=2+3” 我应该从lexer中获得以下令牌列表
[Str“x”,Op冒号,Op相等,Num 2,Op,Plus,Num 3]
这就是我得到的

但是解析器应该返回命令
分配“x”(Ibin Plus(常数2)(常数3)
这是命令的正确表示形式。但我得到的不是这样的表示形式:
分配“x”(常数2)

我猜我在pIntExpr函数中的某个点上搞砸了,因为赋值的变量标识符和:=被解析了,它没有解析最后的元素。下面是这个例子的相关解析器,看看是否有人能帮我定位我做错了什么

——整数表达式
数据IntExpr=Const Int
|Var Iden--Iden=String
|Neg IntExpr
|IBin OPINTEXPR IntExpr
衍生节目
类型TParser=Parsec[Token]()
--命令的内部表示形式
数据通信=跳过
|分配Iden IntExpr
|如果断言Comm Comm
|序列通信
|而断言通信
|Newvar Iden IntExpr通信
衍生节目
--非顺序命令解析器
pComm'::TParser Comm
pComm'=选择[pif、pskip、密码、时间、pNewVar]
--赋值命令的解析器
密码::tPasser通信

pAssign=do vchoice函数将按照解析器在列表中的顺序尝试解析器

由于变量的yoiur解析器出现在更复杂加法表达式的解析器之前,因此它在尝试另一个表达式之前成功

要解决此问题,请将变量解析器放在以变量开头的任何表达式之后(并在使用choice时考虑任何其他子字符串匹配问题)

类似的问题包括3-4+1到-2。人们希望在没有其他优先权的情况下(所以是求和-项而不是求和)左联想


你也可能不希望1 + 10×5变为55,所以如果你想实现运算符优先级,你就必须在+和*等周围小心。你可以通过解析乘法作为一个术语的表达式来实现这一点,然后将加性表达式作为一个和的和。不幸的是,这是一项大学作业,我们得到了代码“骨架”而且不应该使用buildExpressionParser。无论如何,感谢您提供的信息,这可能对将来来到这里的人很有用。@AndrewC我用我对您的建议所做的更新了问题。感谢您提供的有关选择的提示,它帮助我了解了发生了什么(我想)另请参见: