Prolog - 带有文件输入的 DCG 解析器 [英] Prolog - DCG parser with input from file

查看:48
本文介绍了Prolog - 带有文件输入的 DCG 解析器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为项目的一部分,我需要编写一个解析器,它可以读取文件并将其解析为我可以在我的程序中使用的事实.

As part of a project I need to write a parser that can read a file and parse into facts I can use in my program.

文件结构如下:

property = { el1 , el2 , ... }.  

我最终想要的是:

property(el1).
property(el2).
...

我这样阅读我的文件:

main :-
       open('myFile.txt', read, Str),
       read_file(Str,Lines),
       close(Str),
       write(Lines), nl.

read_file(Stream,[]) :-
                       at_end_of_stream(Stream).

read_file(Stream,[X|L]) :-
                          \+ at_end_of_stream(Stream),
                          read(Stream,X),
                          parse(X),            % Here I call upon my parser.
                          read_file(Stream,L).

现在我已经阅读了几本关于 DCG 的书籍和网上,但它们都解释了相同的简单示例,您可以在其中生成诸如猫吃蝙蝠"之类的句子......当我想将其用于上述示例时我惨败.

Now I have read in several books and online about DCG, but they all explain the same simple examples where you can generate sentences like "the cat eats the bat" etc... When I want to use it for the above example I fail miserably.

我所做的是解析"下面的一行:

What I did manage was "parsing" the underneath line:

property = el1.

property(el1).

与此:

parse(X) :-
           X =.. List,    % Reason I do this is because X is one atom and not a list.
           phrase(sentence(Statement), List),
           asserta(Statement).

sentence(Statement) --> ['=', Gender, Person] , { Statement =.. [Gender, Person] }.

我什至不知道我在这里是否以正确的方式使用了 dcg,所以任何关于这方面的帮助将不胜感激.现在我遇到的问题是,如何对列表中的多个元素执行此操作,以及如何处理{"和}".
我真正想要的是一个可以处理这些类型的句子(超过 2 个元素)的 dcg:

I don't even know if I'm using the dcg in a correct way here, so any on help on this would be appreciated. Now the problem I having is, how to do this with multiple elements in my list, and how to handle '{' and '}'.
What I really want is a dcg that can handle these types of sentences (with more than 2 elements):

现在我知道这里有很多人在谈到 dcgs 时会参考 dcg_basics 和 pio 库.但是,我还有一个问题,当我尝试使用该库时,我收到错误消息:

Now I know many people around here refer to the libraries dcg_basics and pio when it comes to dcgs. However, I have an additional problem that when I try to use the library I receive the error:

ERROR: (c:/users/ldevriendt/documents/prolog/file3.pl:3):
      Type error: `text' expected, found `http/dcg_basics'
Warning: (c:/users/ldevriendt/documents/prolog/file3.pl:3):
      Goal (directive) failed: user:[library(http/dcg_basics)]

当我这样做时:

:- [library(http/dcg_basics)].

附加信息:

  • I use the program: SWI-Prolog-Editor on a Windows environment.

对此的任何帮助将不胜感激!

Any help on this would be appreciated!

这个问题的目的是了解更多关于 DCG 及其在解析器中的使用.

The aim of this is question is to learn more about DCG and its use in parsers.

推荐答案

只要您的文件是纯 Prolog 语法,建议您使用 Prolog 术语 IO.只需一次调用即可阅读完全结构化的术语.使用 DCG 的方式更复杂,效率也更低(这里不确定,应该测量,但 read(Term) 调用在 C 中实现的 Prolog 解析器...)请参阅其他 问题,使用完全相同的格式(至少,你可以检查其他人是否在这里得到了答案关于你的同一个任务......)

as long as your file is in plain Prolog syntax, you're advised to use Prolog term IO. Fully structured terms are read with a single call. Using a DCG its' way more complicate, and a bit less efficient (not sure here, should measure, but read(Term) invokes a Prolog parser implemented in C...) See this other question, that uses the very same format (at least, you could check if some other guy got an answer here on SO about your same assignment...)

在评论后编辑...

您说得对,DCG 是在 Prolog 中处理一般解析的正确方式.DCG 产品中的参数可以被视为语义属性,因此编程 DCG 可以被视为对输入提供工作语义分析(参见 属性语法,也是语言工程中的一项重要技术.

You're right that DCG are the right way to handle general parse in Prolog. Arguments in DCG productions can be seen as semantic attributes, thus programming DCG can be seen as providing a working semantic analysis on the input (see Attribute Grammar, an important technique -also- in language engineering).

而且确实可以很好地解决所提供的示例,而无需使用术语 IO 所需的技巧.

And indeed the presented examples can perfectly well be solved without the hacks required with term IO.

这是:

:- use_module(library(pio)).  % autoload(ed), added just for easy browsing
:- use_module(library(dcg/basics)).

property(P) -->
    b, "my props", b, "=", b, "{", elS(Es) , b, "}", b,
    { P =.. [property|Es] }.

elS([E|Es]) --> el(E), b, ("," -> elS(Es) ; {Es = []}).
el(N) --> number(N).
el(S) --> csym(S). % after Jeremy Knees comment...
b --> blanks.

%   parse a C symbol
csym(S) -->
    [F], { code_type(F, csymf) },
    csym1(Cs),
    !, { atom_codes(S, [F|Cs]) }.

csym1([C|Cs]) -->
    [C], { code_type(C, csym) },
    csym1(Cs).
csym1([]) --> [].

有了这个,我们有

?- phrase(property(P), "my props = {1,2,3}").
P = property(1, 2, 3).

感谢 library(pureio) 我们可以应用语义编程到 Prolog 流,并获得与短语/2 相同的行为的奖励.

Thanks to library(pureio) we can apply semantic programming to Prolog streams, and be rewarded of the same behaviour of phrase/2.

更多

其他答案展示了一种实用的方法来实现具有运算符解析和惰性求值的表达式计算器.

This other answer show a practical way to implement an expression calculator with operator resolution, and lazy evaluation.

这篇关于Prolog - 带有文件输入的 DCG 解析器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆