use*_*944 5 algorithm grammar parsing prolog dcg
我是Prolog的新手,我试图了解如何将语法从DCG转换为普通的定句。我知道DCG表示法只是Prolog中常规定语从句的语法糖。我开始描述正常定语法和DCG之间的一些相似之处,但是未能应用相同的模式,所以我问是否有一些我遗漏的规则或可能有效的转换算法。
这是我正在研究的语法,这是我为了翻译该语法所做的工作:
expr --> term, addterm.
addterm --> [].
addterm --> [+], expr.
term --> factor, multfactor.
multfactor --> [].
multfactor --> [*], term.
factor --> [I], {integer(I)}.
factor --> ['('], expr, [')'].
Run Code Online (Sandbox Code Playgroud)
该语法实际上检查算术运算的句法正确性。第一条规则实际上很容易转换,因为它的模式类似于正常的定语法,第四条规则也是如此。但是我对其他四个都不了解。这是我如何转换规则:
expr(E0,E) :- term(E0,E1), addterm(E1,E).
Run Code Online (Sandbox Code Playgroud)
如果您的Prolog系统提供了expand_term/2内置谓词,则通常可以使用将语法规则扩展为子句。例如:
?- expand_term((a --> b, c), Clause).
Clause = (a(_G1012, _G1013):-b(_G1012, _G1028), c(_G1028, _G1013)).
Run Code Online (Sandbox Code Playgroud)
为了使输出更具可读性(并且仅用于此目的),请尝试:
?- expand_term((a --> b, c), Clause), numbervars(Clause, 0, _).
Clause = (a(A, B):-b(A, C), c(C, B)).
Run Code Online (Sandbox Code Playgroud)
numbervars/3 是大多数Prolog系统上发现的事实上的标准谓词。
你走在正确的轨道上!继续下去,你会得到这样的结果:
expr(Xs0,Xs) :- % expr -->
term(Xs0,Xs1), % term,
addterm(Xs1,Xs). % addterm.
addterm(Xs0,Xs) :- % addterm -->
Xs0 = Xs. % [].
addterm(Xs0,Xs) :- % addterm -->
Xs0 = [+|Xs1], % [+],
expr(Xs1,Xs). % expr.
term(Xs0,Xs) :- % term -->
factor(Xs0,Xs1), % factor,
multfactor(Xs1,Xs). % multfactor.
multfactor(Xs0,Xs) :- % multfactor -->
Xs0 = Xs. % [].
multfactor(Xs0,Xs) :- % multfactor -->
Xs0 = [*|Xs1], % [*],
term(Xs1,Xs). % term.
factor(Xs0,Xs) :- % factor -->
Xs0 = [I|Xs], % [I],
integer(I). % {integer(I)}.
factor(Xs0,Xs) :- % factor -->
Xs0 = ['('|Xs1], % ['('],
expr(Xs1,Xs2), % expr,
Xs2 = [')'|Xs]. ` % [')'].
Run Code Online (Sandbox Code Playgroud)