Prolog - DCG parser with input from file

前端 未结 4 1805
萌比男神i
萌比男神i 2021-02-19 20:11

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.

The file structure looks as follows:

p         


        
4条回答
  •  暗喜
    暗喜 (楼主)
    2021-02-19 20:47

    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...)

    edit after comments...

    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).

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

    Here it is:

    :- 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([]) --> [].
    

    with that, we have

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

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

    more

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

提交回复
热议问题