
Dear Haskellers, I have tried the "while language parser" tutorial on haskellwiki, but I encounter an problem I can not understand here, The following is the code: http://pastebin.com/saC9vwCn The problem is, with the code, the parse result of "fact := a / b * c" is *Main> parseString "fact := a / b * c" Assign "fact" (ABinary Multiply (ABinary Divide (Var "a") (Var "b")) (Var "c")) *Main> But if I swap the order of "/" and "*" operators in aOperators(make "*" appear before "/" operator), then the result is *Main> parseString "fact := a / b * c" Assign "fact" (ABinary Divide (Var "a") (ABinary Multiply (Var "b") (Var "c"))) *Main> So it seems that the order of the operator will affect the parse result. What's the problem with my code? How can I make my program to produce consistent parse result. Best Regards, --m00nlight

On Mon, Apr 13, 2015 at 02:56:47PM +0800, m00nlight wrote:
Dear Haskellers,
I have tried the "while language parser" tutorial on haskellwiki, but I encounter an problem I can not understand here, The following is the code:
So it seems that the order of the operator will affect the parse result. What's the problem with my code? How can I make my program to produce consistent parse result.
Checking the documentation for OperatorTable [1] (the first argument to buildExpressionParser), it seems it is working as expected: An OperatorTable s u m a is a list of Operator s u m a lists. The list is ordered in descending precedence. All operators in one list have the same precedence (but may have a different associativity). I think you can take advantage of the fact that OperatorTable is /a list of lists/, hence aOperators = [ [Prefix (reservedOp "-" >> return (Neg ))] , [Infix (reservedOp "/" >> return (ABinary Divide )) AssocLeft, Infix (reservedOp "*" >> return (ABinary Multiply )) AssocLeft] , [Infix (reservedOp "+" >> return (ABinary Add )) AssocLeft] , [Infix (reservedOp "-" >> return (ABinary Subtract )) AssocLeft] ] should do the trick (try swapping the elements in the second list. Will this do? [1] http://hackage.haskell.org/package/parsec-3.0.0/docs/Text-Parsec-Expr.html#t...

Hi Francesco,
Thanks for your reply. But after I change the aOperators like the following, it still produce non-correct parse result.
aOperators = [ [Prefix (reservedOp "-" >> return (Neg ))]
, [ Infix (reservedOp "*" >> return (ABinary Divide )) AssocLeft,
Infix (reservedOp "/" >> return (ABinary Multiply )) AssocLeft]
, [Infix (reservedOp "+" >> return (ABinary Add )) AssocLeft,
Infix (reservedOp "-" >> return (ABinary Subtract )) AssocLeft]
]
parse result:
*Main> parseString "res := a / b * c"
Assign "res" (ABinary Divide (ABinary Multiply (Var "a") (Var "b")) (Var "c"))
*Main>
--m00nlight
在2015年04月13 15时21分, "Francesco Ariis"
Dear Haskellers,
I have tried the "while language parser" tutorial on haskellwiki, but I encounter an problem I can not understand here, The following is the code:
So it seems that the order of the operator will affect the parse result. What's the problem with my code? How can I make my program to produce consistent parse result.
Checking the documentation for OperatorTable [1] (the first argument to buildExpressionParser), it seems it is working as expected: An OperatorTable s u m a is a list of Operator s u m a lists. The list is ordered in descending precedence. All operators in one list have the same precedence (but may have a different associativity). I think you can take advantage of the fact that OperatorTable is /a list of lists/, hence aOperators = [ [Prefix (reservedOp "-" >> return (Neg ))] , [Infix (reservedOp "/" >> return (ABinary Divide )) AssocLeft, Infix (reservedOp "*" >> return (ABinary Multiply )) AssocLeft] , [Infix (reservedOp "+" >> return (ABinary Add )) AssocLeft] , [Infix (reservedOp "-" >> return (ABinary Subtract )) AssocLeft] ] should do the trick (try swapping the elements in the second list. Will this do? [1] http://hackage.haskell.org/package/parsec-3.0.0/docs/Text-Parsec-Expr.html#t... _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

On Mon, Apr 13, 2015 at 03:49:43PM +0800, m00nlight wrote:
Hi Francesco,
Thanks for your reply. But after I change the aOperators like the following, it still produce non-correct parse result.
aOperators = [ [Prefix (reservedOp "-" >> return (Neg ))] , [ Infix (reservedOp "*" >> return (ABinary Divide )) AssocLeft, Infix (reservedOp "/" >> return (ABinary Multiply )) AssocLeft] , [Infix (reservedOp "+" >> return (ABinary Add )) AssocLeft, Infix (reservedOp "-" >> return (ABinary Subtract )) AssocLeft] ]
Check those lines: , [ Infix (reservedOp "*" >> return (ABinary Divide )) AssocLeft, Infix (reservedOp "/" >> return (ABinary Multiply )) AssocLeft] Divide should go on the same line of "/", not "*"! Similar fix for Multiply!

According to the given code, that result seems to be fine... Apply / to a
and be and that result is applied to * together with c. Only odd thing is
that you named the / Multiply and the * Divide.
Am 13.04.2015 09:50 schrieb "m00nlight"
Hi Francesco,
Thanks for your reply. But after I change the aOperators like the following, it still produce non-correct parse result.
aOperators = [ [Prefix (reservedOp "-" >> return (Neg ))] , [ Infix (reservedOp "*" >> return (ABinary Divide )) AssocLeft, Infix (reservedOp "/" >> return (ABinary Multiply )) AssocLeft] , [Infix (reservedOp "+" >> return (ABinary Add )) AssocLeft, Infix (reservedOp "-" >> return (ABinary Subtract )) AssocLeft] ]
parse result:
*Main> parseString "res := a / b * c" Assign "res" (ABinary Divide (ABinary Multiply (Var "a") (Var "b")) (Var "c")) *Main>
--m00nlight
在2015年04月13 15时21分, "Francesco Ariis"
写道: On Mon, Apr 13, 2015 at 02:56:47PM +0800, m00nlight wrote:
Dear Haskellers,
I have tried the "while language parser" tutorial on haskellwiki, but I encounter an problem I can not understand here, The following is the code:
So it seems that the order of the operator will affect the parse result. What's the problem with my code? How can I make my program to produce consistent parse result.
Checking the documentation for OperatorTable [1] (the first argument to buildExpressionParser), it seems it is working as expected:
An OperatorTable s u m a is a list of Operator s u m a lists. The list is ordered in descending precedence. All operators in one list have the same precedence (but may have a different associativity).
I think you can take advantage of the fact that OperatorTable is /a list of lists/, hence
aOperators = [ [Prefix (reservedOp "-" >> return (Neg ))] , [Infix (reservedOp "/" >> return (ABinary Divide )) AssocLeft, Infix (reservedOp "*" >> return (ABinary Multiply )) AssocLeft] , [Infix (reservedOp "+" >> return (ABinary Add )) AssocLeft] , [Infix (reservedOp "-" >> return (ABinary Subtract )) AssocLeft] ]
should do the trick (try swapping the elements in the second list. Will this do?
[1] http://hackage.haskell.org/package/parsec-3.0.0/docs/Text-Parsec-Expr.html#t... _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
<#14cb1c225ea1e3ea_> _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Hi Norbert, Francesco,
Thanks. Just an stupid mistake when I change the code. It is actually correct.
Thanks for all your help.
--m00nlight
在2015年04月13 16时29分, "Norbert Melzer"
Dear Haskellers,
I have tried the "while language parser" tutorial on haskellwiki, but I encounter an problem I can not understand here, The following is the code:
So it seems that the order of the operator will affect the parse result. What's the problem with my code? How can I make my program to produce consistent parse result.
Checking the documentation for OperatorTable [1] (the first argument to buildExpressionParser), it seems it is working as expected: An OperatorTable s u m a is a list of Operator s u m a lists. The list is ordered in descending precedence. All operators in one list have the same precedence (but may have a different associativity). I think you can take advantage of the fact that OperatorTable is /a list of lists/, hence aOperators = [ [Prefix (reservedOp "-" >> return (Neg ))] , [Infix (reservedOp "/" >> return (ABinary Divide )) AssocLeft, Infix (reservedOp "*" >> return (ABinary Multiply )) AssocLeft] , [Infix (reservedOp "+" >> return (ABinary Add )) AssocLeft] , [Infix (reservedOp "-" >> return (ABinary Subtract )) AssocLeft] ] should do the trick (try swapping the elements in the second list. Will this do? [1] http://hackage.haskell.org/package/parsec-3.0.0/docs/Text-Parsec-Expr.html#t... _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
participants (3)
-
Francesco Ariis
-
m00nlight
-
Norbert Melzer