String 在Prolog中删除字符串中的空白

String 在Prolog中删除字符串中的空白,string,parsing,prolog,whitespace,dcg,String,Parsing,Prolog,Whitespace,Dcg,我用Prolog编写了解析器。我还没做完。它是代码的一部分。下一步是删除字符串中的所有空白 parse(Source, Tree) :- kill_whitespace(Source, CleanInput), % remove whitespaces actual_parse(CleanInput, Tree). actual_parse(CleanInput, Tree):- phrase(expr(Tree),CleanInput).

我用Prolog编写了解析器。我还没做完。它是代码的一部分。下一步是删除字符串中的所有空白

parse(Source, Tree) :-  kill_whitespace(Source, CleanInput), % remove whitespaces
                        actual_parse(CleanInput, Tree).

actual_parse(CleanInput, Tree):- phrase(expr(Tree),CleanInput).

expr(Ast) --> term(Ast1), expr_(Ast1,Ast).
expr_(Acc,Ast) --> " + ", !, term(Ast2), expr_(plus(Acc,Ast2), Ast).
expr_(Acc,Ast) --> " - ", !, term(Ast2), expr_(minus(Acc,Ast2), Ast).
expr_(Acc,Acc) --> [].

term(Ast) --> factor(Ast1), term_(Ast1,Ast).
term_(Acc,Ast) --> " * ", !, factor(Ast2), term_(mul(Acc,Ast2),Ast).
term_(Acc,Ast) --> " ** ", !, factor(Ast2), term_(pol(Acc,Ast2),Ast).
term_(Acc,Acc) --> [].

factor(Ast) --> "(", !, expr(Ast), ")".
factor(D)--> [X], { X >= 48 , X=<57 , D is X-48 }.
factor(id(N,E)) --> "x", factor(N), ":=", expr(E), ";".
真的!但是,当我写作时:

?- parse("x2 := 4",T).
false.
它也必须是真的,并且应该是一个过滤器:
kill_whitespace(Source,cleanpoint)

不同的解决方案效率低下。
如何才能做到这一点?

好吧,最简单的方法是解析字符串并删除空格/仅保留非whispace和一个。但这需要第二次解析

另一种解决方法是使用您自己的谓词“获取”字符,
i、 e.
foo-->“a”。
变成
foo-->获取(“a”)。
其中
get//1
类似于:

get(X) --> [X].
get(X) --> whitespace, get(X).

我通常会在可能出现空格的地方放置一个“跳过”非终端。这种跳过通常会丢弃注释以及任何其他“无趣”文本

要尽可能简化,请执行以下操作:

% discard any number of spaces
s --> "" ; " ", s.
我喜欢一个简短的名字,以保持语法整洁。放弃换行符等。。以及:

s --> "" ; (" ";"\t";"\n";"\r"), s.
“风格”注释:代替

parse(Source, Tree) :-
   expr(Tree, Source, []).
你可以考虑

parse(Source, Tree) :-
   phrase(expr(Tree), Source).

编写解析器的通常方法是分两个阶段编写:

第一阶段进行词法分析并生成一个标记流。此时将丢弃空格和其他对解析不重要的“标记”(例如注释)


第二阶段自己进行解析,检查词法分析器生成的标记列表。

过滤器使得在需要的地方很难保留空格,如字符串内部。还有一些地方需要空格来分隔令牌。事实上,最后一个案例也没有从我提出的跳过谓词中得到处理…@capelical。最好将输入标记化,处理所有空格/string/etc问题,然后对其进行解析。
parse(Source, Tree) :-
   phrase(expr(Tree), Source).