我正在读取一个包含上下文无关语法的文件,并对每行进行标记并生成表单
的列表L = ['S', =, a, 'S', b, ;, 'S', =, c;].
在列表中';'表示换行。该列表可以根据文件中的语法进行扩展。现在我想为遇到的每个';'分区。
例如,考虑以下规则getRule(List, First, Rest):-
我应该能够得到第一个语法行'S', =, a, 'S', b,作为第一个和其余的列表作为Rest每次递归。
这是整个事情(如何将列表划分为规则):
getRules([], _Delimiter, []) :- !.
getRules(List, Delimiter, [Rule|Rules]) :-
getRule(List, Delimiter, Rule, Rest),
getRules(Rest, Delimiter, Rules).
使用你要求的getRule:
getRule([], _Delimiter, [], []) :- !.
getRule([Delimiter|Rest], Delimiter, [], Rest) :- !.
getRule([Item|List], Delimiter, [Item|Rule], Rest) :-
getRule(List, Delimiter, Rule, Rest).
与 调用
?- getRule(['S', =, a, 'S', b, ;, 'S', =, c, ;], ;, Rule, Rest).
返回Rule = ['S', =, a, 'S', b],
Rest = ['S', =, c, ;].
和主要的:
?- getRules(['S', =, a, 'S', b, ;, 'S', =, c, ;], ;, Rules).
返回Rules = [['S', =, a, 'S', b], ['S', =, c]].
显然可以硬编码;如果你想的话!
如果你需要任何关于代码的解释,请询问。
我添加了评论中讨论的修改,并删除了剧透,因为你读了。
这是你要求的另一件事:
divideRules(Rules, PureRules) :-
divideRules_(Rules, Temp),
append(Temp, PureRules).
divideRules_([], []) :- !.
divideRules_([Rule|Rules], [PureRule|PureRules]) :-
divideRule(Rule, PureRule),
divideRules_(Rules, PureRules).
divideRule(Rule, PureRule) :-
getRule(Rule, ::=, Left, Right),
append([Left, [::=]], NewLeft),
getRules(Right, '|', PureRight),
maplist(append(NewLeft), PureRight, PureRule).
这是我的猜测,但我现在不能运行prolog解释器,所以它是未经测试的:
grammarize([], []) :- !.
grammarize([[Left, ::=|Right]|PureRules], [grammar(Left, Right)|Grammars]) :-
grammarize(PureRules, Grammars).