Looking for advice: structured output according to command line switches

In my existing version (PHP, :face_vomiting:) of my language there is a command line option to have the errors output as either one of:

  • plain text (console use)
  • JSON
  • XML

I currently have errors coming out but I am passing in the File as I have so far failed to figure out how to use the prefix(File:Location) feature. I have been using this as my guide:
www.pathwayslms.com/swipltuts/message/index.html

The only code I have so far is this:

prolog:message(ast_error(syntax(map, uneven_elements, (L,C), File))) -->
    ['~s:~d:~d: map has an odd number of elements.'-[File, L, C]].

which is following the rules but I would then like to be able to decide how to subsequently render it out as JSON, XML or plain text according to some command line option previously set.

I have yet to succeed playing with message_property/2 etc, the error message handler I have basically unpacks then repacks the error term so convert the location, and make that and the source file name available, here’s the code, totally in flux, warts and all…

% ALL ERRORS are of the form:
% <module>_error( ErrorType ( Topic, Reason, Pos ) )
%
% ast_error( syntax( map, uneven_elements, 1234 ) ).
handle_error(File, Code, Error) :-
    Error =.. [Sender, Exception],
    Exception =.. [ErrorType, TopicOrKeyword, Reason, Pos],
    (   Pos >= 0
    ->  pos_linecol(Code, Pos, Locn)
    ;   Locn = (-1,-1)
    ),
    NewExc =.. [ErrorType, TopicOrKeyword, Reason, Locn, File],
    NewError =.. [Sender, NewExc],
    print_message(error, NewError).

So… looking for advice, enlightenment, suggestions for more idiomatic Prolog as I continue to learn!

Thanks,
Sean.

That’s the SAME LINK I mentioned in my post Eric :smiley:

1 Like

I think the way to go is to define user:print_message_hook/3, which provides you with the level, the error term and the lines. Unfortunately there is no public way to translate the lines to a nice string. You could call message_to_string/2 on the term (which goes again through the translation grammar, but that might not be too bad). Then you have the structured term and a string and you can define some translation from the term to JSON/XML. I’m not sure there is a sensible generic translation though. Some of these rules do further inspection of the environment to create a meaningful message.

If you manage to come up with something nice it can be a good contribution to the library.

Agreed. You can generalise things only so far until you are no longer general. I think that my problem is very domain specific i.e. wanting to produce XML/JSON/plaintext versions of a structure. As it is, the print_message pipeline is pretty good, I’ve not seen anything like that before.

I’ve said it before and I will say it again, the more I persevere and dig in with SWI the more I continue to be surprised at its flexibility and power, but as Uncle Ben says…

I only can take credits for the copying. It was introduced by Quintus Prolog in the late 80s :slight_smile: I did extend it a bit though, such as adding more channels, adding color support and generalizing properties to define the prefix, output, context, etc.

1 Like

I was very surprised not only by the print_message pipeline but also by the way that SWI makes it so easy to hook into lots of things, it’s a treasure chest of hacker goodies waiting to be explored. Today I am about to wade into the “GetOpt” stuff, I’ve used the Haskell and GNU C libraries before, and the documentation shows no real departing from that.

Great stuff is SWI for sure! :+1:

Yes, my mind was partially distracted. Thanks.

At least you have a mind. I am not sure what’s upstairs for me but I think the BIOS is sore need of an update…

1 Like