规范互斥数据结构

时间:2012-06-04 12:41:54

标签: parsing data-structures

注意:这与互斥的并发问题无关,但我想不出更好的描述问题的方法。

我有一个问题,我有一个案例,我想让用户选择一些标志,但一些标志是互斥的。我想用数据结构描述哪些标志是互斥的,但我想到的一切都很笨拙。

基本上,我希望能够指定如何使用标志:

[-fa | -e | -d] [-c] [-g | -h]

这应该在语义上意味着,我可以使用-fa,-e,-d中的任何一个,但不能有两个或更多(但是,f可以与a一起使用,而且不需要同时使用它们)。我可以有一个-c或者没有-c,我可以有-g或-h,但不能两者都有。

这是我的“最佳”解决方案。

Map [Flag,MutexGroup](及其逆,Map [MutexGroup,List [Flag]]) Map [MutexGroup,List [MutexGroup]]

我的例子看起来像

地图(“f” - > 1,“a” - > 1,“e” - > 2,“d” - > 3,“c” - > 4,“g” - > ; 5,“h” - > 6) 地图(1 - >列表(2,3),2 - >列表(1,3),3 - >列表(1,2),4 - > List.empty,5 - >列表(6 ),6 - >列表(5))

为简洁起见,我没有包含Map [MutexGroup,List [Flag]]。

这个解决方案让我不禁想到必须要使用它。是否有规范的方法来处理这类事情?

1 个答案:

答案 0 :(得分:2)

你正在描述一种语法。

表示语法的最好方法是抽象语法树。树是规范结构,代表(互斥)选择。

您可以通过多种方式表示语法树,但一种不错的方法是使用algebraic data types,因为它们静态地保证只能构造格式良好的表达式。标志本身形成一个集合,因此使用Set数据类型来强制执行no-duplicates属性也很好。

-- can have any one of -fa, -e, -d, but not two or more
-- (however, f can be used with a, and you don't need to use both).
-- I can either have a -c or not, and I can have either -g or -h, but not both.
--

-- zero or more flags
type Flags = Set Flag

-- Flags come in three groups
data Flag
        = F1 FAED
        | F2 C
        | F3 GH
    -- equality up to the first constructor. 

-- one of: -f or -a; -e; -d
data FAED
        = FA FA 
        | E
        | D

-- a type for: -f ; -a ; -f -a
data FA = F
        | A
        | FA

-- the -c flag
data C  = C

-- either -g or -h
data GH = G
        | H

还有其他方法可以对您的语言进行编码,但这足以让您沿着使用语法树表示语言的道路前进。