查找不同的终端符号和非终端符号

时间:2019-03-07 01:27:52

标签: haskell context-free-grammar

我目前正在编写两个函数,这些函数将用于返回给定语法中出现的所有不同终端的列表。

这是语法的类型:

data Grammar = Grammar [Prod]
               deriving (Show, Eq)

这是我到目前为止所拥有的:

terminals :: Grammar -> [String]                                          
terminals ts = nub [ x | x <-ts]

nonterms  :: Grammar -> [String]
nonterms nt = nub [ x | x <- nt]

放置在函数中的语法如下(3个示例):

g4 = "P -> true ; P -> false; P -> not P ; P -> P and P"
g5 = "P -> P & N; P -> N; N -> ~ N; N -> t"                                   
g6 = "P -> N & P; P -> N; N -> ~ N; N -> t"

但是,由于GHCI无法将预期类型“ [String]”与实际类型“语法”相匹配,因此我使用的功能无法正常工作。

我脱离了上下文无关文法(CFG)的基本原理,即上下文无关文法是

 G = (T,N,P,S)

其中T是终端符号(“令牌”)的集合T,非终端符号的集合N,产品的集合P和起始符号S。

我如何使用/编写两个函数,这些函数可以返回给定语法中出现的所有不同终端(分别是非终端)的列表。上面的三个语法示例。谢谢。

1 个答案:

答案 0 :(得分:2)

terminals :: Grammar -> [String]                                          
terminals ts = nub [ x | x <-ts]

函数terminals的类型为返回[String]。它的实现返回nub的结果。 nub的类型为Eq a => [a] -> [a],因此要使其返回[String],其输入也必须为[String]。这意味着[ x | x <-ts]必须为[String]类型,然后x必须为String类型。在列表理解中执行x <- ts意味着ts必须是x类型的列表,因此在这种情况下,ts必须是[String]。 / p>

现在问题变得明显了。给定函数输出及其实现的类型,ts必须为[String]类型,但是给定函数输入的类型,ts必须为{{ 1}}。由于Grammar[String]是不同的类型,因此会导致您看到类型错误。

旁注:Grammar仅与[ x | x <-ts]等效,而ts仅与[ x | x <- nt]等效。