Parsing/RPN to infix conversion: Difference between revisions

→‎{{header|Haskell}}: Fixed typo which broke compilation. Added test in main(). Applied Hlint, Ormolu.
(→‎{{header|Haskell}}: Fixed typo which broke compilation. Added test in main(). Applied Hlint, Ormolu.)
Line 1,911:
This solution is a rough translation of the solution provided on RubyQuiz, as linked above.
 
<lang Haskell>data Expression = Const String | Exp Expression String Expression
<lang Haskell>
data Expression = Const String | Exp Expression String Expression
 
precedence :: Expression -> Int
precedence (Const _) = 5
precedence (Exp _ op _)
| op `elem`== ["^"] = 4
| op `elem` ["*", "/"] = 3
| op `elem` ["+", "-"] = 2
| otherwise = 0
 
leftAssoc :: Expression -> Bool
leftAssoc (Const _) = False
leftAssoc (Exp _ op _) = op `notElem` ["^", "*", "+"]
 
rightAssoc :: Expression -> Bool
rightAssoc (Const _) = False
rightAssoc (Exp _ op _) = op `elem`== ["^"]
 
instance Show Expression where
show (Const x) = x
show exp@(Exp l op r) = left++ <> " "++ <> op++ <> " "++ <> right
where
where left = if leftNeedParen then "( "++(show l)++" )" else show l
left
right = if rightNeedParen the "( "++(show r)++" )" else show r
| leftNeedParen = "(leftPrec " <> opPrec)show ||l ((leftPrec<> ==" opPrec) && (rightAssoc exp))"
| otherwise = show l
rightNeedParen = (rightPrec < opPrec) || ((rightPrec == opPrec) && (leftAssoc exp))
right
leftPrec = precedence l
rightPrec | rightNeedParen = precedence"( " <> show r <> " )"
opPrec | otherwise = precedenceshow expr
leftNeedParen =
(leftPrec < opPrec)
|| ((leftPrec == opPrec) && rightAssoc exp)
rightNeedParen =
(rightPrec < opPrec)
rightNeedParen = (rightPrec < opPrec) || ((rightPrec == opPrec) && (leftAssoc exp))
leftPrec = precedence l
rightPrec = precedence r
opPrec = precedence exp
 
buildExp :: [Expression] -> String -> [Expression]
buildExp stack x
| not . isOp $ x = Const x : stack
| otherwise = Exp l x r : rest
where
where r : l : rest = stack
isOp = (`elem` ["^", "*", "/", "+", "-"])
 
main =:: doIO ()
main =
contents <- getContents
mapM_
mapM_ (print . head .( foldl buildExp []) .words) (lines contentswords)
</lang>
3 + 4 * 2[ /"3 (4 2 * 1 5 - 52 )3 ^ 2 ^ 3/ +",
 
"1 42 + 5 3 4 + 2^ 35 *6 *+ *^",
Input:
"1 4 + 5 3 + 2 3 * * *",
<pre>
3 4 2 * 1 5 -"1 2 * 3 ^4 ^* / +*",
"1 2 + 3 4 + ^ 5 6 + ^"
]</lang>
1 4 + 5 3 + 2 3 * * *
{{Out}}
1 2 * 3 4 * *
1<pre>3 + 4 * 2 +/ 3( 41 +- +5 ) ^ 2 ^ 3
</pre>
 
Output:
<pre>
3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )
( 1 + 4 ) * ( 5 + 3 ) * 2 * 3
1 * 2 * 3 * 4
1 + 2 + 3 + 4</pre>
</pre>
 
=={{header|Icon}} and {{header|Unicon}}==
9,655

edits