【发布时间】:2014-12-14 17:26:17
【问题描述】:
我之前问过这个问题,但似乎我的问题措辞过于狭隘。所以让我们看看我能不能解释一下我到底在追求什么。
假设我有某种类型支持多个二元运算符,每个运算符具有不同的优先级和关联性。如何编写一个正确括住子表达式的Show 实例?
我知道我在这里很密集,但我每次都弄错了我尝试这样做。您必须遵循一些机械程序才能正确完成这项工作,但我找不到。谁能给我举个例子?
我知道这最终归结为将所有内容包装在 showParen 中,并使用带有正确幻数的 showsPrec 显示子表达式,我可以使其几乎工作,但它永远不会在所有情况下都可以正常工作。
编辑:考虑以下代码
data Expr =
Const Int |
Expr :+: Expr |
Expr :-: Expr |
Expr :*: Expr |
Expr :/: Expr
infixl 6 :+:
infixl 6 :-:
infixl 7 :*:
infixl 7 :/:
instance Show Expr where
showsPrec p e0 =
case e0 of
Const n -> shows n
x :+: y -> showParen (p > 6) $ (showsPrec 6 x) . (" :+: " ++) . (showsPrec 6 y)
x :-: y -> showParen (p > 6) $ (showsPrec 6 x) . (" :-: " ++) . (showsPrec 6 y)
x :*: y -> showParen (p > 7) $ (showsPrec 7 x) . (" :*: " ++) . (showsPrec 7 y)
x :/: y -> showParen (p > 7) $ (showsPrec 7 x) . (" :/: " ++) . (showsPrec 7 y)
这几乎正常工作:
*Main> Const 1 :+: Const 2 :*: Const 3 :+: Const 4
1 :+: 2 :*: 3 :+: 4
*Main> (Const 1 :+: Const 2) :*: (Const 3 :+: Const 4)
(1 :+: 2) :*: (3 :+: 4)
但不完全是:
*Main> Const 1 :+: Const 2 :-: Const 3 :-: Const 4
1 :+: 2 :-: 3 :-: 4
*Main> Const 1 :+: Const 2 :-: (Const 3 :-: Const 4)
1 :+: 2 :-: 3 :-: 4
所以看起来 precedence 是可以的,但是 associativity 是borked。
【问题讨论】:
-
Google 建议这两个问题:Pretty Printing AST with Minimal Parentheses 和 Associativity and Precedence of Expressions when Generating C / C++ Code?。这些可能会给你一些想法。我不确定这是否是其中之一的副本,但现在我倾向于“不是重复”,因为这个问题部分是关于如何使一般技术顺利融入 Haskell 生态系统。
标签: string haskell operator-precedence