Prolog - DCG parser with input from file

前端 未结 4 1748
萌比男神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:54

    Well, the purpose of a homework question is to learn. Doing it with a DCG will teach you a more generally useful skill than horsing operators about.

    I think your issues are less with DCG's inherently than with string handling.

    You have a bunch of places where you use univ (the =.. operator) to convert between lists and strings. Univ probably is NOT what you want here. Univ unifies a term with a list.

    foo(bar, baz)  =..  [foo, bar, baz]
    

    What you need to understand is that a string in Prolog can be in several different forms The string 'hi Flores' could be

    'hi Flores' - this is an atom - a 'solid chunk' of thing. The single quotes aren't needed for some character sequences (see your book), so hi_flores is a perfectly good atom without single quotes.

    [104,105,32,70,108,111,114,101,115] - a list of ASCII codes.  This is likely what you want. These can be written with double quotes, "hi Floris"  in prolog code.
    
    To save your sanity, put
    
    :- portray_text(true).  
    

    in your file so it prints out "hi Floris" in debug, not a bunch of numbers.

    There's also a list of one character atoms

    [h, i, ' ', 'F', l, o, r, i, s]

    but you probably don't want those.

    You might find the SICSTUS compatability pred read_line useful.

    Now, in a DCG, you sometimes want to match 'literals' - literally that thing. If so, put that in a list. Here's a DCG for if statements in some vaguely VBish language

    if_statement  --> "if", wh, "(", condition, ")", wh, 
                      "then", wh, body, wh, "else", wh,
                      else_body, wh, "endif".
    
    % whitespace
    wh -->  [].
    wh -->  " ", wh.
    wh --> [10], wh.   % handle newline and cr
    wh --> [12], wh.
    

    the wh's everywhere are optional whitespace.

    Now, for overall strategy, you can either read in one line at a time, or read in the whole file. For one line, use read_line, which returns a list of codes. read_file_to_codes will get the whole file.

    If you use the whole file strategy, and newlines are significant, you'll need to remove them from the definition of whitespace, obviously.

    And, of course, all this leads to the question why questions about this problem are flooding SO instead of the instructor's in box.

提交回复
热议问题