我正在尝试进一步开发一些为简化正则表达式而开发的Haskell代码,我遇到了一个小问题。当我运行以下命令时:
*Language.HaLex.RegExp> simplifyRegExp(Star (Or a Epsilon))
我得到输出'a'*如果我用b替换a',我得'b'*就像我应该的那样。当我使用Then时出现问题。以下命令:
*Language.HaLex.RegExp> simplifyRegExp(Then (Star a) (Star a))
工作正常并按预期产生'a'*但用b替换a产生以下输出:
*Language.HaLex.RegExp> simplifyRegExp(Then (Star b) (Star b))
'b'*'b'*
虽然它应该只产生'b'*。现在,如果我将变量名称更改为行
中的bsimplifyRegExp (Then x y) | x' == Star a && y' == x' = y'
它适用于b但不适用于任何其他字母。所以我的问题是为什么它在Star部分工作正常但在Then部分没有工作?
我已经添加了以下代码中的一些重要部分,但如果不够,可以随意询问更多内容。
data RegExp sy = Empty -- ^ Empty Language
| Epsilon -- ^ Empty String
| Literal sy -- ^ Literals
| Or (RegExp sy) (RegExp sy) -- ^ Disjuncion
| Then (RegExp sy) (RegExp sy) -- ^ Sequence
| Star (RegExp sy) -- ^ Repetition, possibly zero time
deriving (Read, Eq)
a = Literal 'a'
b = Literal 'b'
c = Literal 'c'
simplifyRegExp Empty = Empty
simplifyRegExp Epsilon = Epsilon
simplifyRegExp (Literal x) = Literal x
simplifyRegExp (Star x) = case x' of
Or a Epsilon -> Star (simplifyRegExp a)
where x' = simplifyRegExp x
simplifyRegExp (Then x y) | x' == Star a && y' == x' = y'
where x' = simplifyRegExp x
y' = simplifyRegExp y
答案 0 :(得分:1)
您有可变范围问题。
在case
模式匹配Or a Epsilon
中,a
是本地绑定到该案例规则右侧的新变量(即Star (simplifyRegExp a)
)。稍后,在simplifyRegExp (Then x y)
的等式中,您可以参考Star a
a
本地绑定的位置,而是引用顶级定义
a = Literal 'a'
这几乎肯定不是你想要的行为,因为正则表达式的简化超越了它的结构而忽略了文字的实际选择。