You could try to bottom parse bottom up.
This is the processor:
:- op(150, xfx, ---> ).
parse(Phrase) -->
leaf(SubPhrase),
lc(SubPhrase, Phrase).
leaf(Cat) --> [Word], {word(Word,Cat)}.
leaf(Phrase) --> {Phrase ---> []}.
lc(Phrase, Phrase) --> [].
lc(SubPhrase, SuperPhrase) -->
{Phrase ---> [SubPhrase|Rest]},
parse_rest(Rest),
lc(Phrase, SuperPhrase).
parse_rest([]) --> [].
parse_rest([Phrase|Phrases]) -->
parse(Phrase),
parse_rest(Phrases).
An example of grammar specification (but func seems ill specified, and there is no precedence or associativity specification...)
expr(E) ---> [opp, expr(E), clp].
expr(not(E)) ---> [not, opp, expr(E), clp].
expr(impl(L,R)) ---> [expr(L), impl, expr(R)].
expr(ne(L,R)) ---> [expr(L), ne, expr(R)].
expr(mul(L,R)) ---> [expr(L), mul, expr(R)].
expr(add(L,R)) ---> [expr(L), add, expr(R)].
expr(func(L,R)) ---> [func(L), impl, func(R)].
expr(num(N)) ---> [num(N)].
func(f(F, As)) ---> [name(F), args(As)].
args([A|As]) ---> [arg(A), comma, args(As)].
args([A]) ---> [arg(A)].
arg(E) ---> [expr(E)].
word(N, name(N)) :- atom(N).
word(N, num(N)) :- integer(N).
word(=>, impl).
word('(', opp).
word(')', clp).
word(*, mul).
word(+, add).
word(not, not).
word(=/=, ne).
word(',', comma).
an example run
?- phrase(parse(E), [not,'(',2,+,2,*,3,')']).
E = func(f(not, [mul(add(num(2), num(2)), num(3))])) ;
E = func(f(not, [add(num(2), mul(num(2), num(3)))])) ;
E = expr(not(mul(add(num(2), num(2)), num(3)))) ;
E = arg(not(mul(add(num(2), num(2)), num(3)))) ;
E = args([not(mul(add(num(2), num(2)), num(3)))]) ;
E = expr(not(add(num(2), mul(num(2), num(3))))) ;
E = arg(not(add(num(2), mul(num(2), num(3))))) ;
E = args([not(add(num(2), mul(num(2), num(3))))]) ;
false.
but maybe this is no so useful for your task...