Search code examples
parsingprologdcgmeta-predicate

How to create a higher order DCG parser in Prolog?


I would like to have some more general parsers, like for example paren that would take a parser and wrap it with parentheses:

paren(Parser, Result) -->
  "(", some_magic_dcg_call(Parser, Result), ")".


:- phrase(paren(number, N), "(123)").
123
:- phrase(paren(someatom, A), "(a)").
a

I tried call and dcg_call, but they don't seem to solve the problem. How can I run an arbitrary parser inside another parser?


Solution

  • This solution using call works in SWI-Prolog:

    :- set_prolog_flag(double_quotes, chars).
    
    paren(Parser, Result) -->
        "(",
        call(Parser, Result),
        ")".
    
    number(123) -->
        "123".
    
    someatom(a) -->
        "a".
    

    Tests:

    ?- phrase(paren(number, N), "(123)").
    N = 123.
    
    ?- phrase(paren(someatom, A), "(a)").
    A = a.