very simple:
...
expr(Z) --> [L], {calculate(L, Z)}.
calculate(L, M) :- expr(M, L, []).
yields
?- calculate([+,2,-,9,8],X).
X = 3 ;
false.
2 ?- calculate([+,2,[-,9,8]],X).
X = 3 ;
false.
btw calculate/3 should better be expressed with phrase/2 (at least in SWI-Prolog)
calculate(L, M) :- phrase(expr(M), L).
but an error arise on backtracking
?- calculate([+,2,[-,9,8]],X).
X = 3 ;
ERROR: Type error: `list' expected, found `8' (an integer)
Exception: (14) expr(_G2432, [-, 9, 8], []) ? aabort
% Execution Aborted
then we need a guard:
calculate(L, M) :- is_list(L), phrase(expr(M), L).