Now I posted already a tight Prolog reader on SWI-Prolog
discourse. Here is it in all its glory. It doesn't handle negative
numbers, but its cute to play around with operator parsing,
like for example:
/* SICStus 4.7.1 */
?- consult('reader.p').
?- reader(T,1200,[:-,x0],[]).
T = (:-x0) ?
?- reader(T,1200,[:-,:-,x0],[]).
error(syntax_error(operator_clash),_415)
The code is only one page:
reader(X, L) -->
reader_primary(Z, L, K), reader_secondary(Z, X, L, K).
reader_primary(H, L, R) --> [A], {current_op(R, M, A), is_prefix(M, E)}, !,
{L < R -> throw(error(syntax_error(operator_clash),_)); true},
{T is R-E}, reader(Z, T), {H =.. [A,Z]}.
reader_primary(X, _, 0) --> [X].
reader_secondary(H, X, L, C) --> [A],
{current_op(R, M, A), is_infix(M, D, E), L >= R}, !,
{R-D < C -> throw(error(syntax_error(operator_clash),_)); true},
{T is R-E}, reader(Z, T),
{J =.. [A,H,Z]},
reader_secondary(J, X, L, R).
reader_secondary(H, X, L, C) --> [A],
{current_op(R, M, A), is_postfix(M, D), L >= R}, !,
{R-D < C -> throw(error(syntax_error(operator_clash),_)); true},
{J =.. [A,H]},
reader_secondary(J, X, L, R).
reader_secondary(H, H, _, _) --> [].
is_infix(xfx, 1, 1).
is_infix(yfx, 0, 1).
is_infix(xfy, 1, 0).
is_prefix(fx, 1).
is_prefix(fy, 0).
is_postfix(xf, 1).
is_postfix(yf, 0).