SVG解析和数据类型

时间:2016-01-18 17:37:20

标签: parsing haskell types

我正在编写SVG解析器,主要是作为学习如何使用Parsec的练习。目前我使用以下数据类型来表示我的SVG文件:

data SVG = Element String [Attribute] [SVG]
         | SelfClosingTag [Attribute]
         | Body String
         | Comment String
         | XMLDecl String

这很有效,但我不确定数据类型的Element String [Attribute] [SVG]部分。 由于SVG的潜在tags数量有限,我考虑使用类型来表示SVG元素而不是使用String。像这样:

data SVG = Element TagName [Attribute] [SVG]
         | ...

data TagName = A
             | AltGlyph
             | AltGlyphDef
             ...
             | View
             | Vkern

这是个好主意吗?如果有的话,这样做有什么好处? 有更优雅的解决方案吗?

2 个答案:

答案 0 :(得分:4)

我个人更喜欢枚举所有可能TagName的方法。这样,如果你犯了任何粗心的错误,编译器会给你错误和警告。例如,如果我想编写一个涵盖每种可能类型的Element的函数,那么如果在ADT中枚举每个类型,编译器可以为您提供非详尽的匹配警告。如果将其表示为字符串,则无法实现。另外,如果我想匹配特定类型的Element,并且我不小心拼错TagName,编译器将捕获它。第三个原因,这可能并不适用于此,但值得注意的是,如果我后来决定添加或删除TagName的变体,那么编译器会告诉我每个需要的地方改性。我怀疑SVG标签名称会发生​​这种情况,但总的来说,这是值得记住的。

答案 1 :(得分:4)

回答您的问题:

您可以采用这种方式执行此操作,具体取决于您在解析树之后要执行的操作。

如果您只关心SVG解析器是描述SGV数据的形状,那么您只需要一个字符串。

另一方面,如果你想以某种方式将SVG数据转换为类似图形的东西(你预期会评估你的AST),你会发现最好在类型系统中表示所有语义信息。它将使下一步更容易。

我心中的问题是解析通道是否恰好是实现这一目标的地方。 (完全披露,我对SVG只是熟悉了。)我怀疑只有一个平坦的标签列表,你最好用Element各自拥有它自己的必需和可选属性集。如果此转换“在程序中稍后发生”,则无需创建TagName数据类型。您可以在将属性合并到Element s。

的同时捕获所有类型错误

另一方面,可以做一个很好的论证直接解析成一个完整的Element树,在这种情况下,我会删除[Attribute]的通用[SVG]Element字段构造函数,而是在TagName构造函数中创建适当的字段。

您没有问过的问题的另一个答案:

尽早将源代码位置放入您的解析树中。从个人经历来看,我可以告诉你,你的程序越大越难。