我是Ocaml的新手,为了完成作业,我必须编写一个函数filter_reachable ,它需要一个语法并返回一个简化的语法和不可达规则。我被允许使用的唯一模块是Pervasives和List模块,没有其他模块。从OCaml中的语法中删除不可达规则
我的想法是首先列出所有可到达的非终止列表。然后,如果非终结部分位于所有可到达非终结符的列表中,则可以访问规则。所有可访问的规则都放入一个新列表中,并与开始符号配对以创建简化语法。
我的解决方案如下。但它不起作用,我不明白为什么。任何人都可以帮我修复它吗?
let rec member x s=
match s with
[]->false
| y::ys-> (x = y) || member x ys
(*the type of a symbol*)
type ('nonterminal, 'terminal) symbol =
| N of 'nonterminal
| T of 'terminal
let rec get_nont sl=
match sl with
|[]->[]
|h::t->match h with
|N x-> x::get_nont t
|T y-> get_nont t
let rec get_rea_nont (n,r) =
n::(match r with
|[]->[]
|h::t->match h with
| a,b -> if a=n then (get_nont b)@(get_rea_nont (n,t))
else get_rea_nont(n,t)
| _-> [])
let rec fil (st,rl)=
let x = get_rea_nont(st,rl) in
(match rl with
|[]-> []
|h::t-> match h with
|a,b -> if (member a x) then h::fil(st,t)
else fil(st,t)
|_->[]
|_->[]
)
let rec filter(st,rl)=
(st,fil(st,rl))
你打算什么类型用来代表一个语法?我只看到了单个符号的定义(终端或非终结符)。 作为一个注释,你的函数'member'在名字List.mem下的List模块中可用。绝对值得熟悉List模块的功能,尤其是因为您可以使用它们! –
语法中使用的符号。它可以是非终端符号或终端符号;每种符号都有一个值,其类型是任意的。符号的类型已发布 右侧是符号列表。它对应于单个文法规则的右侧。右侧可以是空的。 规则是一对,由(1)非终结符值(语法规则的左侧)和(2)右侧组成。 语法是一对,由开始符号和规则列表组成。开始符号是非终结值。 – user974036
OK,那么你的名为'rl'的参数代表规则列表,而一对(st,rl)代表一个语法。 –